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,190 @@
1
+ /* Flot plugin for plotting textual data or categories.
2
+
3
+ Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+ Licensed under the MIT license.
5
+
6
+ Consider a dataset like [["February", 34], ["March", 20], ...]. This plugin
7
+ allows you to plot such a dataset directly.
8
+
9
+ To enable it, you must specify mode: "categories" on the axis with the textual
10
+ labels, e.g.
11
+
12
+ $.plot("#placeholder", data, { xaxis: { mode: "categories" } });
13
+
14
+ By default, the labels are ordered as they are met in the data series. If you
15
+ need a different ordering, you can specify "categories" on the axis options
16
+ and list the categories there:
17
+
18
+ xaxis: {
19
+ mode: "categories",
20
+ categories: ["February", "March", "April"]
21
+ }
22
+
23
+ If you need to customize the distances between the categories, you can specify
24
+ "categories" as an object mapping labels to values
25
+
26
+ xaxis: {
27
+ mode: "categories",
28
+ categories: { "February": 1, "March": 3, "April": 4 }
29
+ }
30
+
31
+ If you don't specify all categories, the remaining categories will be numbered
32
+ from the max value plus 1 (with a spacing of 1 between each).
33
+
34
+ Internally, the plugin works by transforming the input data through an auto-
35
+ generated mapping where the first category becomes 0, the second 1, etc.
36
+ Hence, a point like ["February", 34] becomes [0, 34] internally in Flot (this
37
+ is visible in hover and click events that return numbers rather than the
38
+ category labels). The plugin also overrides the tick generator to spit out the
39
+ categories as ticks instead of the values.
40
+
41
+ If you need to map a value back to its label, the mapping is always accessible
42
+ as "categories" on the axis object, e.g. plot.getAxes().xaxis.categories.
43
+
44
+ */
45
+
46
+ (function ($) {
47
+ var options = {
48
+ xaxis: {
49
+ categories: null
50
+ },
51
+ yaxis: {
52
+ categories: null
53
+ }
54
+ };
55
+
56
+ function processRawData(plot, series, data, datapoints) {
57
+ // if categories are enabled, we need to disable
58
+ // auto-transformation to numbers so the strings are intact
59
+ // for later processing
60
+
61
+ var xCategories = series.xaxis.options.mode == "categories",
62
+ yCategories = series.yaxis.options.mode == "categories";
63
+
64
+ if (!(xCategories || yCategories))
65
+ return;
66
+
67
+ var format = datapoints.format;
68
+
69
+ if (!format) {
70
+ // FIXME: auto-detection should really not be defined here
71
+ var s = series;
72
+ format = [];
73
+ format.push({ x: true, number: true, required: true });
74
+ format.push({ y: true, number: true, required: true });
75
+
76
+ if (s.bars.show || (s.lines.show && s.lines.fill)) {
77
+ var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));
78
+ format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });
79
+ if (s.bars.horizontal) {
80
+ delete format[format.length - 1].y;
81
+ format[format.length - 1].x = true;
82
+ }
83
+ }
84
+
85
+ datapoints.format = format;
86
+ }
87
+
88
+ for (var m = 0; m < format.length; ++m) {
89
+ if (format[m].x && xCategories)
90
+ format[m].number = false;
91
+
92
+ if (format[m].y && yCategories)
93
+ format[m].number = false;
94
+ }
95
+ }
96
+
97
+ function getNextIndex(categories) {
98
+ var index = -1;
99
+
100
+ for (var v in categories)
101
+ if (categories[v] > index)
102
+ index = categories[v];
103
+
104
+ return index + 1;
105
+ }
106
+
107
+ function categoriesTickGenerator(axis) {
108
+ var res = [];
109
+ for (var label in axis.categories) {
110
+ var v = axis.categories[label];
111
+ if (v >= axis.min && v <= axis.max)
112
+ res.push([v, label]);
113
+ }
114
+
115
+ res.sort(function (a, b) { return a[0] - b[0]; });
116
+
117
+ return res;
118
+ }
119
+
120
+ function setupCategoriesForAxis(series, axis, datapoints) {
121
+ if (series[axis].options.mode != "categories")
122
+ return;
123
+
124
+ if (!series[axis].categories) {
125
+ // parse options
126
+ var c = {}, o = series[axis].options.categories || {};
127
+ if ($.isArray(o)) {
128
+ for (var i = 0; i < o.length; ++i)
129
+ c[o[i]] = i;
130
+ }
131
+ else {
132
+ for (var v in o)
133
+ c[v] = o[v];
134
+ }
135
+
136
+ series[axis].categories = c;
137
+ }
138
+
139
+ // fix ticks
140
+ if (!series[axis].options.ticks)
141
+ series[axis].options.ticks = categoriesTickGenerator;
142
+
143
+ transformPointsOnAxis(datapoints, axis, series[axis].categories);
144
+ }
145
+
146
+ function transformPointsOnAxis(datapoints, axis, categories) {
147
+ // go through the points, transforming them
148
+ var points = datapoints.points,
149
+ ps = datapoints.pointsize,
150
+ format = datapoints.format,
151
+ formatColumn = axis.charAt(0),
152
+ index = getNextIndex(categories);
153
+
154
+ for (var i = 0; i < points.length; i += ps) {
155
+ if (points[i] == null)
156
+ continue;
157
+
158
+ for (var m = 0; m < ps; ++m) {
159
+ var val = points[i + m];
160
+
161
+ if (val == null || !format[m][formatColumn])
162
+ continue;
163
+
164
+ if (!(val in categories)) {
165
+ categories[val] = index;
166
+ ++index;
167
+ }
168
+
169
+ points[i + m] = categories[val];
170
+ }
171
+ }
172
+ }
173
+
174
+ function processDatapoints(plot, series, datapoints) {
175
+ setupCategoriesForAxis(series, "xaxis", datapoints);
176
+ setupCategoriesForAxis(series, "yaxis", datapoints);
177
+ }
178
+
179
+ function init(plot) {
180
+ plot.hooks.processRawData.push(processRawData);
181
+ plot.hooks.processDatapoints.push(processDatapoints);
182
+ }
183
+
184
+ $.plot.plugins.push({
185
+ init: init,
186
+ options: options,
187
+ name: 'categories',
188
+ version: '1.0'
189
+ });
190
+ })(jQuery);
@@ -0,0 +1,176 @@
1
+ /* Flot plugin for showing crosshairs when the mouse hovers over the plot.
2
+
3
+ Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+ Licensed under the MIT license.
5
+
6
+ The plugin supports these options:
7
+
8
+ crosshair: {
9
+ mode: null or "x" or "y" or "xy"
10
+ color: color
11
+ lineWidth: number
12
+ }
13
+
14
+ Set the mode to one of "x", "y" or "xy". The "x" mode enables a vertical
15
+ crosshair that lets you trace the values on the x axis, "y" enables a
16
+ horizontal crosshair and "xy" enables them both. "color" is the color of the
17
+ crosshair (default is "rgba(170, 0, 0, 0.80)"), "lineWidth" is the width of
18
+ the drawn lines (default is 1).
19
+
20
+ The plugin also adds four public methods:
21
+
22
+ - setCrosshair( pos )
23
+
24
+ Set the position of the crosshair. Note that this is cleared if the user
25
+ moves the mouse. "pos" is in coordinates of the plot and should be on the
26
+ form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple
27
+ axes), which is coincidentally the same format as what you get from a
28
+ "plothover" event. If "pos" is null, the crosshair is cleared.
29
+
30
+ - clearCrosshair()
31
+
32
+ Clear the crosshair.
33
+
34
+ - lockCrosshair(pos)
35
+
36
+ Cause the crosshair to lock to the current location, no longer updating if
37
+ the user moves the mouse. Optionally supply a position (passed on to
38
+ setCrosshair()) to move it to.
39
+
40
+ Example usage:
41
+
42
+ var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } };
43
+ $("#graph").bind( "plothover", function ( evt, position, item ) {
44
+ if ( item ) {
45
+ // Lock the crosshair to the data point being hovered
46
+ myFlot.lockCrosshair({
47
+ x: item.datapoint[ 0 ],
48
+ y: item.datapoint[ 1 ]
49
+ });
50
+ } else {
51
+ // Return normal crosshair operation
52
+ myFlot.unlockCrosshair();
53
+ }
54
+ });
55
+
56
+ - unlockCrosshair()
57
+
58
+ Free the crosshair to move again after locking it.
59
+ */
60
+
61
+ (function ($) {
62
+ var options = {
63
+ crosshair: {
64
+ mode: null, // one of null, "x", "y" or "xy",
65
+ color: "rgba(170, 0, 0, 0.80)",
66
+ lineWidth: 1
67
+ }
68
+ };
69
+
70
+ function init(plot) {
71
+ // position of crosshair in pixels
72
+ var crosshair = { x: -1, y: -1, locked: false };
73
+
74
+ plot.setCrosshair = function setCrosshair(pos) {
75
+ if (!pos)
76
+ crosshair.x = -1;
77
+ else {
78
+ var o = plot.p2c(pos);
79
+ crosshair.x = Math.max(0, Math.min(o.left, plot.width()));
80
+ crosshair.y = Math.max(0, Math.min(o.top, plot.height()));
81
+ }
82
+
83
+ plot.triggerRedrawOverlay();
84
+ };
85
+
86
+ plot.clearCrosshair = plot.setCrosshair; // passes null for pos
87
+
88
+ plot.lockCrosshair = function lockCrosshair(pos) {
89
+ if (pos)
90
+ plot.setCrosshair(pos);
91
+ crosshair.locked = true;
92
+ };
93
+
94
+ plot.unlockCrosshair = function unlockCrosshair() {
95
+ crosshair.locked = false;
96
+ };
97
+
98
+ function onMouseOut(e) {
99
+ if (crosshair.locked)
100
+ return;
101
+
102
+ if (crosshair.x != -1) {
103
+ crosshair.x = -1;
104
+ plot.triggerRedrawOverlay();
105
+ }
106
+ }
107
+
108
+ function onMouseMove(e) {
109
+ if (crosshair.locked)
110
+ return;
111
+
112
+ if (plot.getSelection && plot.getSelection()) {
113
+ crosshair.x = -1; // hide the crosshair while selecting
114
+ return;
115
+ }
116
+
117
+ var offset = plot.offset();
118
+ crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width()));
119
+ crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height()));
120
+ plot.triggerRedrawOverlay();
121
+ }
122
+
123
+ plot.hooks.bindEvents.push(function (plot, eventHolder) {
124
+ if (!plot.getOptions().crosshair.mode)
125
+ return;
126
+
127
+ eventHolder.mouseout(onMouseOut);
128
+ eventHolder.mousemove(onMouseMove);
129
+ });
130
+
131
+ plot.hooks.drawOverlay.push(function (plot, ctx) {
132
+ var c = plot.getOptions().crosshair;
133
+ if (!c.mode)
134
+ return;
135
+
136
+ var plotOffset = plot.getPlotOffset();
137
+
138
+ ctx.save();
139
+ ctx.translate(plotOffset.left, plotOffset.top);
140
+
141
+ if (crosshair.x != -1) {
142
+ var adj = plot.getOptions().crosshair.lineWidth % 2 ? 0.5 : 0;
143
+
144
+ ctx.strokeStyle = c.color;
145
+ ctx.lineWidth = c.lineWidth;
146
+ ctx.lineJoin = "round";
147
+
148
+ ctx.beginPath();
149
+ if (c.mode.indexOf("x") != -1) {
150
+ var drawX = Math.floor(crosshair.x) + adj;
151
+ ctx.moveTo(drawX, 0);
152
+ ctx.lineTo(drawX, plot.height());
153
+ }
154
+ if (c.mode.indexOf("y") != -1) {
155
+ var drawY = Math.floor(crosshair.y) + adj;
156
+ ctx.moveTo(0, drawY);
157
+ ctx.lineTo(plot.width(), drawY);
158
+ }
159
+ ctx.stroke();
160
+ }
161
+ ctx.restore();
162
+ });
163
+
164
+ plot.hooks.shutdown.push(function (plot, eventHolder) {
165
+ eventHolder.unbind("mouseout", onMouseOut);
166
+ eventHolder.unbind("mousemove", onMouseMove);
167
+ });
168
+ }
169
+
170
+ $.plot.plugins.push({
171
+ init: init,
172
+ options: options,
173
+ name: 'crosshair',
174
+ version: '1.0'
175
+ });
176
+ })(jQuery);
@@ -0,0 +1,353 @@
1
+ /* Flot plugin for plotting error bars.
2
+
3
+ Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+ Licensed under the MIT license.
5
+
6
+ Error bars are used to show standard deviation and other statistical
7
+ properties in a plot.
8
+
9
+ * Created by Rui Pereira - rui (dot) pereira (at) gmail (dot) com
10
+
11
+ This plugin allows you to plot error-bars over points. Set "errorbars" inside
12
+ the points series to the axis name over which there will be error values in
13
+ your data array (*even* if you do not intend to plot them later, by setting
14
+ "show: null" on xerr/yerr).
15
+
16
+ The plugin supports these options:
17
+
18
+ series: {
19
+ points: {
20
+ errorbars: "x" or "y" or "xy",
21
+ xerr: {
22
+ show: null/false or true,
23
+ asymmetric: null/false or true,
24
+ upperCap: null or "-" or function,
25
+ lowerCap: null or "-" or function,
26
+ color: null or color,
27
+ radius: null or number
28
+ },
29
+ yerr: { same options as xerr }
30
+ }
31
+ }
32
+
33
+ Each data point array is expected to be of the type:
34
+
35
+ "x" [ x, y, xerr ]
36
+ "y" [ x, y, yerr ]
37
+ "xy" [ x, y, xerr, yerr ]
38
+
39
+ Where xerr becomes xerr_lower,xerr_upper for the asymmetric error case, and
40
+ equivalently for yerr. Eg., a datapoint for the "xy" case with symmetric
41
+ error-bars on X and asymmetric on Y would be:
42
+
43
+ [ x, y, xerr, yerr_lower, yerr_upper ]
44
+
45
+ By default no end caps are drawn. Setting upperCap and/or lowerCap to "-" will
46
+ draw a small cap perpendicular to the error bar. They can also be set to a
47
+ user-defined drawing function, with (ctx, x, y, radius) as parameters, as eg.
48
+
49
+ function drawSemiCircle( ctx, x, y, radius ) {
50
+ ctx.beginPath();
51
+ ctx.arc( x, y, radius, 0, Math.PI, false );
52
+ ctx.moveTo( x - radius, y );
53
+ ctx.lineTo( x + radius, y );
54
+ ctx.stroke();
55
+ }
56
+
57
+ Color and radius both default to the same ones of the points series if not
58
+ set. The independent radius parameter on xerr/yerr is useful for the case when
59
+ we may want to add error-bars to a line, without showing the interconnecting
60
+ points (with radius: 0), and still showing end caps on the error-bars.
61
+ shadowSize and lineWidth are derived as well from the points series.
62
+
63
+ */
64
+
65
+ (function ($) {
66
+ var options = {
67
+ series: {
68
+ points: {
69
+ errorbars: null, //should be 'x', 'y' or 'xy'
70
+ xerr: { err: 'x', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null},
71
+ yerr: { err: 'y', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null}
72
+ }
73
+ }
74
+ };
75
+
76
+ function processRawData(plot, series, data, datapoints){
77
+ if (!series.points.errorbars)
78
+ return;
79
+
80
+ // x,y values
81
+ var format = [
82
+ { x: true, number: true, required: true },
83
+ { y: true, number: true, required: true }
84
+ ];
85
+
86
+ var errors = series.points.errorbars;
87
+ // error bars - first X then Y
88
+ if (errors == 'x' || errors == 'xy') {
89
+ // lower / upper error
90
+ if (series.points.xerr.asymmetric) {
91
+ format.push({ x: true, number: true, required: true });
92
+ format.push({ x: true, number: true, required: true });
93
+ } else
94
+ format.push({ x: true, number: true, required: true });
95
+ }
96
+ if (errors == 'y' || errors == 'xy') {
97
+ // lower / upper error
98
+ if (series.points.yerr.asymmetric) {
99
+ format.push({ y: true, number: true, required: true });
100
+ format.push({ y: true, number: true, required: true });
101
+ } else
102
+ format.push({ y: true, number: true, required: true });
103
+ }
104
+ datapoints.format = format;
105
+ }
106
+
107
+ function parseErrors(series, i){
108
+
109
+ var points = series.datapoints.points;
110
+
111
+ // read errors from points array
112
+ var exl = null,
113
+ exu = null,
114
+ eyl = null,
115
+ eyu = null;
116
+ var xerr = series.points.xerr,
117
+ yerr = series.points.yerr;
118
+
119
+ var eb = series.points.errorbars;
120
+ // error bars - first X
121
+ if (eb == 'x' || eb == 'xy') {
122
+ if (xerr.asymmetric) {
123
+ exl = points[i + 2];
124
+ exu = points[i + 3];
125
+ if (eb == 'xy')
126
+ if (yerr.asymmetric){
127
+ eyl = points[i + 4];
128
+ eyu = points[i + 5];
129
+ } else eyl = points[i + 4];
130
+ } else {
131
+ exl = points[i + 2];
132
+ if (eb == 'xy')
133
+ if (yerr.asymmetric) {
134
+ eyl = points[i + 3];
135
+ eyu = points[i + 4];
136
+ } else eyl = points[i + 3];
137
+ }
138
+ // only Y
139
+ } else if (eb == 'y')
140
+ if (yerr.asymmetric) {
141
+ eyl = points[i + 2];
142
+ eyu = points[i + 3];
143
+ } else eyl = points[i + 2];
144
+
145
+ // symmetric errors?
146
+ if (exu == null) exu = exl;
147
+ if (eyu == null) eyu = eyl;
148
+
149
+ var errRanges = [exl, exu, eyl, eyu];
150
+ // nullify if not showing
151
+ if (!xerr.show){
152
+ errRanges[0] = null;
153
+ errRanges[1] = null;
154
+ }
155
+ if (!yerr.show){
156
+ errRanges[2] = null;
157
+ errRanges[3] = null;
158
+ }
159
+ return errRanges;
160
+ }
161
+
162
+ function drawSeriesErrors(plot, ctx, s){
163
+
164
+ var points = s.datapoints.points,
165
+ ps = s.datapoints.pointsize,
166
+ ax = [s.xaxis, s.yaxis],
167
+ radius = s.points.radius,
168
+ err = [s.points.xerr, s.points.yerr];
169
+
170
+ //sanity check, in case some inverted axis hack is applied to flot
171
+ var invertX = false;
172
+ if (ax[0].p2c(ax[0].max) < ax[0].p2c(ax[0].min)) {
173
+ invertX = true;
174
+ var tmp = err[0].lowerCap;
175
+ err[0].lowerCap = err[0].upperCap;
176
+ err[0].upperCap = tmp;
177
+ }
178
+
179
+ var invertY = false;
180
+ if (ax[1].p2c(ax[1].min) < ax[1].p2c(ax[1].max)) {
181
+ invertY = true;
182
+ var tmp = err[1].lowerCap;
183
+ err[1].lowerCap = err[1].upperCap;
184
+ err[1].upperCap = tmp;
185
+ }
186
+
187
+ for (var i = 0; i < s.datapoints.points.length; i += ps) {
188
+
189
+ //parse
190
+ var errRanges = parseErrors(s, i);
191
+
192
+ //cycle xerr & yerr
193
+ for (var e = 0; e < err.length; e++){
194
+
195
+ var minmax = [ax[e].min, ax[e].max];
196
+
197
+ //draw this error?
198
+ if (errRanges[e * err.length]){
199
+
200
+ //data coordinates
201
+ var x = points[i],
202
+ y = points[i + 1];
203
+
204
+ //errorbar ranges
205
+ var upper = [x, y][e] + errRanges[e * err.length + 1],
206
+ lower = [x, y][e] - errRanges[e * err.length];
207
+
208
+ //points outside of the canvas
209
+ if (err[e].err == 'x')
210
+ if (y > ax[1].max || y < ax[1].min || upper < ax[0].min || lower > ax[0].max)
211
+ continue;
212
+ if (err[e].err == 'y')
213
+ if (x > ax[0].max || x < ax[0].min || upper < ax[1].min || lower > ax[1].max)
214
+ continue;
215
+
216
+ // prevent errorbars getting out of the canvas
217
+ var drawUpper = true,
218
+ drawLower = true;
219
+
220
+ if (upper > minmax[1]) {
221
+ drawUpper = false;
222
+ upper = minmax[1];
223
+ }
224
+ if (lower < minmax[0]) {
225
+ drawLower = false;
226
+ lower = minmax[0];
227
+ }
228
+
229
+ //sanity check, in case some inverted axis hack is applied to flot
230
+ if ((err[e].err == 'x' && invertX) || (err[e].err == 'y' && invertY)) {
231
+ //swap coordinates
232
+ var tmp = lower;
233
+ lower = upper;
234
+ upper = tmp;
235
+ tmp = drawLower;
236
+ drawLower = drawUpper;
237
+ drawUpper = tmp;
238
+ tmp = minmax[0];
239
+ minmax[0] = minmax[1];
240
+ minmax[1] = tmp;
241
+ }
242
+
243
+ // convert to pixels
244
+ x = ax[0].p2c(x),
245
+ y = ax[1].p2c(y),
246
+ upper = ax[e].p2c(upper);
247
+ lower = ax[e].p2c(lower);
248
+ minmax[0] = ax[e].p2c(minmax[0]);
249
+ minmax[1] = ax[e].p2c(minmax[1]);
250
+
251
+ //same style as points by default
252
+ var lw = err[e].lineWidth ? err[e].lineWidth : s.points.lineWidth,
253
+ sw = s.points.shadowSize != null ? s.points.shadowSize : s.shadowSize;
254
+
255
+ //shadow as for points
256
+ if (lw > 0 && sw > 0) {
257
+ var w = sw / 2;
258
+ ctx.lineWidth = w;
259
+ ctx.strokeStyle = "rgba(0,0,0,0.1)";
260
+ drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w + w/2, minmax);
261
+
262
+ ctx.strokeStyle = "rgba(0,0,0,0.2)";
263
+ drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w/2, minmax);
264
+ }
265
+
266
+ ctx.strokeStyle = err[e].color? err[e].color: s.color;
267
+ ctx.lineWidth = lw;
268
+ //draw it
269
+ drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, 0, minmax);
270
+ }
271
+ }
272
+ }
273
+ }
274
+
275
+ function drawError(ctx,err,x,y,upper,lower,drawUpper,drawLower,radius,offset,minmax){
276
+
277
+ //shadow offset
278
+ y += offset;
279
+ upper += offset;
280
+ lower += offset;
281
+
282
+ // error bar - avoid plotting over circles
283
+ if (err.err == 'x'){
284
+ if (upper > x + radius) drawPath(ctx, [[upper,y],[Math.max(x + radius,minmax[0]),y]]);
285
+ else drawUpper = false;
286
+ if (lower < x - radius) drawPath(ctx, [[Math.min(x - radius,minmax[1]),y],[lower,y]] );
287
+ else drawLower = false;
288
+ }
289
+ else {
290
+ if (upper < y - radius) drawPath(ctx, [[x,upper],[x,Math.min(y - radius,minmax[0])]] );
291
+ else drawUpper = false;
292
+ if (lower > y + radius) drawPath(ctx, [[x,Math.max(y + radius,minmax[1])],[x,lower]] );
293
+ else drawLower = false;
294
+ }
295
+
296
+ //internal radius value in errorbar, allows to plot radius 0 points and still keep proper sized caps
297
+ //this is a way to get errorbars on lines without visible connecting dots
298
+ radius = err.radius != null? err.radius: radius;
299
+
300
+ // upper cap
301
+ if (drawUpper) {
302
+ if (err.upperCap == '-'){
303
+ if (err.err=='x') drawPath(ctx, [[upper,y - radius],[upper,y + radius]] );
304
+ else drawPath(ctx, [[x - radius,upper],[x + radius,upper]] );
305
+ } else if ($.isFunction(err.upperCap)){
306
+ if (err.err=='x') err.upperCap(ctx, upper, y, radius);
307
+ else err.upperCap(ctx, x, upper, radius);
308
+ }
309
+ }
310
+ // lower cap
311
+ if (drawLower) {
312
+ if (err.lowerCap == '-'){
313
+ if (err.err=='x') drawPath(ctx, [[lower,y - radius],[lower,y + radius]] );
314
+ else drawPath(ctx, [[x - radius,lower],[x + radius,lower]] );
315
+ } else if ($.isFunction(err.lowerCap)){
316
+ if (err.err=='x') err.lowerCap(ctx, lower, y, radius);
317
+ else err.lowerCap(ctx, x, lower, radius);
318
+ }
319
+ }
320
+ }
321
+
322
+ function drawPath(ctx, pts){
323
+ ctx.beginPath();
324
+ ctx.moveTo(pts[0][0], pts[0][1]);
325
+ for (var p=1; p < pts.length; p++)
326
+ ctx.lineTo(pts[p][0], pts[p][1]);
327
+ ctx.stroke();
328
+ }
329
+
330
+ function draw(plot, ctx){
331
+ var plotOffset = plot.getPlotOffset();
332
+
333
+ ctx.save();
334
+ ctx.translate(plotOffset.left, plotOffset.top);
335
+ $.each(plot.getData(), function (i, s) {
336
+ if (s.points.errorbars && (s.points.xerr.show || s.points.yerr.show))
337
+ drawSeriesErrors(plot, ctx, s);
338
+ });
339
+ ctx.restore();
340
+ }
341
+
342
+ function init(plot) {
343
+ plot.hooks.processRawData.push(processRawData);
344
+ plot.hooks.draw.push(draw);
345
+ }
346
+
347
+ $.plot.plugins.push({
348
+ init: init,
349
+ options: options,
350
+ name: 'errorbars',
351
+ version: '1.0'
352
+ });
353
+ })(jQuery);