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