-
Notifications
You must be signed in to change notification settings - Fork 4
/
graphing_japanese_age.cpp
137 lines (105 loc) · 3.86 KB
/
graphing_japanese_age.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <fstream>
#include <iostream>
#include <string>
#include "Graph.h"
#include "Window.h"
using namespace Graph_lib;
using namespace std;
struct Distribution {
int year, young, middle, old;
};
istream& operator>>(istream& is, Distribution& d);
// data value to coordinate conversion
class Scale {
int cbase; // coordinate base
int vbase; // base of values
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; }
};
// display Japanese age data read from a file
int main(int argc, char* argv[]) {
if (argc < 2) {
cout << "Usage: " << argv[0] << " input_file\n";
return 0;
}
ifstream ifs(argv[1]);
if (!ifs)
error("can't open ", argv[1]);
constexpr int xmax = 600; // window size
constexpr int ymax = 400;
constexpr int xoffset = 100; // distance from left-hand side of window to y axis
constexpr int yoffset = 60; // distance from bottom of window to x axis
constexpr int xspace = 40; // space beyond axis
constexpr int yspace = 40;
constexpr int xlength = xmax - xoffset - xspace; // length of axes
constexpr int ylength = ymax - yoffset - yspace;
constexpr int base_year = 1960;
constexpr int end_year = 2040;
constexpr double xscale = double(xlength) / (end_year - base_year);
constexpr double yscale = double(ylength) / 100;
constexpr int font_size = 14;
Scale xs(xoffset, base_year, xscale);
Scale ys(ymax - yoffset, 0, -yscale);
Graph_lib::Window win(Point(100, 100), xmax, ymax, "Aging Japan");
Axis x_axis(
Axis::x, Point(xoffset, ymax - yoffset), xlength, (end_year - base_year) / 10,
"year 1960 1970 1980 1990 "
"2000 2010 2020 2030 2040");
x_axis.label.set_font_size(font_size);
x_axis.label.move(-100, 0);
Axis y_axis(Axis::y, Point(xoffset, ymax - yoffset), ylength, 10, "% of population");
y_axis.label.set_font_size(font_size);
Line current_year(Point(xs(2008), ys(0)), Point(xs(2008), ys(100)));
current_year.set_style(Line_style::dash);
Open_polyline children;
Open_polyline adults;
Open_polyline aged;
for (Distribution d; ifs >> d;) {
if (d.year < base_year || d.year > end_year)
error("year out of range");
if (d.young + d.middle + d.old != 100)
error("percentages don't add up");
const 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(20, children.point(0).y), "age 0-14");
children.set_color(Color::red);
children_label.set_color(Color::red);
children_label.set_font_size(font_size);
Text adults_label(Point(20, adults.point(0).y), "age 15-64");
adults.set_color(Color::blue);
adults_label.set_color(Color::blue);
adults_label.set_font_size(font_size);
Text aged_label(Point(20, aged.point(0).y), "age 65+");
aged.set_color(Color::dark_green);
aged_label.set_color(Color::dark_green);
aged_label.set_font_size(font_size);
win.attach(x_axis);
win.attach(y_axis);
win.attach(current_year);
win.attach(children);
win.attach(adults);
win.attach(aged);
win.attach(children_label);
win.attach(adults_label);
win.attach(aged_label);
gui_main();
return 0;
}
// assume format: ( year : young middle old )
istream& operator>>(istream& is, Distribution& d) {
char ch1 = 0, ch2 = 0, ch3 = 0;
Distribution dd;
if (!(is >> ch1 >> dd.year >> ch2 >> dd.young >> dd.middle >> dd.old >> ch3))
return is;
else if (ch1 != '(' || ch2 != ':' || ch3 != ')') {
is.clear(ios_base::failbit);
return is;
}
d = dd;
return is;
}