我的朋友帮助我构建了一个程序,该程序将从文件中获取数据并将其放在向量中。然后,数据将用于制作温度条形图。我已经完成了代码,但是在较高温度下添加颜色的部分不起作用。因此,例如,较冷的温度是蓝色的,因为它们变得温暖,它变成橙色和红色等。我是新手,所以任何帮助表示赞赏。如果需要上下文,我已经包含了整个代码,但第一部分是颜色更改部分。
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());
}
答案 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
输出的裁剪部分
至于我之前提到的使用不同的色彩空间,我假设我想要输入中最冷的温度的蓝色(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提供):
<强>更新强> 继上面我留下的代码(特别注意在计算最小/最大温度之前转换为deg F )我修改了程序中的最后一个for循环并添加了hsvToRgb函数我提到。我使用了相同的数据。输出现在看起来像这样:
这是循环本身:
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;
}