SVG矩形着色

时间:2014-08-07 13:44:24

标签: html c++ svg

我的朋友帮助我构建了一个程序,该程序将从文件中获取数据并将其放在向量中。然后,数据将用于制作温度条形图。我已经完成了代码,但是在较高温度下添加颜色的部分不起作用。因此,例如,较冷的温度是蓝色的,因为它们变得温暖,它变成橙色和红色等。我是新手,所以任何帮助表示赞赏。如果需要上下文,我已经包含了整个代码,但第一部分是颜色更改部分。

string red;
    ostringstream red_color;
    red_color << 255 - (int) temp[i];
    int red_c = (int)(255 - (int) temp[i]);
    red = red_color.str();





#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <istream>
#include <sstream>

using namespace std;
string html_start() { return("<!DOCTYPE html>\n<html>\n<body>\n\n"); }
string html_end()   { return("\n</body>\n</html>\n\n"); }
string svg_start()  { return("<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\"   viewBox=\"0 0 1024 768\" preserveAspectRatio=\"xMinYMid meet\" >\n"); }
string svg_end()    { return("</svg>\n"); }
string svg_line(int x1, int y1, int x2, int y2, string color);
string svg_text(int x, int y, string text, int font_size, string fill_color);
int main()
{
    ifstream fin;

fin.open("/Users/bryan/Documents/CS/Final/parsableTemps.txt");
if (fin.fail())
{
    cout << "Input file opening failed. \n";
    exit(1);
}

   vector<float> temp;
   double t;
   while (fin >> t)
   {
       temp.push_back(t);
   }

fin.close();

float low = temp[0];
float high = temp[0];

for (int i=0; i<temp.size(); i++){
if (temp[i] < low)
    low = temp[i];
if (temp[i] > high)
    high = temp[i];}

for (int j = 0; j < temp.size(); j++)
    temp[j] = (float)9/5*temp[j] + 32;

ofstream fout;
int column = 10;
int width = 5;
int i;
int temp_start = 20;

fout.open("graph.html");
fout << html_start();
fout << "<h1>Monthly Temperature Change over the Last 20 Years </h1>\n";
fout << svg_start();


fout << svg_line(temp_start, width, temp_start, 110, "black");


fout << svg_line(10, 100, 1250, 100, "black");


for (int l = 0; l < 8; l++)
    fout << svg_line(17, 90 - 10*l, temp_start, 90 - 10*l, "black");


for (int n = 0; n < 4; n++){
    string temp;
    ostringstream number;
    number << (n+1)*20;
    temp = number.str();
    fout << svg_text(5, 103 - (n+1)*20, temp , 10, "black");
}


for (int o = 0; o < 21; o++){
    string temp;
    ostringstream year;
    year << 1993 + o;
    temp = year.str();
    fout << svg_text(temp_start + 60*o - 15, 125, temp , 15, "black");
}


for (int m = 0; m < 20; m++)
    fout << svg_line(temp_start + 60 * (m + 1), 100, temp_start + 60 * (m + 1), 108,     "black");

for(i=0; i< temp.size(); i++) {
/// this is where it begins
    string red;
    ostringstream red_color;
    red_color << 255 - (int) temp[i];
    int red_c = (int)(255 - (int) temp[i]);
    red = red_color.str();
/// this is where it ends
    fout << "   <rect x=\"" << temp_start << "\" y=\"" << 100 - temp[i] << "\" width=\""     << width << "\" height=\"" << temp[i] << "\" style=\"fill:rgb(127,0,255);stroke-    width:1;stroke:rgb(0,0,0)\"/>\n";
    temp_start += width;
}





fout << svg_end();
fout << html_end();
fout.close();

return 0;}

string svg_text(int x, int y, string text)
{
   std::ostringstream assembled_oss;
   assembled_oss << " <text x=\"" << x << "\" y=\"" << y << "\" font-size=\"20\"     fill=\"black\">" << text << "\"</text>\n";
   return(assembled_oss.str());
}

    string svg_text(int x, int y, string text, int font_size, string fill_color)
{
   std::ostringstream assembled_oss;
   assembled_oss << " <text x=\"" << x << "\" y=\"" << y << "\" font-size=\"" << font_size <<     "\"";
   assembled_oss << " fill=\"" << fill_color << "\">" << text << "</text>\n";
   return(assembled_oss.str());
}

string svg_text(int x, int y, string text, int font_size, string fill_color, string     font_family)
{
   std::ostringstream assembled_oss;
   assembled_oss << " <text x=\"" << x << "\" y=\"" << y << "\" font-size=\"" << font_size <<     "\"";
   assembled_oss << " fill=\"" << fill_color << "\" font_family=\"" << font_family << "\">" <<     text << "</text>\n";
   return(assembled_oss.str());
}

string svg_line(int x1, int y1, int x2, int y2, string color)
{
   std::ostringstream assembled_oss;
   assembled_oss << " <line x1=\"" << x1 << "\" y1=\"" << y1 << "\" x2=\"" << x2 << "\" y2=\"" << y2 << "\"";
   assembled_oss << " stroke=\"" << color << "\" stroke-width=\"2\"/>\n";
   return(assembled_oss.str());
}

string svg_line(int x1, int y1, int x2, int y2, string color, int width)
{
   std::ostringstream assembled_oss;
   assembled_oss << " <line x1=\"" << x1 << "\" y1=\"" << y1 << "\" x2=\"" << x2 << "\" y2=\"" << y2 << "\"";
   assembled_oss << " stroke=\"" << color << "\" stroke-width=\"" << width << "\"/>\n";
   return(assembled_oss.str());
}

string svg_rect(int x1, int y1, int width, int height)
{
   std::ostringstream assembled_oss;
   assembled_oss << " <rect x=\"" << x1 << "\" y=\"" << y1 << "\" width=\"" << width <<     "\" height=\"" << height << "\"";
   assembled_oss << " style=\"fill:rgb(0,0,0);stroke-width:1;stroke:rgb(0,0,0)\"/>\n";
   return(assembled_oss.str());
}

1 个答案:

答案 0 :(得分:0)

除了我之前的评论之外,这里是我使用的代码和我作为输入提供的数据。

<强>的main.cpp

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <istream>
#include <sstream>

using namespace std;
string html_start()
{
    return("<!DOCTYPE html>\n<html>\n<body>\n\n");
}
string html_end()
{
    return("\n</body>\n</html>\n\n");
}
string svg_start()
{
    return("<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 1024 768\" preserveAspectRatio=\"xMinYMid meet\" >\n");
}
string svg_end()
{
    return("</svg>\n");
}
string svg_line(int x1, int y1, int x2, int y2, string color);
string svg_text(int x, int y, string text, int font_size, string fill_color);

