读取文件:
( 1960 : 30 64 6 )
(1970 : 24 69 7 )
(1980 : 23 68 9 )
(1990 : 18 70 12)
(2000 : 15 68 17 )
(2010 : 13 64 23 )
(2020 : 12 60 28)
( 2030 : 11 59 30 )
( 2040 : 11 56 33 )
运行代码:
//绘制数据图
#include"std_lib_facilities.h"
#include"GUI/Simple_window.h"
#include"GUI/Graph.h"
#include"GUI/Point.h"
//------------------------------------------------------------------------
//定义保存数据项的Distribution类型
struct Distribution
{
int year, young, middle, old;
};
//------------------------------------------------------------------------
//定义读取数据项的输入操作符
istream& operator>>(istream& is, Distribution& d)
{
char ch1 = 0;
char ch2 = 0;
char ch3 = 0;
Distribution dd;
if (is >> ch1 >> dd.year
>> ch2 >> dd.young >> dd.middle >> dd.old
>> ch3)
{
if (ch1 != '(' || ch2 != ':' || ch3 != ')')
{
is.clear(ios_base::failbit);
return is;
}
}
else
return is;
d = dd;
return is;
}
//--------------------------------------------------------------------------
//定义比例缩放类
class Scale
{
int cbase;
int vbase;
double scale;
public:
Scale(int b, int vb, double s) :cbase(b), vbase(vb), scale(s) {}
int operator()(int v)const { return cbase + (v - vbase) * scale; }
};
//---------------------------------------------------------------------------
int main()
try{
//构造一些常量
const int xmax = 600;
const int ymax = 400;
const int x_orig = xmax / 2;
const int y_orig = ymax / 2;
const Point orig(x_orig, y_orig);
const int r_min = -10;
const int r_max = 11;
const int n_points = 3000;
const int x_scale = 30;
const int y_scale = 30;
const int base_year = 1960;
const int end_year = 2040;
const int xoffset = 100;
const int yoffset = 60;
const int xspace = 40;
const int yspace = 40;
const int xlength = xmax - xoffset - xspace;
const int ylength = ymax - yoffset - yspace;
const double xscale = double(xlength) / (end_year - base_year);
const double yscale = double(ylength) / 100;
//-----------------------------------------------------------------------
//构建窗口
Simple_window win(Point(100, 100), xmax, ymax, "Aging Japan");
//-----------------------------------------------------------------------
//打开文件
string file_name = "japanese-age-data.txt";
ifstream ifs(file_name.c_str());
if (!ifs)error("can't open ", file_name);
//-----------------------------------------------------------------------
//数据比例缩放
Scale xs(xoffset, base_year, xscale);
Scale ys(ymax - yoffset, 0, -yscale);
//------------------------------------------------------------------------
//构造坐标系
Axis x(Axis::x, Point(xoffset, ymax - yoffset), xlength,
(end_year - base_year) / 10,
"year 1960 1970 1980 1990 "
"2000 2010 2020 2030 2040");
x.label.move(-100, 0);
x.set_color(Color::black);
Axis y(Axis::y, Point(xoffset, ymax - yoffset), ylength, 10, "% of population");
y.set_color(Color::black);
Line current_year(Point(xs(2008), ys(0)), Point(xs(2008), ys(100)));
current_year.set_color(Color::black);
current_year.set_style(Line_style::dash);
//------------------------------------------------------------------------
//读取文件数据
Open_polyline children;
Open_polyline adults;
Open_polyline aged;
Distribution d;
while (ifs >> d)
{
if (d.year < base_year || end_year < d.year)
error("year out of range");
if (d.young + d.middle + d.old != 100)
error("percentages don't add up");
int x = xs(d.year);
children.add(Point(x, ys(d.young)));
adults.add(Point(x, ys(d.middle)));
aged.add(Point(x, ys(d.old)));
}
//------------------------------------------------------------------------
//为图形添加标签并设置颜色
Text children_label(Point(10, children.point(0).y), "age 0-14");
children.set_color(Color::red);
children_label.set_color(Color::red);
Text adults_label(Point(10, adults.point(0).y), "age 15-64");
adults.set_color(Color::blue);
adults_label.set_color(Color::blue);
Text aged_label(Point(10, aged.point(0).y), "age 65+");
aged.set_color(Color::dark_green);
aged_label.set_color(Color::dark_green);
//------------------------------------------------------------------------
//将不同的Shape对象添加到Window对象中
win.attach(children);
win.attach(adults);
win.attach(aged);
win.attach(children_label);
win.attach(adults_label);
win.attach(aged_label);
win.attach(x);
win.attach(y);
win.attach(current_year);
//------------------------------------------------------------------------
//启动GUI系统
win.wait_for_button();
//------------------------------------------------------------------------
}
catch (exception& e) {
cerr << "error:" << e.what() << '\n';
keep_window_open();
return 1;
}
catch (...) {
cerr << "Oops:unknown exception!\n";
keep_window_open();
return 2;
}
//------------------------------------------------------------------------------
运行结果: