columbus3 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (199) hide show
  1. checksums.yaml +4 -4
  2. data/README.textile +62 -0
  3. data/bower_components/flot/.bower.json +19 -0
  4. data/bower_components/flot/.gitignore +3 -0
  5. data/bower_components/flot/.travis.yml +3 -0
  6. data/bower_components/flot/API.md +1498 -0
  7. data/bower_components/flot/CONTRIBUTING.md +98 -0
  8. data/bower_components/flot/FAQ.md +75 -0
  9. data/bower_components/flot/LICENSE.txt +22 -0
  10. data/bower_components/flot/Makefile +12 -0
  11. data/bower_components/flot/NEWS.md +1026 -0
  12. data/bower_components/flot/PLUGINS.md +143 -0
  13. data/bower_components/flot/README.md +110 -0
  14. data/bower_components/flot/component.json +8 -0
  15. data/bower_components/flot/examples/ajax/data-eu-gdp-growth-1.json +4 -0
  16. data/bower_components/flot/examples/ajax/data-eu-gdp-growth-2.json +4 -0
  17. data/bower_components/flot/examples/ajax/data-eu-gdp-growth-3.json +4 -0
  18. data/bower_components/flot/examples/ajax/data-eu-gdp-growth-4.json +4 -0
  19. data/bower_components/flot/examples/ajax/data-eu-gdp-growth-5.json +4 -0
  20. data/bower_components/flot/examples/ajax/data-eu-gdp-growth.json +4 -0
  21. data/bower_components/flot/examples/ajax/data-japan-gdp-growth.json +4 -0
  22. data/bower_components/flot/examples/ajax/data-usa-gdp-growth.json +4 -0
  23. data/bower_components/flot/examples/ajax/index.html +173 -0
  24. data/bower_components/flot/examples/annotating/index.html +87 -0
  25. data/bower_components/flot/examples/axes-interacting/index.html +97 -0
  26. data/bower_components/flot/examples/axes-multiple/index.html +77 -0
  27. data/bower_components/flot/examples/axes-time-zones/date.js +893 -0
  28. data/bower_components/flot/examples/axes-time-zones/index.html +114 -0
  29. data/bower_components/flot/examples/axes-time-zones/tz/africa +1181 -0
  30. data/bower_components/flot/examples/axes-time-zones/tz/antarctica +413 -0
  31. data/bower_components/flot/examples/axes-time-zones/tz/asia +2717 -0
  32. data/bower_components/flot/examples/axes-time-zones/tz/australasia +1719 -0
  33. data/bower_components/flot/examples/axes-time-zones/tz/backward +117 -0
  34. data/bower_components/flot/examples/axes-time-zones/tz/etcetera +81 -0
  35. data/bower_components/flot/examples/axes-time-zones/tz/europe +2856 -0
  36. data/bower_components/flot/examples/axes-time-zones/tz/factory +10 -0
  37. data/bower_components/flot/examples/axes-time-zones/tz/iso3166.tab +276 -0
  38. data/bower_components/flot/examples/axes-time-zones/tz/leapseconds +100 -0
  39. data/bower_components/flot/examples/axes-time-zones/tz/northamerica +3235 -0
  40. data/bower_components/flot/examples/axes-time-zones/tz/pacificnew +28 -0
  41. data/bower_components/flot/examples/axes-time-zones/tz/solar87 +390 -0
  42. data/bower_components/flot/examples/axes-time-zones/tz/solar88 +390 -0
  43. data/bower_components/flot/examples/axes-time-zones/tz/solar89 +395 -0
  44. data/bower_components/flot/examples/axes-time-zones/tz/southamerica +1711 -0
  45. data/bower_components/flot/examples/axes-time-zones/tz/systemv +38 -0
  46. data/bower_components/flot/examples/axes-time-zones/tz/yearistype.sh +38 -0
  47. data/bower_components/flot/examples/axes-time-zones/tz/zone.tab +441 -0
  48. data/bower_components/flot/examples/axes-time/index.html +137 -0
  49. data/bower_components/flot/examples/background.png +0 -0
  50. data/bower_components/flot/examples/basic-options/index.html +91 -0
  51. data/bower_components/flot/examples/basic-usage/index.html +57 -0
  52. data/bower_components/flot/examples/canvas/index.html +75 -0
  53. data/bower_components/flot/examples/categories/index.html +64 -0
  54. data/bower_components/flot/examples/examples.css +97 -0
  55. data/bower_components/flot/examples/image/hs-2004-27-a-large-web.jpg +0 -0
  56. data/bower_components/flot/examples/image/index.html +69 -0
  57. data/bower_components/flot/examples/index.html +80 -0
  58. data/bower_components/flot/examples/interacting/index.html +118 -0
  59. data/bower_components/flot/examples/navigate/arrow-down.gif +0 -0
  60. data/bower_components/flot/examples/navigate/arrow-left.gif +0 -0
  61. data/bower_components/flot/examples/navigate/arrow-right.gif +0 -0
  62. data/bower_components/flot/examples/navigate/arrow-up.gif +0 -0
  63. data/bower_components/flot/examples/navigate/index.html +153 -0
  64. data/bower_components/flot/examples/percentiles/index.html +79 -0
  65. data/bower_components/flot/examples/realtime/index.html +122 -0
  66. data/bower_components/flot/examples/resize/index.html +76 -0
  67. data/bower_components/flot/examples/selection/index.html +152 -0
  68. data/bower_components/flot/examples/series-errorbars/index.html +150 -0
  69. data/bower_components/flot/examples/series-pie/index.html +818 -0
  70. data/bower_components/flot/examples/series-toggle/index.html +121 -0
  71. data/bower_components/flot/examples/series-types/index.html +90 -0
  72. data/bower_components/flot/examples/shared/jquery-ui/jquery-ui.min.css +6 -0
  73. data/bower_components/flot/examples/stacking/index.html +107 -0
  74. data/bower_components/flot/examples/symbols/index.html +76 -0
  75. data/bower_components/flot/examples/threshold/index.html +76 -0
  76. data/bower_components/flot/examples/tracking/index.html +135 -0
  77. data/bower_components/flot/examples/visitors/index.html +147 -0
  78. data/bower_components/flot/examples/zooming/index.html +144 -0
  79. data/bower_components/flot/excanvas.js +1428 -0
  80. data/bower_components/flot/excanvas.min.js +1 -0
  81. data/bower_components/flot/flot.jquery.json +27 -0
  82. data/bower_components/flot/jquery.colorhelpers.js +180 -0
  83. data/bower_components/flot/jquery.flot.canvas.js +345 -0
  84. data/bower_components/flot/jquery.flot.categories.js +190 -0
  85. data/bower_components/flot/jquery.flot.crosshair.js +176 -0
  86. data/bower_components/flot/jquery.flot.errorbars.js +353 -0
  87. data/bower_components/flot/jquery.flot.fillbetween.js +226 -0
  88. data/bower_components/flot/jquery.flot.image.js +241 -0
  89. data/bower_components/flot/jquery.flot.js +3168 -0
  90. data/bower_components/flot/jquery.flot.navigate.js +346 -0
  91. data/bower_components/flot/jquery.flot.pie.js +820 -0
  92. data/bower_components/flot/jquery.flot.resize.js +59 -0
  93. data/bower_components/flot/jquery.flot.selection.js +360 -0
  94. data/bower_components/flot/jquery.flot.stack.js +188 -0
  95. data/bower_components/flot/jquery.flot.symbol.js +71 -0
  96. data/bower_components/flot/jquery.flot.threshold.js +142 -0
  97. data/bower_components/flot/jquery.flot.time.js +432 -0
  98. data/bower_components/flot/jquery.js +9472 -0
  99. data/bower_components/flot/package.json +11 -0
  100. data/bower_components/jquery/.bower.json +38 -0
  101. data/bower_components/jquery/MIT-LICENSE.txt +21 -0
  102. data/bower_components/jquery/bower.json +28 -0
  103. data/bower_components/jquery/dist/jquery.js +9210 -0
  104. data/bower_components/jquery/dist/jquery.min.js +5 -0
  105. data/bower_components/jquery/dist/jquery.min.map +1 -0
  106. data/bower_components/jquery/src/ajax.js +786 -0
  107. data/bower_components/jquery/src/ajax/jsonp.js +89 -0
  108. data/bower_components/jquery/src/ajax/load.js +75 -0
  109. data/bower_components/jquery/src/ajax/parseJSON.js +13 -0
  110. data/bower_components/jquery/src/ajax/parseXML.js +28 -0
  111. data/bower_components/jquery/src/ajax/script.js +64 -0
  112. data/bower_components/jquery/src/ajax/var/nonce.js +5 -0
  113. data/bower_components/jquery/src/ajax/var/rquery.js +3 -0
  114. data/bower_components/jquery/src/ajax/xhr.js +136 -0
  115. data/bower_components/jquery/src/attributes.js +11 -0
  116. data/bower_components/jquery/src/attributes/attr.js +141 -0
  117. data/bower_components/jquery/src/attributes/classes.js +158 -0
  118. data/bower_components/jquery/src/attributes/prop.js +94 -0
  119. data/bower_components/jquery/src/attributes/support.js +35 -0
  120. data/bower_components/jquery/src/attributes/val.js +161 -0
  121. data/bower_components/jquery/src/callbacks.js +205 -0
  122. data/bower_components/jquery/src/core.js +502 -0
  123. data/bower_components/jquery/src/core/access.js +60 -0
  124. data/bower_components/jquery/src/core/init.js +123 -0
  125. data/bower_components/jquery/src/core/parseHTML.js +39 -0
  126. data/bower_components/jquery/src/core/ready.js +97 -0
  127. data/bower_components/jquery/src/core/var/rsingleTag.js +4 -0
  128. data/bower_components/jquery/src/css.js +450 -0
  129. data/bower_components/jquery/src/css/addGetHookIf.js +22 -0
  130. data/bower_components/jquery/src/css/curCSS.js +57 -0
  131. data/bower_components/jquery/src/css/defaultDisplay.js +70 -0
  132. data/bower_components/jquery/src/css/hiddenVisibleSelectors.js +15 -0
  133. data/bower_components/jquery/src/css/support.js +96 -0
  134. data/bower_components/jquery/src/css/swap.js +28 -0
  135. data/bower_components/jquery/src/css/var/cssExpand.js +3 -0
  136. data/bower_components/jquery/src/css/var/getStyles.js +12 -0
  137. data/bower_components/jquery/src/css/var/isHidden.js +13 -0
  138. data/bower_components/jquery/src/css/var/rmargin.js +3 -0
  139. data/bower_components/jquery/src/css/var/rnumnonpx.js +5 -0
  140. data/bower_components/jquery/src/data.js +178 -0
  141. data/bower_components/jquery/src/data/Data.js +181 -0
  142. data/bower_components/jquery/src/data/accepts.js +20 -0
  143. data/bower_components/jquery/src/data/var/data_priv.js +5 -0
  144. data/bower_components/jquery/src/data/var/data_user.js +5 -0
  145. data/bower_components/jquery/src/deferred.js +149 -0
  146. data/bower_components/jquery/src/deprecated.js +13 -0
  147. data/bower_components/jquery/src/dimensions.js +50 -0
  148. data/bower_components/jquery/src/effects.js +648 -0
  149. data/bower_components/jquery/src/effects/Tween.js +114 -0
  150. data/bower_components/jquery/src/effects/animatedSelector.js +13 -0
  151. data/bower_components/jquery/src/event.js +868 -0
  152. data/bower_components/jquery/src/event/ajax.js +13 -0
  153. data/bower_components/jquery/src/event/alias.js +39 -0
  154. data/bower_components/jquery/src/event/support.js +9 -0
  155. data/bower_components/jquery/src/exports/amd.js +24 -0
  156. data/bower_components/jquery/src/exports/global.js +32 -0
  157. data/bower_components/jquery/src/intro.js +44 -0
  158. data/bower_components/jquery/src/jquery.js +37 -0
  159. data/bower_components/jquery/src/manipulation.js +580 -0
  160. data/bower_components/jquery/src/manipulation/_evalUrl.js +18 -0
  161. data/bower_components/jquery/src/manipulation/support.js +32 -0
  162. data/bower_components/jquery/src/manipulation/var/rcheckableType.js +3 -0
  163. data/bower_components/jquery/src/offset.js +207 -0
  164. data/bower_components/jquery/src/outro.js +1 -0
  165. data/bower_components/jquery/src/queue.js +142 -0
  166. data/bower_components/jquery/src/queue/delay.js +22 -0
  167. data/bower_components/jquery/src/selector-native.js +172 -0
  168. data/bower_components/jquery/src/selector-sizzle.js +14 -0
  169. data/bower_components/jquery/src/selector.js +1 -0
  170. data/bower_components/jquery/src/serialize.js +111 -0
  171. data/bower_components/jquery/src/sizzle/dist/sizzle.js +2067 -0
  172. data/bower_components/jquery/src/sizzle/dist/sizzle.min.js +3 -0
  173. data/bower_components/jquery/src/sizzle/dist/sizzle.min.map +1 -0
  174. data/bower_components/jquery/src/traversing.js +199 -0
  175. data/bower_components/jquery/src/traversing/findFilter.js +100 -0
  176. data/bower_components/jquery/src/traversing/var/rneedsContext.js +6 -0
  177. data/bower_components/jquery/src/var/arr.js +3 -0
  178. data/bower_components/jquery/src/var/class2type.js +4 -0
  179. data/bower_components/jquery/src/var/concat.js +5 -0
  180. data/bower_components/jquery/src/var/hasOwn.js +5 -0
  181. data/bower_components/jquery/src/var/indexOf.js +5 -0
  182. data/bower_components/jquery/src/var/pnum.js +3 -0
  183. data/bower_components/jquery/src/var/push.js +5 -0
  184. data/bower_components/jquery/src/var/rnotwhite.js +3 -0
  185. data/bower_components/jquery/src/var/slice.js +5 -0
  186. data/bower_components/jquery/src/var/strundefined.js +3 -0
  187. data/bower_components/jquery/src/var/support.js +4 -0
  188. data/bower_components/jquery/src/var/toString.js +5 -0
  189. data/bower_components/jquery/src/wrap.js +79 -0
  190. data/columbus3.gemspec +1 -1
  191. data/exe/columbus3 +72 -7
  192. data/lib/columbus3.rb +2 -1
  193. data/lib/columbus3/metadata/sidecar.rb +10 -1
  194. data/lib/columbus3/renderer/flot_renderer.rb +66 -0
  195. data/lib/columbus3/renderer/{renderer.rb → leaflet_renderer.rb} +0 -0
  196. data/lib/columbus3/version.rb +1 -1
  197. data/lib/html/flot.html.erb +106 -0
  198. metadata +194 -5
  199. data/README.md +0 -41