int main()
{
    ifstream fin;

 //   fin.open("/Users/bryan/Documents/CS/Final/parsableTemps.txt");
    fin.open("temps.txt");
    if (fin.fail())
    {
        cout << "Input file opening failed. \n";
        exit(1);
    }

    vector<float> temp;
    double t;
    while (fin >> t)
    {
        temp.push_back(t);
    }

    fin.close();

    for (int j = 0; j < temp.size(); j++)
        temp[j] = (float)9/5*temp[j] + 32;


    float low = temp[0];
    float high = temp[0];

    for (int i=0; i<temp.size(); i++)
    {
        if (temp[i] < low)
            low = temp[i];
        if (temp[i] > high)
            high = temp[i];
    }


    ofstream fout;
    int column = 10;
    int width = 5;
    int i;
    int temp_start = 20;

    fout.open("graph.html");
    fout << html_start();
    fout << "<h1>Monthly Temperature Change over the Last 20 Years </h1>\n";
    fout << svg_start();


    fout << svg_line(temp_start, width, temp_start, 110, "black");


    fout << svg_line(10, 100, 1250, 100, "black");


    for (int l = 0; l < 8; l++)
        fout << svg_line(17, 90 - 10*l, temp_start, 90 - 10*l, "black");


    for (int n = 0; n < 4; n++)
    {
        string temp;
        ostringstream number;
        number << (n+1)*20;
        temp = number.str();
        fout << svg_text(5, 103 - (n+1)*20, temp , 10, "black");
    }


    for (int o = 0; o < 21; o++)
    {
        string temp;
        ostringstream year;
        year << 1993 + o;
        temp = year.str();
        fout << svg_text(temp_start + 60*o - 15, 125, temp , 15, "black");
    }

    for (int m = 0; m < 20; m++)
        fout << svg_line(temp_start + 60 * (m + 1), 100, temp_start + 60 * (m + 1), 108,     "black");

    for(i=0; i< temp.size(); i++)
    {
/// this is where it begins
        string red;
        ostringstream red_color;

//        red_color << 255 - (int) temp[i];
        red_color << (int) ( ((temp[i] - low) / (high-low) ) * 255);
//        red_color << (int) ( (255 * temp[i]) / high);

        red = red_color.str();
/// this is where it ends
//        fout << "   <rect x=\"" << temp_start << "\" y=\"" << 100 - temp[i] << "\" width=\""     << width << "\" height=\"" << temp[i] << "\" style=\"fill:rgb(127,0,255);stroke-    width:1;stroke:rgb(0,0,0)\"/>\n";
        fout << "   <rect x=\"" << temp_start << "\" y=\"" << 100 - temp[i] << "\" width=\""     << width << "\" height=\"" << temp[i] << "\" style=\"fill:rgb(" << red << ",0,255);stroke-    width:1;stroke:rgb(0,0,0)\"/>\n";
        temp_start += width;
    }

    fout << svg_end();
    fout << html_end();
    fout.close();
    return 0;
}

string svg_text(int x, int y, string text)
{
    std::ostringstream assembled_oss;
    assembled_oss << " <text x=\"" << x << "\" y=\"" << y << "\" font-size=\"20\"     fill=\"black\">" << text << "\"</text>\n";
    return(assembled_oss.str());
}

string svg_text(int x, int y, string text, int font_size, string fill_color)
{
    std::ostringstream assembled_oss;
    assembled_oss << " <text x=\"" << x << "\" y=\"" << y << "\" font-size=\"" << font_size <<     "\"";
    assembled_oss << " fill=\"" << fill_color << "\">" << text << "</text>\n";
    return(assembled_oss.str());
}

string svg_text(int x, int y, string text, int font_size, string fill_color, string     font_family)
{
    std::ostringstream assembled_oss;
    assembled_oss << " <text x=\"" << x << "\" y=\"" << y << "\" font-size=\"" << font_size <<     "\"";
    assembled_oss << " fill=\"" << fill_color << "\" font_family=\"" << font_family << "\">" <<     text << "</text>\n";
    return(assembled_oss.str());
}

string svg_line(int x1, int y1, int x2, int y2, string color)
{
    std::ostringstream assembled_oss;
    assembled_oss << " <line x1=\"" << x1 << "\" y1=\"" << y1 << "\" x2=\"" << x2 << "\" y2=\"" << y2 << "\"";
    assembled_oss << " stroke=\"" << color << "\" stroke-width=\"2\"/>\n";
    return(assembled_oss.str());
}

string svg_line(int x1, int y1, int x2, int y2, string color, int width)
{
    std::ostringstream assembled_oss;
    assembled_oss << " <line x1=\"" << x1 << "\" y1=\"" << y1 << "\" x2=\"" << x2 << "\" y2=\"" << y2 << "\"";
    assembled_oss << " stroke=\"" << color << "\" stroke-width=\"" << width << "\"/>\n";
    return(assembled_oss.str());
}

string svg_rect(int x1, int y1, int width, int height)
{
    std::ostringstream assembled_oss;
    assembled_oss << " <rect x=\"" << x1 << "\" y=\"" << y1 << "\" width=\"" << width <<     "\" height=\"" << height << "\"";
    assembled_oss << " style=\"fill:rgb(0,0,0);stroke-width:1;stroke:rgb(0,0,0)\"/>\n";
    return(assembled_oss.str());
}

