1 /* acre - A cairo-based library for creating plots and charts.
3 * Copyright © 2009 Carl Worth <cworth@cworth.org>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23 #include <cairo-xlib.h>
32 acre_data_t *data0, *data1, *data2;
35 acre = acre_create ();
36 acre_set_x_axis_label (acre, "X axis");
37 acre_set_y_axis_label (acre, "Y axis");
39 data0 = acre_data_create ();
40 data1 = acre_data_create ();
41 data2 = acre_data_create ();
43 acre_data_set_name (data0, "Data 0");
44 acre_data_set_name (data1, "Data 1");
45 acre_data_set_name (data2, "Data 2");
47 for (i = 0; i <= 100; i++) {
48 acre_data_add_point_2d (data0, i, 0 - (i/3.0)*(i/3.0));
51 for (i = 0; i < 100; i++) {
52 double t = 1.0 - (i / 100.0);
53 acre_data_add_point_2d (data1, i, -1000 * (1.0 - t*t*t));
56 for (i = 0; i <= 1000; i++) {
63 y = -1200 + 1000 * sin(t) / t;
64 acre_data_add_point_2d (data2, x, y);
67 acre_add_data (acre, data0);
68 acre_add_data (acre, data1);
69 acre_add_data (acre, data2);
71 acre_set_title (acre, "All the data");
77 draw (Display *dpy, Window window, Visual *visual, acre_t *acre,
78 int width, int height, double x_min, double x_max)
81 cairo_surface_t *surface;
83 surface = cairo_xlib_surface_create (dpy, window, visual,
85 cr = cairo_create (surface);
88 cairo_set_source_rgb (cr, 1, 1, 1);
91 acre_set_x_axis_range (acre, x_min, x_max);
92 acre_draw (acre, cr, width, height);
96 cairo_surface_destroy (surface);
101 handle_events(Display *dpy, Window window, Visual *visual,
102 acre_t *acre, int width, int height)
105 KeyCode quit_code = XKeysymToKeycode (dpy, XStringToKeysym("Q"));
106 KeyCode escape_code = XKeysymToKeycode (dpy, XStringToKeysym("Escape"));
107 KeyCode left_code = XKeysymToKeycode (dpy, XStringToKeysym("Left"));
108 KeyCode right_code = XKeysymToKeycode (dpy, XStringToKeysym("Right"));
109 KeyCode plus_code = XKeysymToKeycode (dpy, XStringToKeysym("plus"));
110 KeyCode equal_code = XKeysymToKeycode (dpy, XStringToKeysym("equal"));
111 KeyCode minus_code = XKeysymToKeycode (dpy, XStringToKeysym("minus"));
112 KeyCode home_code = XKeysymToKeycode (dpy, XStringToKeysym("Home"));
114 bool need_redraw = false;
115 double x_min, x_max, shift;
117 acre_get_x_axis_data_range (acre, &x_min, &x_max);
120 if (! XPending (dpy) && need_redraw)
121 draw (dpy, window, visual, acre,
122 width, height, x_min, x_max);
126 XNextEvent (dpy, &xev);
130 keycode = xev.xkey.keycode;
131 if (keycode == quit_code ||
132 keycode == escape_code)
136 else if (keycode == left_code)
138 shift = PAN * (x_max - x_min);
142 else if (keycode == right_code)
144 shift = PAN * (x_max - x_min);
148 else if (keycode == plus_code ||
149 keycode == equal_code)
151 shift = ZOOM * (x_max - x_min);
155 else if (keycode == minus_code)
157 shift = (ZOOM/(1 - 2 * ZOOM)) * (x_max - x_min);
161 else if (keycode == home_code)
163 acre_get_x_axis_data_range (acre, &x_min, &x_max);
170 case ConfigureNotify:
171 width = xev.xconfigure.width;
172 height = xev.xconfigure.height;
175 if (xev.xexpose.count == 0)
189 XSetWindowAttributes window_attr;
191 unsigned long window_mask, event_mask;
197 acre = load_chart ();
199 dpy = XOpenDisplay (NULL);
202 fprintf(stderr, "Failed to open display %s\n",
207 root = DefaultRootWindow (dpy);
208 white = WhitePixel (dpy, DefaultScreen (dpy));
209 visual = DefaultVisual (dpy, DefaultScreen (dpy));
210 colormap = XCreateColormap (dpy, root, visual, AllocNone);
211 event_mask = KeyPressMask | StructureNotifyMask | ExposureMask;
214 window_mask |= CWBackPixel; window_attr.background_pixel = white;
215 window_mask |= CWBorderPixel; window_attr.border_pixel = white;
216 window_mask |= CWColormap; window_attr.colormap = colormap;
217 window_mask |= CWEventMask; window_attr.event_mask = event_mask;
219 window = XCreateWindow(dpy, root, 0, 0, width, height, 0,
220 DefaultDepth (dpy, DefaultScreen (dpy)),
222 window_mask, &window_attr);
224 XMapWindow (dpy, window);
226 handle_events (dpy, window, visual, acre, width, height);
230 XDestroyWindow (dpy, window);