@@ -0,0 +1,226 @@
1
+ /* Flot plugin for computing bottoms for filled line and bar charts.
2
+
3
+ Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+ Licensed under the MIT license.
5
+
6
+ The case: you've got two series that you want to fill the area between. In Flot
7
+ terms, you need to use one as the fill bottom of the other. You can specify the
8
+ bottom of each data point as the third coordinate manually, or you can use this
9
+ plugin to compute it for you.
10
+
11
+ In order to name the other series, you need to give it an id, like this:
12
+
13
+ var dataset = [
14
+ { data: [ ... ], id: "foo" } , // use default bottom
15
+ { data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom
16
+ ];
17
+
18
+ $.plot($("#placeholder"), dataset, { lines: { show: true, fill: true }});
19
+
20
+ As a convenience, if the id given is a number that doesn't appear as an id in
21
+ the series, it is interpreted as the index in the array instead (so fillBetween:
22
+ 0 can also mean the first series).
23
+
24
+ Internally, the plugin modifies the datapoints in each series. For line series,
25
+ extra data points might be inserted through interpolation. Note that at points
26
+ where the bottom line is not defined (due to a null point or start/end of line),
27
+ the current line will show a gap too. The algorithm comes from the
28
+ jquery.flot.stack.js plugin, possibly some code could be shared.
29
+
30
+ */
31
+
32
+ (function ( $ ) {
33
+
34
+ var options = {
35
+ series: {
36
+ fillBetween: null // or number
37
+ }
38
+ };
39
+
40
+ function init( plot ) {
41
+
42
+ function findBottomSeries( s, allseries ) {
43
+
44
+ var i;
45
+
46
+ for ( i = 0; i < allseries.length; ++i ) {
47
+ if ( allseries[ i ].id === s.fillBetween ) {
48
+ return allseries[ i ];
49
+ }
50
+ }
51
+
52
+ if ( typeof s.fillBetween === "number" ) {
53
+ if ( s.fillBetween < 0 || s.fillBetween >= allseries.length ) {
54
+ return null;
55
+ }
56
+ return allseries[ s.fillBetween ];
57
+ }
58
+
59
+ return null;
60
+ }
61
+
62
+ function computeFillBottoms( plot, s, datapoints ) {
63
+
64
+ if ( s.fillBetween == null ) {
65
+ return;
66
+ }
67
+
68
+ var other = findBottomSeries( s, plot.getData() );
69
+
70
+ if ( !other ) {
71
+ return;
72
+ }
73
+
74
+ var ps = datapoints.pointsize,
75
+ points = datapoints.points,
76
+ otherps = other.datapoints.pointsize,
77
+ otherpoints = other.datapoints.points,
78
+ newpoints = [],
79
+ px, py, intery, qx, qy, bottom,
80
+ withlines = s.lines.show,
81
+ withbottom = ps > 2 && datapoints.format[2].y,
82
+ withsteps = withlines && s.lines.steps,
83
+ fromgap = true,
84
+ i = 0,
85
+ j = 0,
86
+ l, m;
87
+
88
+ while ( true ) {
89
+
90
+ if ( i >= points.length ) {
91
+ break;
92
+ }
93
+
94
+ l = newpoints.length;
95
+
96
+ if ( points[ i ] == null ) {
97
+
98
+ // copy gaps
99
+
100
+ for ( m = 0; m < ps; ++m ) {
101
+ newpoints.push( points[ i + m ] );
102
+ }
103
+
104
+ i += ps;
105
+
106
+ } else if ( j >= otherpoints.length ) {
107
+
108
+ // for lines, we can't use the rest of the points
109
+
110
+ if ( !withlines ) {
111
+ for ( m = 0; m < ps; ++m ) {
112
+ newpoints.push( points[ i + m ] );
113
+ }
114
+ }
115
+
116
+ i += ps;
117
+
118
+ } else if ( otherpoints[ j ] == null ) {
119
+
120
+ // oops, got a gap
121
+
122
+ for ( m = 0; m < ps; ++m ) {
123
+ newpoints.push( null );
124
+ }
125
+
126
+ fromgap = true;
127
+ j += otherps;
128
+
129
+ } else {
130
+
131
+ // cases where we actually got two points
132
+
133
+ px = points[ i ];
134
+ py = points[ i + 1 ];
135
+ qx = otherpoints[ j ];
136
+ qy = otherpoints[ j + 1 ];
137
+ bottom = 0;
138
+
139
+ if ( px === qx ) {
140
+
141
+ for ( m = 0; m < ps; ++m ) {
142
+ newpoints.push( points[ i + m ] );
143
+ }
144
+
145
+ //newpoints[ l + 1 ] += qy;
146
+ bottom = qy;
147
+
148
+ i += ps;
149
+ j += otherps;
150
+
151
+ } else if ( px > qx ) {
152
+
153
+ // we got past point below, might need to
154
+ // insert interpolated extra point
155
+
156
+ if ( withlines && i > 0 && points[ i - ps ] != null ) {
157
+ intery = py + ( points[ i - ps + 1 ] - py ) * ( qx - px ) / ( points[ i - ps ] - px );
158
+ newpoints.push( qx );
159
+ newpoints.push( intery );
160
+ for ( m = 2; m < ps; ++m ) {
161
+ newpoints.push( points[ i + m ] );
162
+ }
163
+ bottom = qy;
164
+ }
165
+
166
+ j += otherps;
167
+
168
+ } else { // px < qx
169
+
170
+ // if we come from a gap, we just skip this point
171
+
172
+ if ( fromgap && withlines ) {
173
+ i += ps;
174
+ continue;
175
+ }
176
+
177
+ for ( m = 0; m < ps; ++m ) {
178
+ newpoints.push( points[ i + m ] );
179
+ }
180
+
181
+ // we might be able to interpolate a point below,
182
+ // this can give us a better y
183
+
184
+ if ( withlines && j > 0 && otherpoints[ j - otherps ] != null ) {
185
+ bottom = qy + ( otherpoints[ j - otherps + 1 ] - qy ) * ( px - qx ) / ( otherpoints[ j - otherps ] - qx );
186
+ }
187
+
188
+ //newpoints[l + 1] += bottom;
189
+
190
+ i += ps;
191
+ }
192
+
193
+ fromgap = false;
194
+
195
+ if ( l !== newpoints.length && withbottom ) {
196
+ newpoints[ l + 2 ] = bottom;
197
+ }
198
+ }
199
+
200
+ // maintain the line steps invariant
201
+
202
+ if ( withsteps && l !== newpoints.length && l > 0 &&
203
+ newpoints[ l ] !== null &&
204
+ newpoints[ l ] !== newpoints[ l - ps ] &&
205
+ newpoints[ l + 1 ] !== newpoints[ l - ps + 1 ] ) {
206
+ for (m = 0; m < ps; ++m) {
207
+ newpoints[ l + ps + m ] = newpoints[ l + m ];
208
+ }
209
+ newpoints[ l + 1 ] = newpoints[ l - ps + 1 ];
210
+ }
211
+ }
212
+
213
+ datapoints.points = newpoints;
214
+ }
215
+
216
+ plot.hooks.processDatapoints.push( computeFillBottoms );
217
+ }
218
+
219
+ $.plot.plugins.push({
220
+ init: init,
221
+ options: options,
222
+ name: "fillbetween",
223
+ version: "1.0"
224
+ });
225
+
226
+ })(jQuery);
@@ -0,0 +1,241 @@
1
+ /* Flot plugin for plotting images.
2
+
3
+ Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+ Licensed under the MIT license.
5
+
6
+ The data syntax is [ [ image, x1, y1, x2, y2 ], ... ] where (x1, y1) and
7
+ (x2, y2) are where you intend the two opposite corners of the image to end up
8
+ in the plot. Image must be a fully loaded Javascript image (you can make one
9
+ with new Image()). If the image is not complete, it's skipped when plotting.
10
+
11
+ There are two helpers included for retrieving images. The easiest work the way
12
+ that you put in URLs instead of images in the data, like this:
13
+
14
+ [ "myimage.png", 0, 0, 10, 10 ]
15
+
16
+ Then call $.plot.image.loadData( data, options, callback ) where data and
17
+ options are the same as you pass in to $.plot. This loads the images, replaces
18
+ the URLs in the data with the corresponding images and calls "callback" when
19
+ all images are loaded (or failed loading). In the callback, you can then call
20
+ $.plot with the data set. See the included example.
21
+
22
+ A more low-level helper, $.plot.image.load(urls, callback) is also included.
23
+ Given a list of URLs, it calls callback with an object mapping from URL to
24
+ Image object when all images are loaded or have failed loading.
25
+
26
+ The plugin supports these options:
27
+
28
+ series: {
29
+ images: {
30
+ show: boolean
31
+ anchor: "corner" or "center"
32
+ alpha: [ 0, 1 ]
33
+ }
34
+ }
35
+
36
+ They can be specified for a specific series:
37
+
38
+ $.plot( $("#placeholder"), [{
39
+ data: [ ... ],
40
+ images: { ... }
41
+ ])
42
+
43
+ Note that because the data format is different from usual data points, you
44
+ can't use images with anything else in a specific data series.
45
+
46
+ Setting "anchor" to "center" causes the pixels in the image to be anchored at
47
+ the corner pixel centers inside of at the pixel corners, effectively letting
48
+ half a pixel stick out to each side in the plot.
49
+
50
+ A possible future direction could be support for tiling for large images (like
51
+ Google Maps).
52
+
53
+ */
54
+
55
+ (function ($) {
56
+ var options = {
57
+ series: {
58
+ images: {
59
+ show: false,
60
+ alpha: 1,
61
+ anchor: "corner" // or "center"
62
+ }
63
+ }
64
+ };
65
+
66
+ $.plot.image = {};
67
+
68
+ $.plot.image.loadDataImages = function (series, options, callback) {
69
+ var urls = [], points = [];
70
+
71
+ var defaultShow = options.series.images.show;
72
+
73
+ $.each(series, function (i, s) {
74
+ if (!(defaultShow || s.images.show))
75
+ return;
76
+
77
+ if (s.data)
78
+ s = s.data;
79
+
80
+ $.each(s, function (i, p) {
81
+ if (typeof p[0] == "string") {
82
+ urls.push(p[0]);
83
+ points.push(p);
84
+ }
85
+ });
86
+ });
87
+
88
+ $.plot.image.load(urls, function (loadedImages) {
89
+ $.each(points, function (i, p) {
90
+ var url = p[0];
91
+ if (loadedImages[url])
92
+ p[0] = loadedImages[url];
93
+ });
94
+
95
+ callback();
96
+ });
97
+ }
98
+
99
+ $.plot.image.load = function (urls, callback) {
100
+ var missing = urls.length, loaded = {};
101
+ if (missing == 0)
102
+ callback({});
103
+
104
+ $.each(urls, function (i, url) {
105
+ var handler = function () {
106
+ --missing;
107
+
108
+ loaded[url] = this;
109
+
110
+ if (missing == 0)
111
+ callback(loaded);
112
+ };
113
+
114
+ $('<img />').load(handler).error(handler).attr('src', url);
115
+ });
116
+ };
117
+
118
+ function drawSeries(plot, ctx, series) {
119
+ var plotOffset = plot.getPlotOffset();
120
+
121
+ if (!series.images || !series.images.show)
122
+ return;
123
+
124
+ var points = series.datapoints.points,
125
+ ps = series.datapoints.pointsize;
126
+
127
+ for (var i = 0; i < points.length; i += ps) {
128
+ var img = points[i],
129
+ x1 = points[i + 1], y1 = points[i + 2],
130
+ x2 = points[i + 3], y2 = points[i + 4],
131
+ xaxis = series.xaxis, yaxis = series.yaxis,
132
+ tmp;
133
+
134
+ // actually we should check img.complete, but it
135
+ // appears to be a somewhat unreliable indicator in
136
+ // IE6 (false even after load event)
137
+ if (!img || img.width <= 0 || img.height <= 0)
138
+ continue;
139
+
140
+ if (x1 > x2) {
141
+ tmp = x2;
142
+ x2 = x1;
143
+ x1 = tmp;
144
+ }
145
+ if (y1 > y2) {
146
+ tmp = y2;
147
+ y2 = y1;
148
+ y1 = tmp;
149
+ }
150
+
151
+ // if the anchor is at the center of the pixel, expand the
152
+ // image by 1/2 pixel in each direction
153
+ if (series.images.anchor == "center") {
154
+ tmp = 0.5 * (x2-x1) / (img.width - 1);
155
+ x1 -= tmp;
156
+ x2 += tmp;
157
+ tmp = 0.5 * (y2-y1) / (img.height - 1);
158
+ y1 -= tmp;
159
+ y2 += tmp;
160
+ }
161
+
162
+ // clip
163
+ if (x1 == x2 || y1 == y2 ||
164
+ x1 >= xaxis.max || x2 <= xaxis.min ||
165
+ y1 >= yaxis.max || y2 <= yaxis.min)
166
+ continue;
167
+
168
+ var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height;
169
+ if (x1 < xaxis.min) {
170
+ sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1);
171
+ x1 = xaxis.min;
172
+ }
173
+
174
+ if (x2 > xaxis.max) {
175
+ sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1);
176
+ x2 = xaxis.max;
177
+ }
178
+
179
+ if (y1 < yaxis.min) {
180
+ sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1);
181
+ y1 = yaxis.min;
182
+ }
183
+
184
+ if (y2 > yaxis.max) {
185
+ sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1);
186
+ y2 = yaxis.max;
187
+ }
188
+
189
+ x1 = xaxis.p2c(x1);
190
+ x2 = xaxis.p2c(x2);
191
+ y1 = yaxis.p2c(y1);
192
+ y2 = yaxis.p2c(y2);
193
+
194
+ // the transformation may have swapped us
195
+ if (x1 > x2) {
196
+ tmp = x2;
197
+ x2 = x1;
198
+ x1 = tmp;
199
+ }
200
+ if (y1 > y2) {
201
+ tmp = y2;
202
+ y2 = y1;
203
+ y1 = tmp;
204
+ }
205
+
206
+ tmp = ctx.globalAlpha;
207
+ ctx.globalAlpha *= series.images.alpha;
208
+ ctx.drawImage(img,
209
+ sx1, sy1, sx2 - sx1, sy2 - sy1,
210
+ x1 + plotOffset.left, y1 + plotOffset.top,
211
+ x2 - x1, y2 - y1);
212
+ ctx.globalAlpha = tmp;
213
+ }
214
+ }
215
+
216
+ function processRawData(plot, series, data, datapoints) {
217
+ if (!series.images.show)
218
+ return;
219
+
220
+ // format is Image, x1, y1, x2, y2 (opposite corners)
221
+ datapoints.format = [
222
+ { required: true },
223
+ { x: true, number: true, required: true },
224
+ { y: true, number: true, required: true },
225
+ { x: true, number: true, required: true },
226
+ { y: true, number: true, required: true }
227
+ ];
228
+ }
229
+
230
+ function init(plot) {
231
+ plot.hooks.processRawData.push(processRawData);
232
+ plot.hooks.drawSeries.push(drawSeries);
233
+ }
234
+
235
+ $.plot.plugins.push({
236
+ init: init,
237
+ options: options,
238
+ name: 'image',
239
+ version: '1.1'
240
+ });
241
+ })(jQuery);