]> git.sesse.net Git - nms/blob - web/ext/graph.cpp
Added Chillout.
[nms] / web / ext / graph.cpp
1 #include "graph.h"
2
3 int tz_local_offset() { return 7200; } // riktig?
4
5
6 void
7 mygraph_fill_background(graph *mygraph);
8
9 void
10 mygraph_draw_graph (cairo_t *cr,
11                     int x,
12                     int y );
13
14 graph *
15 mygraph_new (int width, int height)
16 {
17   graph *mygraph;
18   mygraph = (graph *)malloc(sizeof(graph));
19   mygraph->width = width;
20   mygraph->height = height;
21
22
23   int stride = width * 4;
24   unsigned char *image;
25   image = (unsigned char *) malloc (sizeof(unsigned char) * stride * height);
26
27   mygraph->surface = cairo_image_surface_create_for_data (image, CAIRO_FORMAT_ARGB32,
28                                                        width, height, stride);
29   mygraph->cr = cairo_create (mygraph->surface);
30
31   cairo_set_source_rgb (mygraph->cr, 1.0, 1.0, 1.0);
32   mygraph_fill_background (mygraph);
33
34   cairo_select_font_face (mygraph->cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
35                           CAIRO_FONT_WEIGHT_NORMAL);
36   cairo_set_font_size (mygraph->cr, 10);
37
38   cairo_set_antialias(mygraph->cr, CAIRO_ANTIALIAS_NONE);
39   cairo_set_line_width (mygraph->cr, 1.0);
40
41   return mygraph;
42 }
43
44 graph *
45 mygraph_make_graph (graph *mygraph, double min_x, double max_x,
46                     double min_y, double max_y, int tickgran)
47 {
48   int xoffset = 70;
49   cairo_text_extents_t extents;
50
51   mygraph->xoffset = xoffset;
52   mygraph->min_x = min_x;
53   mygraph->max_x = max_x;
54   mygraph->min_y = min_y;
55   mygraph->max_y = max_y;
56
57 /*   cairo_t *cr; */
58 /*   cairo_surface_t *surface; */
59
60   double xs = ((double)mygraph->width - (double)(xoffset+2)) /
61              (double)(max_x - min_x);
62
63   double ys = ((double)mygraph->height - 33.) / (double)(min_y - max_y);
64
65   mygraph->xs = xs;
66   mygraph->ys = ys;
67
68   double starthour = fmod((min_x + (double)tz_local_offset()) / 3600., 24.);
69   double diff, center, begin, end;
70
71   char string[20];
72  
73   int i;
74   for (i = 0; i<240; i++)
75     { // Hour marks and text
76       if ((i % 2) == 0)
77         cairo_set_source_rgb (mygraph->cr, 1.0, 1.0, 1.0);
78       else
79         cairo_set_source_rgb (mygraph->cr, 0.90, 0.90, 1.0);
80       
81       diff = (double)i - starthour;
82       begin = (diff * 3600.) * xs;
83       end = ((double)(i+1) - starthour) * 3600.0 * xs;
84       center = (begin + end) / 2.;
85
86       if (begin < 0.0)
87         continue;
88       if (begin > ((double)mygraph->width - ((double)xoffset)))
89         continue;
90
91       cairo_rectangle (mygraph->cr, xoffset+begin, 0,
92                        end - begin, mygraph->height);
93       
94       cairo_fill (mygraph->cr);
95
96       if (begin <= 0.0 || end >= mygraph->width - (xoffset))
97         continue;
98
99       cairo_set_source_rgb (mygraph->cr, 0.0, 0.0, 0.0);
100
101       sprintf(string, "%d", i % 24);
102 //           printf("showing string %s @ %fx%f\n", string, xoffset + center - (extents.width/2), (mygraph->height - extents.height - 2));
103
104       cairo_text_extents (mygraph->cr, string, &extents);
105       cairo_move_to (mygraph->cr, xoffset + center -
106                      (extents.width/2),
107                      (mygraph->height - extents.height - 2));
108
109       cairo_show_text (mygraph->cr, string);
110
111     }
112
113   cairo_set_source_rgb (mygraph->cr, 0.4, 0.4, 0.4);
114    long long ytick;
115   do
116     {
117       ytick = ((long long)max_y - (long long)min_y) / 11;
118       ytick = (long long)(ceil (ytick / tickgran) * tickgran);
119       tickgran /= 10;
120     } while (((long long)max_y - (long long)min_y) / ytick < 4);
121
122   int y;
123   unsigned long long traf;
124   for (i = -11; i<12; i++)
125     {
126       y = (int)((i * ytick - (long long)max_y) * ys + 10);
127       if (y < 2 || y > mygraph->height - 18)
128         continue;
129
130 /*       printf("draw line at %d\n", y); */
131
132       cairo_move_to (mygraph->cr, xoffset, y);
133       cairo_line_to (mygraph->cr, mygraph->width-1, y);
134
135       if (i == 0)
136         {
137
138           cairo_set_source_rgb (mygraph->cr, 0.0, 0.0, 1.0);
139           cairo_stroke (mygraph->cr);
140           cairo_set_source_rgb (mygraph->cr, 0.6, 0.6, 0.6);
141         }
142       else
143         cairo_stroke (mygraph->cr);
144
145       // draw text
146       traf = 8 * ((unsigned long long)i * ytick);
147 /*       printf("traffic: %d\n", traf); */
148
149       if (traf >= 500000000)
150         sprintf (string, "%.1f Gbit", ((double)traf/1000000000));
151       else if (traf >= 500000)
152         sprintf (string, "%.1f Mbit", ((double)traf/1000000));
153       else
154         sprintf (string, "%.1f kbit", ((double)traf/1000));
155
156       cairo_text_extents (mygraph->cr, string, &extents);
157
158 /*      if (y - (extents.height/2) < 2 ||
159           y + (extents.height/2) > mygraph->height - (extents.height + 2))
160         continue; */
161
162       cairo_move_to (mygraph->cr,
163                      xoffset - 4 - extents.width,
164                      y + (extents.height/2));
165
166       cairo_show_text (mygraph->cr, string);
167     }
168
169   cairo_rectangle (mygraph->cr, xoffset, 0, mygraph->width-xoffset-1, mygraph->height-1);
170
171   cairo_set_source_rgb (mygraph->cr, 0.0, 0.0, 0.0);
172   cairo_stroke (mygraph->cr);
173
174   return mygraph;
175 }
176
177 void
178 mygraph_plot_series (graph *mygraph, int *xvals, unsigned long long *yvals, int n_vals,
179                      double r, double g, double b)
180 {
181   int x, i;
182   unsigned long long y;
183   x = xvals[0];
184   y = yvals[0];
185
186   cairo_set_antialias(mygraph->cr, CAIRO_ANTIALIAS_DEFAULT);
187   cairo_set_source_rgb (mygraph->cr, r, g, b);
188
189   int xp = (int)((x - mygraph->min_x) * mygraph->xs + mygraph->xoffset + 1);
190   int yp = (int)((y - mygraph->max_y) * mygraph->ys + 10);
191   
192   cairo_move_to (mygraph->cr, xp, yp);
193
194 /*   printf("Plotting from:\n");
195    printf("(%d, %d) %d (%d, %d)<br/>\n",
196          x, y, (int)((double)(x - (int)mygraph->min_x) * mygraph->xs + (double)(mygraph->xoffset + 1)) ,
197          (int)((double)(x - (int)mygraph->min_x) * mygraph->xs + (double)(mygraph->xoffset + 1)),
198          (int)((double)(y - (int)mygraph->max_y) * mygraph->ys + 10.)); */
199
200   int last_xp = xp, last_yp = yp;
201   
202   for (i = 1; i < n_vals; i++)
203     {
204       x = xvals[i];
205       y = yvals[i];
206       
207       int xp = (int)((x - mygraph->min_x) * mygraph->xs + mygraph->xoffset + 1);
208       int yp = (int)((y - mygraph->max_y) * mygraph->ys + 10);
209       
210       if (abs(xp - last_xp) < 2 && yp > last_yp)
211         continue;
212       
213       cairo_line_to (mygraph->cr, xp, yp);
214       last_xp = xp;
215       last_yp = yp;
216     }
217
218   cairo_stroke(mygraph->cr);
219 }
220
221 void
222 mygraph_to_file (graph *mygraph, char *filename)
223 {
224   cairo_surface_write_to_png (mygraph->surface, filename);
225 }
226
227 void
228 mygraph_cleanup (graph *self)
229 {
230   cairo_destroy (self->cr);
231   cairo_surface_destroy (self->surface);
232 }
233
234 void
235 mygraph_fill_background (graph *mygraph)
236 {
237   cairo_rectangle (mygraph->cr, 0, 0, mygraph->width, mygraph->height);
238   cairo_fill (mygraph->cr);
239 }
240