PluginProbe
Contact Forms by Cimatti / 1.3.2
Contact Forms by Cimatti v1.3.2
2.3.6 2.3.5 2.3.0 2.2.32 2.2.4 2.2.0 2.1.2 2.1.1 trunk 1.0 1.1 1.2 1.2.1 1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 All 62 releases
contact-forms / flot / jquery.flot.image.js

jquery.flot.image.js in Contact Forms by Cimatti 1.3.2, at flot/jquery.flot.image.js

239 lines 7.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*
2 Flot plugin for plotting images, e.g. useful for putting ticks on a
3 prerendered complex visualization.
4
5 The data syntax is [[image, x1, y1, x2, y2], ...] where (x1, y1) and
6 (x2, y2) are where you intend the two opposite corners of the image to
7 end up in the plot. Image must be a fully loaded Javascript image (you
8 can make one with new Image()). If the image is not complete, it's
9 skipped when plotting.
10
11 There are two helpers included for retrieving images. The easiest work
12 the way that you put in URLs instead of images in the data (like
13 ["myimage.png", 0, 0, 10, 10]), then call $.plot.image.loadData(data,
14 options, callback) where data and options are the same as you pass in
15 to $.plot. This loads the images, replaces the URLs in the data with
16 the corresponding images and calls "callback" when all images are
17 loaded (or failed loading). In the callback, you can then call $.plot
18 with the data set. See the included example.
19
20 A more low-level helper, $.plot.image.load(urls, callback) is also
21 included. Given a list of URLs, it calls callback with an object
22 mapping from URL to Image object when all images are loaded or have
23 failed loading.
24
25 Options for the plugin are
26
27 series: {
28 images: {
29 show: boolean
30 anchor: "corner" or "center"
31 alpha: [0,1]
32 }
33 }
34
35 which can be specified for a specific series
36
37 $.plot($("#placeholder"), [{ data: [ ... ], images: { ... } ])
38
39 Note that because the data format is different from usual data points,
40 you can't use images with anything else in a specific data series.
41
42 Setting "anchor" to "center" causes the pixels in the image to be
43 anchored at the corner pixel centers inside of at the pixel corners,
44 effectively letting half a pixel stick out to each side in the plot.
45
46
47 A possible future direction could be support for tiling for large
48 images (like Google Maps).
49
50 */
51
52 (function ($) {
53 var options = {
54 series: {
55 images: {
56 show: false,
57 alpha: 1,
58 anchor: "corner" // or "center"
59 }
60 }
61 };
62
63 $.plot.image = {};
64
65 $.plot.image.loadDataImages = function (series, options, callback) {
66 var urls = [], points = [];
67
68 var defaultShow = options.series.images.show;
69
70 $.each(series, function (i, s) {
71 if (!(defaultShow || s.images.show))
72 return;
73
74 if (s.data)
75 s = s.data;
76
77 $.each(s, function (i, p) {
78 if (typeof p[0] == "string") {
79 urls.push(p[0]);
80 points.push(p);
81 }
82 });
83 });
84
85 $.plot.image.load(urls, function (loadedImages) {
86 $.each(points, function (i, p) {
87 var url = p[0];
88 if (loadedImages[url])
89 p[0] = loadedImages[url];
90 });
91
92 callback();
93 });
94 }
95
96 $.plot.image.load = function (urls, callback) {
97 var missing = urls.length, loaded = {};
98 if (missing == 0)
99 callback({});
100
101 $.each(urls, function (i, url) {
102 var handler = function () {
103 --missing;
104
105 loaded[url] = this;
106
107 if (missing == 0)
108 callback(loaded);
109 };
110
111 $('<img />').load(handler).error(handler).attr('src', url);
112 });
113 }
114
115 function drawSeries(plot, ctx, series) {
116 var plotOffset = plot.getPlotOffset();
117
118 if (!series.images || !series.images.show)
119 return;
120
121 var points = series.datapoints.points,
122 ps = series.datapoints.pointsize;
123
124 for (var i = 0; i < points.length; i += ps) {
125 var img = points[i],
126 x1 = points[i + 1], y1 = points[i + 2],
127 x2 = points[i + 3], y2 = points[i + 4],
128 xaxis = series.xaxis, yaxis = series.yaxis,
129 tmp;
130
131 // actually we should check img.complete, but it
132 // appears to be a somewhat unreliable indicator in
133 // IE6 (false even after load event)
134 if (!img || img.width <= 0 || img.height <= 0)
135 continue;
136
137 if (x1 > x2) {
138 tmp = x2;
139 x2 = x1;
140 x1 = tmp;
141 }
142 if (y1 > y2) {
143 tmp = y2;
144 y2 = y1;
145 y1 = tmp;
146 }
147
148 // if the anchor is at the center of the pixel, expand the
149 // image by 1/2 pixel in each direction
150 if (series.images.anchor == "center") {
151 tmp = 0.5 * (x2-x1) / (img.width - 1);
152 x1 -= tmp;
153 x2 += tmp;
154 tmp = 0.5 * (y2-y1) / (img.height - 1);
155 y1 -= tmp;
156 y2 += tmp;
157 }
158
159 // clip
160 if (x1 == x2 || y1 == y2 ||
161 x1 >= xaxis.max || x2 <= xaxis.min ||
162 y1 >= yaxis.max || y2 <= yaxis.min)
163 continue;
164
165 var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height;
166 if (x1 < xaxis.min) {
167 sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1);
168 x1 = xaxis.min;
169 }
170
171 if (x2 > xaxis.max) {
172 sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1);
173 x2 = xaxis.max;
174 }
175
176 if (y1 < yaxis.min) {
177 sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1);
178 y1 = yaxis.min;
179 }
180
181 if (y2 > yaxis.max) {
182 sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1);
183 y2 = yaxis.max;
184 }
185
186 x1 = xaxis.p2c(x1);
187 x2 = xaxis.p2c(x2);
188 y1 = yaxis.p2c(y1);
189 y2 = yaxis.p2c(y2);
190
191 // the transformation may have swapped us
192 if (x1 > x2) {
193 tmp = x2;
194 x2 = x1;
195 x1 = tmp;
196 }
197 if (y1 > y2) {
198 tmp = y2;
199 y2 = y1;
200 y1 = tmp;
201 }
202
203 tmp = ctx.globalAlpha;
204 ctx.globalAlpha *= series.images.alpha;
205 ctx.drawImage(img,
206 sx1, sy1, sx2 - sx1, sy2 - sy1,
207 x1 + plotOffset.left, y1 + plotOffset.top,
208 x2 - x1, y2 - y1);
209 ctx.globalAlpha = tmp;
210 }
211 }
212
213 function processRawData(plot, series, data, datapoints) {
214 if (!series.images.show)
215 return;
216
217 // format is Image, x1, y1, x2, y2 (opposite corners)
218 datapoints.format = [
219 { required: true },
220 { x: true, number: true, required: true },
221 { y: true, number: true, required: true },
222 { x: true, number: true, required: true },
223 { y: true, number: true, required: true }
224 ];
225 }
226
227 function init(plot) {
228 plot.hooks.processRawData.push(processRawData);
229 plot.hooks.drawSeries.push(drawSeries);
230 }
231
232 $.plot.plugins.push({
233 init: init,
234 options: options,
235 name: 'image',
236 version: '1.1'
237 });
238 })(jQuery);
239