7 public class Graph
: Gtk
.EventBox
9 private Gpx
.Track track
= null;
10 private Pango
.FontDescription fd
= null;
11 private Cairo
.Surface surf
= null;
12 private int LEFT_OFFSET
=60;
13 private int BOTTOM_OFFSET
=30;
17 this
.fd
= new Pango
.FontDescription();//from_string("sans mono");
18 fd
.set_family("sans mono");
19 this
.app_paintable
= true;
20 this
.visible_window
= true;
21 this
.size_allocate
.connect(size_allocate_cb
);
24 public void set_track(Gpx
.Track track
)
27 /* Invalidate the previous plot, so it is redrawn */
35 private void size_allocate_cb(Gdk
.Rectangle alloc
)
37 /* Invalidate the previous plot, so it is redrawn */
40 override bool expose_event(Gdk
.EventExpose event
)
42 stdout
.printf("Expose event\n");
43 var ctx
= Gdk
.cairo_create(this
.window
);
44 /* If no valid surface, render it */
48 /* Draw the actual surface on the widget */
49 ctx
.set_source_surface(this
.surf
, 0, 0);
50 Gdk
.cairo_region(ctx
, event
.region
);
55 private void update_surface(Gtk
.Widget win
)
57 var ctx
= Gdk
.cairo_create(win
.window
);
58 this
.surf
= new Cairo
.Surface
.similar(ctx
.get_target(),Cairo
.Content
.COLOR_ALPHA
,win
.allocation
.width
, win
.allocation
.height
);
59 ctx
= new Cairo
.Context(this
.surf
);
61 /* Paint background white */
62 ctx
.set_source_rgba(1,1,1,1);
64 if(this
.track
== null) return;
66 double max_speed
= track
.max_speed
;
67 double elapsed_time
= track
.get_total_time();
68 ctx
.translate(LEFT_OFFSET
,20);
69 Point f
= track
.points
.data
;
70 stdout
.printf("%f\n", f
.get_time());
73 double graph_width
= win
.allocation
.width
-LEFT_OFFSET
-10;
74 double graph_height
= win
.allocation
.height
-20-BOTTOM_OFFSET
;
76 var layout
= Pango
.cairo_create_layout(ctx
);
78 double step_size
= (graph_height
)/8.0;
79 ctx
.set_source_rgba(0.2, 0.2, 0.2, 0.6);
80 ctx
.set_line_width(1);
81 for(j
=graph_height
;j
>0.0;j
-=step_size
){
83 ctx
.line_to(graph_width
,j
);
87 /* Draw speed and ticks */
88 ctx
.set_source_rgba(0.0, 0.0, 0.0, 1.0);
89 double size
= LEFT_OFFSET
/("%.1f".printf(max_speed
).length
);
90 if(size
> step_size
) size
= step_size
;
91 fd
.set_absolute_size(size
*1024);
92 layout
.set_font_description(fd
);
93 for(j
=0;j
<graph_height
;j
+=step_size
){
94 double speed
= max_speed
*((graph_height
-j
)/graph_height
);
95 var text
= "%.1f".printf(speed
);
97 layout
.set_text(text
,-1);
98 layout
.get_pixel_size(out w
, out h
);
99 ctx
.move_to(-w
-5, j
-h
/2.0);
100 Pango
.cairo_layout_path(ctx
, layout
);
108 ctx
.move_to(0.0,0.0);
109 ctx
.set_source_rgba(0.0, 0.0, 0.0, 1);
110 ctx
.set_line_width(1.5);
111 ctx
.line_to(0.0, graph_height
);
112 ctx
.line_to(graph_width
, graph_height
);
117 ctx
.set_source_rgba(0.1, 0.2, 0.3, 1);
118 ctx
.set_line_width(1);
119 weak List
<Point?
> iter
= track
.points
.first();
120 ctx
.move_to(0.0, graph_height
);
121 while(iter
.next
!= null)
123 weak List
<Point?
> now
= iter
.next
;
124 double time_offset
= (iter
.data
.get_time()-f
.get_time());
125 ctx
.line_to(graph_width
*(double)(time_offset
/(double)elapsed_time
),graph_height
*(double)(1.0-track
.calculate_point_to_point_speed(now
.data
, iter
.data
)/max_speed
));
128 ctx
.line_to(graph_width
, graph_height
);
130 ctx
.stroke_preserve();
132 ctx
.set_source_rgba(0.1, 0.2, 0.8, 0.5);
136 iter
= track
.points
.first();
138 ctx
.set_source_rgba(0.0, 0.0, 0.0, 1.0);
139 fd
.set_absolute_size(12*1024);
140 layout
.set_font_description(fd
);
141 uint interval
= (uint)elapsed_time
/((uint)(graph_width
/(5*12.0)));
143 stdout
.printf("interval %u\n", interval
);
145 for(i
=0; i
< elapsed_time
; i
+= interval
)
147 if(graph_width
*(1-(i
/elapsed_time
)) > 2.5*12 ){
149 var text
= "%02i:%02i".printf((int)i
/3600, ((int)i
%3600)/60);
150 layout
.set_text(text
,-1);
151 layout
.get_pixel_size(out w
, out h
);
152 ctx
.move_to(graph_width
*(double)(i
/elapsed_time
)-w
/2.0, graph_height
+10);
153 Pango
.cairo_layout_path(ctx
, layout
);
157 ctx
.move_to(graph_width
*(double)(i
/elapsed_time
), graph_height
);
158 ctx
.line_to(graph_width
*(double)(i
/elapsed_time
), graph_height
+5);
164 /* Draw average speed */
165 var avg
= track
.get_track_average();
166 ctx
.set_source_rgba(0.0, 0.7, 0.0, 0.7);
167 ctx
.move_to(0.0, graph_height
*(1-avg
/max_speed
));
168 ctx
.line_to(graph_width
, graph_height
*(1-avg
/max_speed
));
172 /* Draw moving speed */
174 avg
= track
.calculate_moving_average(out moving_time
);
175 ctx
.set_source_rgba(0.7, 0.0, 0.0, 0.7);
176 ctx
.move_to(0.0, graph_height
*(1-avg
/max_speed
));
177 ctx
.line_to(graph_width
, graph_height
*(1-avg
/max_speed
));
182 ctx
.set_source_rgba(0.0, 0.0, 0.0, 1.0);
183 fd
.set_absolute_size(12*1024);
184 layout
.set_font_description(fd
);
185 layout
.set_text("Speed (km/h) vs Time (HH:MM)",-1);
186 layout
.get_pixel_size(out w
, out h
);
187 ctx
.move_to(graph_width
/2-w
/2, -20);
188 Pango
.cairo_layout_path(ctx
, layout
);