PluginProbe
Contact Forms by Cimatti / 1.3
Contact Forms by Cimatti v1.3
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.fillbetween.js

jquery.flot.fillbetween.js in Contact Forms by Cimatti 1.3, at flot/jquery.flot.fillbetween.js

184 lines 6.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*
2 Flot plugin for computing bottoms for filled line and bar charts.
3
4 The case: you've got two series that you want to fill the area
5 between. In Flot terms, you need to use one as the fill bottom of the
6 other. You can specify the bottom of each data point as the third
7 coordinate manually, or you can use this plugin to compute it for you.
8
9 In order to name the other series, you need to give it an id, like this
10
11 var dataset = [
12 { data: [ ... ], id: "foo" } , // use default bottom
13 { data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom
14 ];
15
16 $.plot($("#placeholder"), dataset, { line: { show: true, fill: true }});
17
18 As a convenience, if the id given is a number that doesn't appear as
19 an id in the series, it is interpreted as the index in the array
20 instead (so fillBetween: 0 can also mean the first series).
21
22 Internally, the plugin modifies the datapoints in each series. For
23 line series, extra data points might be inserted through
24 interpolation. Note that at points where the bottom line is not
25 defined (due to a null point or start/end of line), the current line
26 will show a gap too. The algorithm comes from the jquery.flot.stack.js
27 plugin, possibly some code could be shared.
28 */
29
30 (function ($) {
31 var options = {
32 series: { fillBetween: null } // or number
33 };
34
35 function init(plot) {
36 function findBottomSeries(s, allseries) {
37 var i;
38 for (i = 0; i < allseries.length; ++i) {
39 if (allseries[i].id == s.fillBetween)
40 return allseries[i];
41 }
42
43 if (typeof s.fillBetween == "number") {
44 i = s.fillBetween;
45
46 if (i < 0 || i >= allseries.length)
47 return null;
48
49 return allseries[i];
50 }
51
52 return null;
53 }
54
55 function computeFillBottoms(plot, s, datapoints) {
56 if (s.fillBetween == null)
57 return;
58
59 var other = findBottomSeries(s, plot.getData());
60 if (!other)
61 return;
62
63 var ps = datapoints.pointsize,
64 points = datapoints.points,
65 otherps = other.datapoints.pointsize,
66 otherpoints = other.datapoints.points,
67 newpoints = [],
68 px, py, intery, qx, qy, bottom,
69 withlines = s.lines.show,
70 withbottom = ps > 2 && datapoints.format[2].y,
71 withsteps = withlines && s.lines.steps,
72 fromgap = true,
73 i = 0, j = 0, l;
74
75 while (true) {
76 if (i >= points.length)
77 break;
78
79 l = newpoints.length;
80
81 if (points[i] == null) {
82 // copy gaps
83 for (m = 0; m < ps; ++m)
84 newpoints.push(points[i + m]);
85 i += ps;
86 }
87 else if (j >= otherpoints.length) {
88 // for lines, we can't use the rest of the points
89 if (!withlines) {
90 for (m = 0; m < ps; ++m)
91 newpoints.push(points[i + m]);
92 }
93 i += ps;
94 }
95 else if (otherpoints[j] == null) {
96 // oops, got a gap
97 for (m = 0; m < ps; ++m)
98 newpoints.push(null);
99 fromgap = true;
100 j += otherps;
101 }
102 else {
103 // cases where we actually got two points
104 px = points[i];
105 py = points[i + 1];
106 qx = otherpoints[j];
107 qy = otherpoints[j + 1];
108 bottom = 0;
109
110 if (px == qx) {
111 for (m = 0; m < ps; ++m)
112 newpoints.push(points[i + m]);
113
114 //newpoints[l + 1] += qy;
115 bottom = qy;
116
117 i += ps;
118 j += otherps;
119 }
120 else if (px > qx) {
121 // we got past point below, might need to
122 // insert interpolated extra point
123 if (withlines && i > 0 && points[i - ps] != null) {
124 intery = py + (points[i - ps + 1] - py) * (qx - px) / (points[i - ps] - px);
125 newpoints.push(qx);
126 newpoints.push(intery)
127 for (m = 2; m < ps; ++m)
128 newpoints.push(points[i + m]);
129 bottom = qy;
130 }
131
132 j += otherps;
133 }
134 else { // px < qx
135 if (fromgap && withlines) {
136 // if we come from a gap, we just skip this point
137 i += ps;
138 continue;
139 }
140
141 for (m = 0; m < ps; ++m)
142 newpoints.push(points[i + m]);
143
144 // we might be able to interpolate a point below,
145 // this can give us a better y
146 if (withlines && j > 0 && otherpoints[j - otherps] != null)
147 bottom = qy + (otherpoints[j - otherps + 1] - qy) * (px - qx) / (otherpoints[j - otherps] - qx);
148
149 //newpoints[l + 1] += bottom;
150
151 i += ps;
152 }
153
154 fromgap = false;
155
156 if (l != newpoints.length && withbottom)
157 newpoints[l + 2] = bottom;
158 }
159
160 // maintain the line steps invariant
161 if (withsteps && l != newpoints.length && l > 0
162 && newpoints[l] != null
163 && newpoints[l] != newpoints[l - ps]
164 && newpoints[l + 1] != newpoints[l - ps + 1]) {
165 for (m = 0; m < ps; ++m)
166 newpoints[l + ps + m] = newpoints[l + m];
167 newpoints[l + 1] = newpoints[l - ps + 1];
168 }
169 }
170
171 datapoints.points = newpoints;
172 }
173
174 plot.hooks.processDatapoints.push(computeFillBottoms);
175 }
176
177 $.plot.plugins.push({
178 init: init,
179 options: options,
180 name: 'fillbetween',
181 version: '1.0'
182 });
183 })(jQuery);
184