<强> temps.txt

10
15
20
25
30
35
40
45

输出的裁剪部分

enter image description here

至于我之前提到的使用不同的色彩空间,我假设我想要输入中最冷的温度的蓝色(rgb 0,0,255)值和红色(rgb 255, 0,0)输入中最热的温度值。

要计算每个条形的rgb值,我将使用以下计算:

float Hue = (curTemp - coldestTemp) / (hottestTemp-coldestTemp);
Hue *= 360 - 240;
Hue += 240;

float Sat = 100;
float Val = 100;

现在你的色调范围从最冷的240到最热的温度的360。 从那里,我通过转换HSV获得r,g,b值 - &gt; RGB使用以下功能。

// Input: h, s, v in range [0..1] (typical ranges are 0..360, 0..100, 0..100)
// Outputs: r, g, b in range [0..1] (typical ranges are 0..255, 0..255, 0..255)
void hsvToRgb(float h, float s, float v, float *r, float *g, float *b)
{
     int i;
     float aa, bb, cc, f;

     if (s == 0.0) // greyscale
        *r = *g = *b = v;
     else
     {
         if (h == 1.0) h = 0.0;
         h *= 6.0;
         i = floor(h);
         f = h - (float)i;
         aa = v * (1.0 - s);
         bb = v * (1.0 - (s * f));
         cc = v * (1.0 - (s * (1.0 - f)));
         switch(i)
         {
           case 0: *r = v; *g = cc; *b = aa; break;
           case 1: *r = bb; *g = v; *b = aa; break;
           case 2: *r = aa; *g = v; *b = cc; break;
           case 3: *r = aa; *g = bb; *b = v; break;
           case 4: *r = cc; *g = aa; *b = v; break;
           case 5: *r = v; *g = aa; *b = bb; break;
         }
     }
}

使用:

float r, g, b;
hsvToRgb( Hue/360.0, Sat/100.0, Val/100.0, &r, &g, &b);
r *= 255.0;
g *= 255.0;
b *= 255.0;

然后我将这些rgb值插入到输出用于每个条形的颜色的代码中。

如果你想要蓝色= 0deg F和红色= 100deg F

,你只需要做一些不同的初始计算。

即:

Hue = curTemp / (100-0);
Hue *= (360 - 240);
Hue += 240;

如果您使用0-100度范围之外的温度,这将产生有趣的结果。您需要将Hue钳制到不低于240且不高于360,使用大于0-100的范围。

有很多关于为什么HSV或HSL颜色空间比RGB更好地用于计算所需颜色的好信息(主要是,它们产生了改变颜色的直观方法)不幸的是,显示器工作使用RGB,因此您需要将它们转换为RGB以供查看。

下载HSV色轮作为参考(对话由Gimp 2.8.0提供):

enter image description here

<强>更新 继上面我留下的代码(特别注意在计算最小/最大温度之前转换为deg F )我修改了程序中的最后一个for循环并添加了hsvToRgb函数我提到。我使用了相同的数据。输出现在看起来像这样:

enter image description here

这是循环本身:

for(i=0; i< temp.size(); i++)
{
    ostringstream rgbColor;
    string col;

    float Hue = (temp[i]-low) / (high-low);         // set Hue in range [0..1]
    Hue *= (360 - 240);                             // make Hue in range [0..120]
    Hue += 240;                                     // make Hue in range [240..360]

    float Sat = 100.0;
    float Val = 100.0;
    float r, g, b;

    hsvToRgb( Hue/360.0, Sat/100.0, Val/100.0, &r, &g, &b);
    r *= 255.0;
    g *= 255.0;
    b *= 255.0;

    rgbColor << (int)r << "," << (int)g << "," << (int)b;
    col = rgbColor.str();

    fout << "<rect x=\"" << temp_start << "\" y=\"" << 100 - temp[i] << "\" width=\"" << width << "\" height=\"" << temp[i] << "\" style=\"fill:rgb(" << col << ");stroke-width:1;stroke:rgb(0,0,0)\"/>\n";
    temp_start += width;
}