1 /* gtkplotflux - flux plots widget for gtk+
2 * Copyright 1999-2001 Adrian E. Feiguin <feiguin@ifir.edu.ar>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <math.h>
24 #include <gtk/gtk.h>
25 #include "gtkplot.h"
26 #include "gtkplot3d.h"
27 #include "gtkplotdata.h"
28 #include "gtkplotflux.h"
29 #include "gtkpsfont.h"
30
31 #define P_(string) string
32
33 static void gtk_plot_flux_class_init (GtkPlotFluxClass *klass);
34 static void gtk_plot_flux_init (GtkPlotFlux *data);
35 static void gtk_plot_flux_destroy (GtkObject *data);
36 static void gtk_plot_flux_get_property (GObject *object,
37 guint prop_id,
38 GValue *value,
39 GParamSpec *pspec);
40 static void gtk_plot_flux_set_property (GObject *object,
41 guint prop_id,
42 const GValue *value,
43 GParamSpec *pspec);
44
45 static void gtk_plot_flux_get_legend_size(GtkPlotData *data,
46 gint *width, gint *height);
47 static void gtk_plot_flux_draw_legend (GtkPlotData *data,
48 gint x, gint y);
49 static void gtk_plot_flux_draw_symbol (GtkPlotData *data,
50 gdouble x,
51 gdouble y,
52 gdouble z,
53 gdouble a,
54 gdouble dx,
55 gdouble dy,
56 gdouble dz,
57 gdouble da);
58 static void gtk_plot_flux_draw_arrow (GtkPlotFlux *flux,
59 gdouble x1, gdouble y1,
60 gdouble x2, gdouble y2);
61
62
63 extern gint roundint (gdouble x);
64
65 enum {
66 ARG_0,
67 ARG_CENTERED,
68 ARG_STYLE,
69 ARG_WIDTH,
70 ARG_LENGTH,
71 ARG_SCALE_MAX,
72 ARG_SIZE_MAX,
73 ARG_SHOW_SCALE,
74 ARG_LABEL_PRECISION,
75 ARG_LABEL_STYLE,
76 ARG_LABEL_PREFIX,
77 ARG_LABEL_SUFFIX,
78 };
79
80 static GtkPlotDataClass *parent_class = NULL;
81
82 GtkType
gtk_plot_flux_get_type(void)83 gtk_plot_flux_get_type (void)
84 {
85 static GtkType data_type = 0;
86
87 if (!data_type)
88 {
89 GtkTypeInfo data_info =
90 {
91 "GtkPlotFlux",
92 sizeof (GtkPlotFlux),
93 sizeof (GtkPlotFluxClass),
94 (GtkClassInitFunc) gtk_plot_flux_class_init,
95 (GtkObjectInitFunc) gtk_plot_flux_init,
96 /* reserved 1*/ NULL,
97 /* reserved 2 */ NULL,
98 (GtkClassInitFunc) NULL,
99 };
100
101 data_type = gtk_type_unique (gtk_plot_data_get_type(), &data_info);
102 }
103 return data_type;
104 }
105
106 static void
gtk_plot_flux_class_init(GtkPlotFluxClass * klass)107 gtk_plot_flux_class_init (GtkPlotFluxClass *klass)
108 {
109 GtkObjectClass *object_class;
110 GtkWidgetClass *widget_class;
111 GtkPlotDataClass *data_class;
112 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
113
114 parent_class = gtk_type_class (gtk_plot_data_get_type ());
115
116 object_class = (GtkObjectClass *) klass;
117 widget_class = (GtkWidgetClass *) klass;
118 data_class = (GtkPlotDataClass *) klass;
119
120 gobject_class->set_property = gtk_plot_flux_set_property;
121 gobject_class->get_property = gtk_plot_flux_get_property;
122 object_class->destroy = gtk_plot_flux_destroy;
123
124 g_object_class_install_property (gobject_class,
125 ARG_CENTERED,
126 g_param_spec_boolean ("centered",
127 P_(""),
128 P_(""),
129 FALSE,
130 G_PARAM_READABLE|G_PARAM_WRITABLE));
131 g_object_class_install_property (gobject_class,
132 ARG_STYLE,
133 g_param_spec_int ("style",
134 P_(""),
135 P_(""),
136 0,G_MAXINT,0,
137 G_PARAM_READABLE|G_PARAM_WRITABLE));
138 g_object_class_install_property (gobject_class,
139 ARG_WIDTH,
140 g_param_spec_int ("width",
141 P_(""),
142 P_(""),
143 0,G_MAXINT,0,
144 G_PARAM_READABLE|G_PARAM_WRITABLE));
145 g_object_class_install_property (gobject_class,
146 ARG_LENGTH,
147 g_param_spec_int ("length",
148 P_(""),
149 P_(""),
150 0,G_MAXINT,0,
151 G_PARAM_READABLE|G_PARAM_WRITABLE));
152 g_object_class_install_property (gobject_class,
153 ARG_SCALE_MAX,
154 g_param_spec_double ("scale_max",
155 P_(""),
156 P_(""),
157 0,G_MAXDOUBLE,0,
158 G_PARAM_READABLE|G_PARAM_WRITABLE));
159 g_object_class_install_property (gobject_class,
160 ARG_SIZE_MAX,
161 g_param_spec_int ("size_max",
162 P_(""),
163 P_(""),
164 0,G_MAXINT,0,
165 G_PARAM_READABLE|G_PARAM_WRITABLE));
166 g_object_class_install_property (gobject_class,
167 ARG_SHOW_SCALE,
168 g_param_spec_boolean ("show_scale",
169 P_(""),
170 P_(""),
171 FALSE,
172 G_PARAM_READABLE|G_PARAM_WRITABLE));
173 g_object_class_install_property (gobject_class,
174 ARG_LABEL_PRECISION,
175 g_param_spec_int ("labels_precision",
176 P_(""),
177 P_(""),
178 0,G_MAXINT,0,
179 G_PARAM_READABLE|G_PARAM_WRITABLE));
180 g_object_class_install_property (gobject_class,
181 ARG_LABEL_STYLE,
182 g_param_spec_int ("labels_style",
183 P_(""),
184 P_(""),
185 0,G_MAXINT,0,
186 G_PARAM_READABLE|G_PARAM_WRITABLE));
187 g_object_class_install_property (gobject_class,
188 ARG_LABEL_PREFIX,
189 g_param_spec_string ("labels_prefix",
190 P_(""),
191 P_(""),
192 NULL,
193 G_PARAM_READABLE|G_PARAM_WRITABLE));
194 g_object_class_install_property (gobject_class,
195 ARG_LABEL_SUFFIX,
196 g_param_spec_string ("labels_suffix",
197 P_(""),
198 P_(""),
199 NULL,
200 G_PARAM_READABLE|G_PARAM_WRITABLE));
201
202 data_class->draw_legend = gtk_plot_flux_draw_legend;
203 data_class->get_legend_size = gtk_plot_flux_get_legend_size;
204 data_class->draw_symbol = gtk_plot_flux_draw_symbol;
205 }
206
207
208 static void
gtk_plot_flux_init(GtkPlotFlux * dataset)209 gtk_plot_flux_init (GtkPlotFlux *dataset)
210 {
211 GtkWidget *widget;
212 GdkColor black, white;
213 GdkColormap *colormap;
214 GtkPlotArray *dim;
215
216 widget = GTK_WIDGET(dataset);
217
218 colormap = gdk_colormap_get_system();
219
220 gdk_color_black(colormap, &black);
221 gdk_color_white(colormap, &white);
222
223 GTK_PLOT_DATA(dataset)->symbol.symbol_style = GTK_PLOT_SYMBOL_EMPTY;
224 GTK_PLOT_DATA(dataset)->symbol.color = black;
225 GTK_PLOT_DATA(dataset)->line.line_style = GTK_PLOT_LINE_SOLID;
226 GTK_PLOT_DATA(dataset)->line.line_width = 1;
227 GTK_PLOT_DATA(dataset)->line.color = black;
228
229 dataset->centered = TRUE;
230 dataset->arrow_length = 8;
231 dataset->arrow_width = 8;
232 dataset->arrow_style = GTK_PLOT_SYMBOL_FILLED;
233
234 dataset->size_max = 1;
235 dataset->scale_max = 1.;
236 dataset->show_scale = TRUE;
237
238 dataset->labels_precision = 3;
239 dataset->labels_style = GTK_PLOT_LABEL_FLOAT;
240 dataset->labels_prefix = NULL;
241 dataset->labels_suffix = NULL;
242
243 dim = gtk_plot_data_find_dimension(GTK_PLOT_DATA(dataset), "x");
244 gtk_plot_array_set_description(dim, "Position X");
245 dim = gtk_plot_data_find_dimension(GTK_PLOT_DATA(dataset), "y");
246 gtk_plot_array_set_description(dim, "Position Y");
247 gtk_plot_array_set_required(dim, TRUE);
248 gtk_plot_array_set_independent(dim, TRUE);
249 dim = gtk_plot_data_find_dimension(GTK_PLOT_DATA(dataset), "z");
250 gtk_plot_array_set_description(dim, "Position Z");
251 gtk_plot_array_set_required(dim, TRUE);
252 gtk_plot_array_set_independent(dim, TRUE);
253 dim = gtk_plot_data_find_dimension(GTK_PLOT_DATA(dataset), "dx");
254 gtk_plot_array_set_required(dim, TRUE);
255 gtk_plot_array_set_label(dim, "DX");
256 gtk_plot_array_set_description(dim, "Size X");
257 dim = gtk_plot_data_find_dimension(GTK_PLOT_DATA(dataset), "dy");
258 gtk_plot_array_set_required(dim, TRUE);
259 gtk_plot_array_set_label(dim, "DY");
260 gtk_plot_array_set_description(dim, "Size Y");
261 dim = gtk_plot_data_find_dimension(GTK_PLOT_DATA(dataset), "dz");
262 gtk_plot_array_set_required(dim, TRUE);
263 gtk_plot_array_set_label(dim, "DZ");
264 gtk_plot_array_set_description(dim, "Size Z");
265 }
266
267 static void
gtk_plot_flux_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)268 gtk_plot_flux_set_property (GObject *object,
269 guint prop_id,
270 const GValue *value,
271 GParamSpec *pspec)
272 {
273 GtkPlotFlux *data;
274
275 data = GTK_PLOT_FLUX (object);
276
277 switch (prop_id)
278 {
279 case ARG_CENTERED:
280 data->centered = g_value_get_boolean(value);
281 break;
282 case ARG_WIDTH:
283 data->arrow_width = g_value_get_int(value);
284 break;
285 case ARG_LENGTH:
286 data->arrow_length = g_value_get_int(value);
287 break;
288 case ARG_STYLE:
289 data->arrow_style = g_value_get_int(value);
290 break;
291 case ARG_SCALE_MAX:
292 data->scale_max = g_value_get_double(value);
293 break;
294 case ARG_SIZE_MAX:
295 data->size_max = g_value_get_int(value);
296 break;
297 case ARG_SHOW_SCALE:
298 data->show_scale = g_value_get_boolean(value);
299 break;
300 case ARG_LABEL_PRECISION:
301 data->labels_precision = g_value_get_int(value);
302 break;
303 case ARG_LABEL_STYLE:
304 data->labels_style = g_value_get_int(value);
305 break;
306 case ARG_LABEL_PREFIX:
307 gtk_plot_flux_set_labels_prefix(data, g_value_get_string(value));
308 break;
309 case ARG_LABEL_SUFFIX:
310 gtk_plot_flux_set_labels_suffix(data, g_value_get_string(value));
311 break;
312 }
313 }
314
315 static void
gtk_plot_flux_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)316 gtk_plot_flux_get_property (GObject *object,
317 guint prop_id,
318 GValue *value,
319 GParamSpec *pspec)
320 {
321 GtkPlotFlux *data;
322
323 data = GTK_PLOT_FLUX (object);
324
325 switch (prop_id)
326 {
327 case ARG_CENTERED:
328 g_value_set_boolean(value, data->centered);
329 break;
330 case ARG_WIDTH:
331 g_value_set_int(value, data->arrow_width);
332 break;
333 case ARG_LENGTH:
334 g_value_set_int(value, data->arrow_length);
335 break;
336 case ARG_STYLE:
337 g_value_set_int(value, data->arrow_style);
338 break;
339 case ARG_SCALE_MAX:
340 g_value_set_double(value, data->scale_max);
341 break;
342 case ARG_SIZE_MAX:
343 g_value_set_int(value, data->size_max);
344 break;
345 case ARG_SHOW_SCALE:
346 g_value_set_boolean(value, data->show_scale);
347 break;
348 case ARG_LABEL_PRECISION:
349 g_value_set_int(value, data->labels_precision);
350 break;
351 case ARG_LABEL_STYLE:
352 g_value_set_int(value, data->labels_style);
353 break;
354 case ARG_LABEL_PREFIX:
355 g_value_set_string(value, data->labels_prefix);
356 break;
357 case ARG_LABEL_SUFFIX:
358 g_value_set_string(value, data->labels_suffix);
359 break;
360 default:
361 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
362 break;
363 }
364 }
365
366 GtkWidget*
gtk_plot_flux_new()367 gtk_plot_flux_new ()
368 {
369 GtkWidget *widget;
370
371 widget = gtk_type_new (gtk_plot_flux_get_type ());
372
373 return (widget);
374 }
375
376 static void
gtk_plot_flux_destroy(GtkObject * object)377 gtk_plot_flux_destroy(GtkObject *object)
378 {
379 GtkPlotFlux *flux = GTK_PLOT_FLUX(object);
380
381 if(flux->labels_prefix) g_free(flux->labels_prefix);
382 flux->labels_prefix = NULL;
383 if(flux->labels_suffix) g_free(flux->labels_suffix);
384 flux->labels_suffix = NULL;
385
386 if (GTK_OBJECT_CLASS (parent_class)->destroy)
387 (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
388 }
389
390 static void
gtk_plot_flux_draw_symbol(GtkPlotData * dataset,gdouble x,gdouble y,gdouble z,gdouble a,gdouble dx,gdouble dy,gdouble dz,gdouble da)391 gtk_plot_flux_draw_symbol(GtkPlotData *dataset,
392 gdouble x, gdouble y, gdouble z, gdouble a,
393 gdouble dx, gdouble dy, gdouble dz, gdouble da)
394 {
395 GtkPlot *plot;
396 GtkPlotFlux *flux = NULL;
397 GdkRectangle area, clip_area;
398 gdouble m;
399 gdouble x1 = 0.0, y1 = 0.0, x2 = 0.0, y2=0.0;
400 gdouble factor, size, xm;
401
402 g_return_if_fail(GTK_IS_PLOT_FLUX(dataset));
403
404 flux = GTK_PLOT_FLUX(dataset);
405
406 g_return_if_fail(dataset->plot != NULL);
407 g_return_if_fail(GTK_WIDGET_VISIBLE(dataset->plot));
408
409 plot = dataset->plot;
410
411 m = plot->magnification;
412 area.x = GTK_WIDGET(plot)->allocation.x;
413 area.y = GTK_WIDGET(plot)->allocation.y;
414 area.width = GTK_WIDGET(plot)->allocation.width;
415 area.height = GTK_WIDGET(plot)->allocation.height;
416
417 clip_area.x = area.x + roundint(plot->x * area.width);
418 clip_area.y = area.y + roundint(plot->y * area.height);
419 clip_area.width = roundint(plot->width * area.width);
420 clip_area.height = roundint(plot->height * area.height);
421
422 /*
423 gtk_plot_pc_clip(plot->pc, &clip_area);
424 */
425
426
427 if(GTK_IS_PLOT3D(plot)){
428 gdouble z1, z2 = 0;
429
430 xm = sqrt(dx * dx + dy * dy + dz * dz);
431 factor = xm / flux->scale_max;
432 size = factor * flux->size_max;
433 x2 = size * dx / xm;
434 y2 = size * dy / xm;
435 z2 = size * dz / xm;
436
437 gtk_plot3d_get_pixel(GTK_PLOT3D(plot), x, y, z,
438 &x1, &y1, &z1);
439 }else{
440 if(plot->clip_data &&
441 (x < plot->xmin || x > plot->xmax || y <plot->ymin || y > plot->ymax))
442 return;
443
444 xm = sqrt(dx * dx + dy * dy);
445 factor = xm / flux->scale_max;
446 size = factor * flux->size_max;
447 x2 = size * dx / xm;
448 y2 = size * dy / xm;
449
450 gtk_plot_get_pixel(plot, x, y, &x1, &y1);
451
452 gtk_plot_flux_draw_arrow (flux, x1, y1, x1+x2*m, y1-y2*m);
453 gtk_plot_data_draw_symbol(dataset, x1, y1);
454 }
455
456 /*
457 gtk_plot_pc_clip(plot->pc, NULL);
458 */
459 }
460
461 static void
gtk_plot_flux_get_legend_size(GtkPlotData * data,gint * width,gint * height)462 gtk_plot_flux_get_legend_size(GtkPlotData *data, gint *width, gint *height)
463 {
464 GtkPlotFlux *flux;
465 GtkPlot *plot = NULL;
466 GtkPlotText legend;
467 gint lascent, ldescent, lheight, lwidth;
468 gdouble m;
469 gchar new_label[100], text[100];
470
471 flux = GTK_PLOT_FLUX(data);
472 plot = data->plot;
473
474 m = plot->magnification;
475 legend = plot->legends_attr;
476
477 if(data->legend)
478 legend.text = data->legend;
479 else
480 legend.text = "";
481
482 *width = *height = 0;
483 if(data->show_legend)
484 gtk_plot_text_get_size(legend.text, legend.angle, legend.font,
485 roundint(legend.height * m),
486 width, height,
487 &lascent, &ldescent);
488
489
490 if(flux->show_scale){
491 gchar aux_text[100];
492 gtk_plot_axis_parse_label(data->gradient, flux->scale_max, flux->labels_precision, flux->labels_style, text);
493 if(flux->labels_prefix){
494 g_snprintf(aux_text, 100, "%s%s", flux->labels_prefix, text);
495 g_snprintf(text, 100, aux_text);
496 }
497 if(flux->labels_suffix) {
498 g_snprintf(aux_text, 100, "%s%s", text, flux->labels_suffix);
499 g_snprintf(text, 100, aux_text);
500 }
501
502 g_snprintf(new_label, 100, "%s", text);
503
504 legend.text = new_label;
505 gtk_plot_text_get_size(legend.text, 0, legend.font,
506 roundint(legend.height * m),
507 &lwidth, &lheight,
508 &lascent, &ldescent);
509
510 *width = MAX(*width, lwidth + roundint(m*(flux->size_max + 8)));
511 *height += MAX(lheight , roundint(m*flux->arrow_width));
512 }
513 }
514
515
516 static void
gtk_plot_flux_draw_legend(GtkPlotData * data,gint x,gint y)517 gtk_plot_flux_draw_legend(GtkPlotData *data, gint x, gint y)
518 {
519 GtkPlotFlux *flux;
520 GtkPlot *plot = NULL;
521 GtkPlotText legend;
522 GdkRectangle area;
523 gint lascent, ldescent, lheight, lwidth;
524 gdouble m;
525 gint line_width;
526 gboolean centered;
527
528 flux = GTK_PLOT_FLUX(data);
529 centered = flux->centered;
530
531 g_return_if_fail(data->plot != NULL);
532 g_return_if_fail(GTK_IS_PLOT(data->plot));
533 g_return_if_fail(GTK_WIDGET_VISIBLE(data->plot));
534
535 plot = data->plot;
536 area.x = GTK_WIDGET(plot)->allocation.x;
537 area.y = GTK_WIDGET(plot)->allocation.y;
538 area.width = GTK_WIDGET(plot)->allocation.width;
539 area.height = GTK_WIDGET(plot)->allocation.height;
540
541 m = plot->magnification;
542 legend = plot->legends_attr;
543
544 if(data->legend)
545 legend.text = data->legend;
546 else
547 legend.text = "";
548
549 gtk_plot_text_get_size(legend.text, legend.angle, legend.font,
550 roundint(legend.height * m),
551 &lwidth, &lheight,
552 &lascent, &ldescent);
553
554 if(data->show_legend){
555 line_width = plot->legends_line_width;
556
557 legend.x = (gdouble)(area.x + x) / (gdouble)area.width;
558 legend.y = (gdouble)(area.y + y + lascent) / (gdouble)area.height;
559
560 gtk_plot_draw_text(plot, legend);
561 }
562 if(flux->show_scale){
563 gchar new_label[100], text_max[100];
564
565 flux->centered = FALSE;
566
567 gtk_plot_flux_draw_arrow(flux,
568 area.x + x,
569 area.y + y + lheight * 3 / 2,
570 area.x + x + roundint(flux->size_max*m),
571 area.y + y + lheight * 3 / 2);
572 y += MAX(lheight, roundint(m*flux->arrow_width));
573
574 gtk_plot_axis_parse_label(data->gradient, flux->scale_max, flux->labels_precision, flux->labels_style, text_max);
575 if(flux->labels_prefix){
576 gchar aux_text[100];
577 g_snprintf(aux_text, 100, "%s%s", flux->labels_prefix, text_max);
578 g_snprintf(text_max, 100, aux_text);
579 }
580 if(flux->labels_suffix){
581 gchar aux_text[100];
582 g_snprintf(aux_text, 100, "%s%s", text_max, flux->labels_suffix);
583 g_snprintf(text_max, 100, aux_text);
584 }
585 g_snprintf(new_label, 100, "%s", text_max);
586
587 legend.x = (gdouble)(area.x + x + m*(flux->size_max + 4)) / (gdouble)area.width;
588 legend.y = (gdouble)(area.y + y + lascent) / (gdouble)area.height;
589 legend.text = new_label;
590 gtk_plot_draw_text(plot, legend);
591
592 flux->centered = centered;
593 y += lheight;
594
595 } else
596 y += lheight;
597 }
598
599 static void
gtk_plot_flux_draw_arrow(GtkPlotFlux * flux,gdouble x1,gdouble y1,gdouble x2,gdouble y2)600 gtk_plot_flux_draw_arrow(GtkPlotFlux *flux, gdouble x1, gdouble y1, gdouble x2, gdouble y2)
601 {
602 GtkPlot *plot;
603 GtkPlotData *data;
604 GtkPlotPoint arrow[3];
605 gdouble xm, ym;
606 gdouble width, height;
607 gdouble arrow_width;
608 gdouble line_width;
609 gdouble angle;
610 gdouble length;
611 gdouble m;
612
613 data = GTK_PLOT_DATA(flux);
614 plot = data->plot;
615
616 m = plot->magnification;
617
618 width = fabs(x2 - x1);
619 height = fabs(y2 - y1);
620
621 if(width == 0 && height == 0) return;
622 if(width != 0)
623 angle = atan2((y2 - y1), (x2 - x1));
624 else
625 angle = asin((y2 - y1)/height);
626
627 length = (y2 - y1)*(y2 - y1) + (x2 - x1)*(x2 - x1);
628 if(length > 0.0) length = sqrt(length);
629
630 arrow_width = flux->arrow_width;
631 line_width = data->symbol.border.line_width;
632 gtk_plot_pc_set_color(plot->pc, &data->symbol.color);
633 gtk_plot_pc_set_lineattr (plot->pc, line_width, 0, 0, 0);
634 gtk_plot_pc_set_dash (plot->pc, 0, 0, 0);
635
636 if(flux->centered && width != 0){
637 x1 -= cos(angle) * length / 2.0;
638 x2 -= cos(angle) * length / 2.0;
639 }
640 if(flux->centered && height != 0){
641 y1 -= sin(angle) * length / 2.0;
642 y2 -= sin(angle) * length / 2.0;
643 }
644
645
646 if(flux->arrow_style == GTK_PLOT_SYMBOL_EMPTY)
647 gtk_plot_pc_draw_line(plot->pc, x1, y1, x2, y2);
648 else
649 gtk_plot_pc_draw_line(plot->pc, x1, y1,
650 x2 - flux->arrow_length * m * cos(angle) / 2.,
651 y2 - flux->arrow_length * m * sin(angle) / 2.);
652
653 arrow[1].x = x2;
654 arrow[1].y = y2;
655 xm = x2 - cos(angle) * flux->arrow_length * m;
656 ym = y2 - sin(angle) * flux->arrow_length * m;
657 arrow[0].x = xm - sin(angle)* arrow_width * m / 2.0;
658 arrow[0].y = ym + cos(angle)* arrow_width * m / 2.0;
659 arrow[2].x = xm + sin(angle)* arrow_width * m / 2.0;
660 arrow[2].y = ym - cos(angle)* arrow_width * m / 2.0;
661
662 switch(flux->arrow_style){
663 case GTK_PLOT_SYMBOL_EMPTY:
664 gtk_plot_pc_draw_lines (plot->pc, arrow, 3);
665 break;
666 case GTK_PLOT_SYMBOL_OPAQUE:
667 gtk_plot_pc_set_color(plot->pc, &plot->background);
668 gtk_plot_pc_draw_polygon (plot->pc, TRUE, arrow, 3);
669 gtk_plot_pc_set_color(plot->pc, &data->symbol.color);
670 gtk_plot_pc_draw_polygon (plot->pc, FALSE, arrow, 3);
671 break;
672 case GTK_PLOT_SYMBOL_FILLED:
673 gtk_plot_pc_draw_polygon (plot->pc, TRUE, arrow, 3);
674 }
675 }
676
677 void
gtk_plot_flux_set_arrow(GtkPlotFlux * flux,gint arrow_length,gint arrow_width,GtkPlotSymbolStyle arrow_style)678 gtk_plot_flux_set_arrow (GtkPlotFlux *flux,
679 gint arrow_length,
680 gint arrow_width,
681 GtkPlotSymbolStyle arrow_style)
682 {
683 flux->arrow_length = arrow_length;
684 flux->arrow_width = arrow_width;
685 flux->arrow_style = arrow_style;
686 }
687
688 void
gtk_plot_flux_get_arrow(GtkPlotFlux * flux,gint * arrow_length,gint * arrow_width,GtkPlotSymbolStyle * arrow_style)689 gtk_plot_flux_get_arrow (GtkPlotFlux *flux,
690 gint *arrow_length,
691 gint *arrow_width,
692 GtkPlotSymbolStyle *arrow_style)
693 {
694 *arrow_length = flux->arrow_length;
695 *arrow_width = flux->arrow_width;
696 *arrow_style = flux->arrow_style;
697 }
698
699 void
gtk_plot_flux_center(GtkPlotFlux * flux,gboolean center)700 gtk_plot_flux_center (GtkPlotFlux *flux, gboolean center)
701 {
702 flux->centered = center;
703 }
704
705 gboolean
gtk_plot_flux_is_centered(GtkPlotFlux * flux)706 gtk_plot_flux_is_centered (GtkPlotFlux *flux)
707 {
708 return(flux->centered);
709 }
710
711 void
gtk_plot_flux_show_scale(GtkPlotFlux * flux,gboolean show)712 gtk_plot_flux_show_scale (GtkPlotFlux *flux, gboolean show)
713 {
714 flux->show_scale = show;
715 }
716
717 void
gtk_plot_flux_set_scale_max(GtkPlotFlux * flux,gdouble scale_max)718 gtk_plot_flux_set_scale_max (GtkPlotFlux *flux, gdouble scale_max)
719 {
720 flux->scale_max = fabs(scale_max);
721 }
722
723 void
gtk_plot_flux_set_size_max(GtkPlotFlux * flux,guint size_max)724 gtk_plot_flux_set_size_max (GtkPlotFlux *flux, guint size_max)
725 {
726 flux->size_max = size_max;
727 }
728
729 void
gtk_plot_flux_set_labels_precision(GtkPlotFlux * flux,gint precision)730 gtk_plot_flux_set_labels_precision (GtkPlotFlux *flux, gint precision)
731 {
732 flux->labels_precision = precision;
733 }
734
735 void
gtk_plot_flux_set_labels_style(GtkPlotFlux * flux,GtkPlotLabelStyle style)736 gtk_plot_flux_set_labels_style (GtkPlotFlux *flux, GtkPlotLabelStyle style)
737 {
738 flux->labels_style = style;
739 }
740
741 void
gtk_plot_flux_set_labels_prefix(GtkPlotFlux * flux,const gchar * prefix)742 gtk_plot_flux_set_labels_prefix (GtkPlotFlux *flux, const gchar *prefix)
743 {
744 if(flux->labels_prefix) g_free(flux->labels_prefix);
745 flux->labels_prefix = NULL;
746 if(prefix)
747 flux->labels_prefix = g_strdup(prefix);
748 }
749
750 void
gtk_plot_flux_set_labels_suffix(GtkPlotFlux * flux,const gchar * suffix)751 gtk_plot_flux_set_labels_suffix (GtkPlotFlux *flux, const gchar *suffix)
752 {
753 if(flux->labels_suffix) g_free(flux->labels_suffix);
754 flux->labels_suffix = NULL;
755 if(suffix)
756 flux->labels_suffix = g_strdup(suffix);
757 }
758
759