highcharts-rails 3.0.3 → 3.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- checksums.yaml.gz.asc +13 -13
- data.tar.gz.asc +13 -13
- data/.gitignore +1 -0
- data/CHANGELOG.markdown +4 -0
- data/README.markdown +1 -0
- data/Rakefile +1 -29
- data/app/assets/javascripts/highcharts.js +280 -16676
- data/app/assets/javascripts/highcharts/adapters/mootools.js +13 -313
- data/app/assets/javascripts/highcharts/adapters/prototype.js +15 -316
- data/app/assets/javascripts/highcharts/adapters/standalone.js +17 -0
- data/app/assets/javascripts/highcharts/highcharts-more.js +50 -2426
- data/app/assets/javascripts/highcharts/modules/annotations.js +7 -401
- data/app/assets/javascripts/highcharts/modules/canvas-tools.js +133 -3113
- data/app/assets/javascripts/highcharts/modules/data.js +16 -581
- data/app/assets/javascripts/highcharts/modules/exporting.js +22 -704
- data/app/assets/javascripts/highcharts/modules/funnel.js +12 -284
- data/app/assets/javascripts/highcharts/modules/heatmap.js +1 -57
- data/app/assets/javascripts/highcharts/modules/map.js +21 -576
- data/highcharts-rails.gemspec +0 -1
- data/lib/highcharts/version.rb +1 -1
- metadata +4 -4
- metadata.gz.asc +13 -13
@@ -1,284 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
(function (
|
12
|
-
|
13
|
-
'use strict';
|
14
|
-
|
15
|
-
// create shortcuts
|
16
|
-
var defaultOptions = Highcharts.getOptions(),
|
17
|
-
defaultPlotOptions = defaultOptions.plotOptions,
|
18
|
-
seriesTypes = Highcharts.seriesTypes,
|
19
|
-
merge = Highcharts.merge,
|
20
|
-
noop = function () {},
|
21
|
-
each = Highcharts.each;
|
22
|
-
|
23
|
-
// set default options
|
24
|
-
defaultPlotOptions.funnel = merge(defaultPlotOptions.pie, {
|
25
|
-
center: ['50%', '50%'],
|
26
|
-
width: '90%',
|
27
|
-
neckWidth: '30%',
|
28
|
-
height: '100%',
|
29
|
-
neckHeight: '25%',
|
30
|
-
|
31
|
-
dataLabels: {
|
32
|
-
//position: 'right',
|
33
|
-
connectorWidth: 1,
|
34
|
-
connectorColor: '#606060'
|
35
|
-
},
|
36
|
-
size: true, // to avoid adapting to data label size in Pie.drawDataLabels
|
37
|
-
states: {
|
38
|
-
select: {
|
39
|
-
color: '#C0C0C0',
|
40
|
-
borderColor: '#000000',
|
41
|
-
shadow: false
|
42
|
-
}
|
43
|
-
}
|
44
|
-
});
|
45
|
-
|
46
|
-
|
47
|
-
seriesTypes.funnel = Highcharts.extendClass(seriesTypes.pie, {
|
48
|
-
|
49
|
-
type: 'funnel',
|
50
|
-
animate: noop,
|
51
|
-
|
52
|
-
/**
|
53
|
-
* Overrides the pie translate method
|
54
|
-
*/
|
55
|
-
translate: function () {
|
56
|
-
|
57
|
-
var
|
58
|
-
// Get positions - either an integer or a percentage string must be given
|
59
|
-
getLength = function (length, relativeTo) {
|
60
|
-
return (/%$/).test(length) ?
|
61
|
-
relativeTo * parseInt(length, 10) / 100 :
|
62
|
-
parseInt(length, 10);
|
63
|
-
},
|
64
|
-
|
65
|
-
sum = 0,
|
66
|
-
series = this,
|
67
|
-
chart = series.chart,
|
68
|
-
plotWidth = chart.plotWidth,
|
69
|
-
plotHeight = chart.plotHeight,
|
70
|
-
cumulative = 0, // start at top
|
71
|
-
options = series.options,
|
72
|
-
center = options.center,
|
73
|
-
centerX = getLength(center[0], plotWidth),
|
74
|
-
centerY = getLength(center[0], plotHeight),
|
75
|
-
width = getLength(options.width, plotWidth),
|
76
|
-
tempWidth,
|
77
|
-
getWidthAt,
|
78
|
-
height = getLength(options.height, plotHeight),
|
79
|
-
neckWidth = getLength(options.neckWidth, plotWidth),
|
80
|
-
neckHeight = getLength(options.neckHeight, plotHeight),
|
81
|
-
neckY = height - neckHeight,
|
82
|
-
data = series.data,
|
83
|
-
path,
|
84
|
-
fraction,
|
85
|
-
half = options.dataLabels.position === 'left' ? 1 : 0,
|
86
|
-
|
87
|
-
x1,
|
88
|
-
y1,
|
89
|
-
x2,
|
90
|
-
x3,
|
91
|
-
y3,
|
92
|
-
x4,
|
93
|
-
y5;
|
94
|
-
|
95
|
-
// Return the width at a specific y coordinate
|
96
|
-
series.getWidthAt = getWidthAt = function (y) {
|
97
|
-
return y > height - neckHeight || height === neckHeight ?
|
98
|
-
neckWidth :
|
99
|
-
neckWidth + (width - neckWidth) * ((height - neckHeight - y) / (height - neckHeight));
|
100
|
-
};
|
101
|
-
series.getX = function (y, half) {
|
102
|
-
return centerX + (half ? -1 : 1) * ((getWidthAt(y) / 2) + options.dataLabels.distance);
|
103
|
-
};
|
104
|
-
|
105
|
-
// Expose
|
106
|
-
series.center = [centerX, centerY, height];
|
107
|
-
series.centerX = centerX;
|
108
|
-
|
109
|
-
/*
|
110
|
-
* Individual point coordinate naming:
|
111
|
-
*
|
112
|
-
* x1,y1 _________________ x2,y1
|
113
|
-
* \ /
|
114
|
-
* \ /
|
115
|
-
* \ /
|
116
|
-
* \ /
|
117
|
-
* \ /
|
118
|
-
* x3,y3 _________ x4,y3
|
119
|
-
*
|
120
|
-
* Additional for the base of the neck:
|
121
|
-
*
|
122
|
-
* | |
|
123
|
-
* | |
|
124
|
-
* | |
|
125
|
-
* x3,y5 _________ x4,y5
|
126
|
-
*/
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
// get the total sum
|
132
|
-
each(data, function (point) {
|
133
|
-
sum += point.y;
|
134
|
-
});
|
135
|
-
|
136
|
-
each(data, function (point) {
|
137
|
-
// set start and end positions
|
138
|
-
y5 = null;
|
139
|
-
fraction = sum ? point.y / sum : 0;
|
140
|
-
y1 = centerY - height / 2 + cumulative * height;
|
141
|
-
y3 = y1 + fraction * height;
|
142
|
-
//tempWidth = neckWidth + (width - neckWidth) * ((height - neckHeight - y1) / (height - neckHeight));
|
143
|
-
tempWidth = getWidthAt(y1);
|
144
|
-
x1 = centerX - tempWidth / 2;
|
145
|
-
x2 = x1 + tempWidth;
|
146
|
-
tempWidth = getWidthAt(y3);
|
147
|
-
x3 = centerX - tempWidth / 2;
|
148
|
-
x4 = x3 + tempWidth;
|
149
|
-
|
150
|
-
// the entire point is within the neck
|
151
|
-
if (y1 > neckY) {
|
152
|
-
x1 = x3 = centerX - neckWidth / 2;
|
153
|
-
x2 = x4 = centerX + neckWidth / 2;
|
154
|
-
|
155
|
-
// the base of the neck
|
156
|
-
} else if (y3 > neckY) {
|
157
|
-
y5 = y3;
|
158
|
-
|
159
|
-
tempWidth = getWidthAt(neckY);
|
160
|
-
x3 = centerX - tempWidth / 2;
|
161
|
-
x4 = x3 + tempWidth;
|
162
|
-
|
163
|
-
y3 = neckY;
|
164
|
-
}
|
165
|
-
|
166
|
-
// save the path
|
167
|
-
path = [
|
168
|
-
'M',
|
169
|
-
x1, y1,
|
170
|
-
'L',
|
171
|
-
x2, y1,
|
172
|
-
x4, y3
|
173
|
-
];
|
174
|
-
if (y5) {
|
175
|
-
path.push(x4, y5, x3, y5);
|
176
|
-
}
|
177
|
-
path.push(x3, y3, 'Z');
|
178
|
-
|
179
|
-
// prepare for using shared dr
|
180
|
-
point.shapeType = 'path';
|
181
|
-
point.shapeArgs = { d: path };
|
182
|
-
|
183
|
-
|
184
|
-
// for tooltips and data labels
|
185
|
-
point.percentage = fraction * 100;
|
186
|
-
point.plotX = centerX;
|
187
|
-
point.plotY = (y1 + (y5 || y3)) / 2;
|
188
|
-
|
189
|
-
// Placement of tooltips and data labels
|
190
|
-
point.tooltipPos = [
|
191
|
-
centerX,
|
192
|
-
point.plotY
|
193
|
-
];
|
194
|
-
|
195
|
-
// Slice is a noop on funnel points
|
196
|
-
point.slice = noop;
|
197
|
-
|
198
|
-
// Mimicking pie data label placement logic
|
199
|
-
point.half = half;
|
200
|
-
|
201
|
-
cumulative += fraction;
|
202
|
-
});
|
203
|
-
|
204
|
-
|
205
|
-
series.setTooltipPoints();
|
206
|
-
},
|
207
|
-
/**
|
208
|
-
* Draw a single point (wedge)
|
209
|
-
* @param {Object} point The point object
|
210
|
-
* @param {Object} color The color of the point
|
211
|
-
* @param {Number} brightness The brightness relative to the color
|
212
|
-
*/
|
213
|
-
drawPoints: function () {
|
214
|
-
var series = this,
|
215
|
-
options = series.options,
|
216
|
-
chart = series.chart,
|
217
|
-
renderer = chart.renderer;
|
218
|
-
|
219
|
-
each(series.data, function (point) {
|
220
|
-
|
221
|
-
var graphic = point.graphic,
|
222
|
-
shapeArgs = point.shapeArgs;
|
223
|
-
|
224
|
-
if (!graphic) { // Create the shapes
|
225
|
-
point.graphic = renderer.path(shapeArgs).
|
226
|
-
attr({
|
227
|
-
fill: point.color,
|
228
|
-
stroke: options.borderColor,
|
229
|
-
'stroke-width': options.borderWidth
|
230
|
-
}).
|
231
|
-
add(series.group);
|
232
|
-
|
233
|
-
} else { // Update the shapes
|
234
|
-
graphic.animate(shapeArgs);
|
235
|
-
}
|
236
|
-
});
|
237
|
-
},
|
238
|
-
|
239
|
-
/**
|
240
|
-
* Extend the pie data label method
|
241
|
-
*/
|
242
|
-
drawDataLabels: function () {
|
243
|
-
var data = this.data,
|
244
|
-
labelDistance = this.options.dataLabels.distance,
|
245
|
-
leftSide,
|
246
|
-
sign,
|
247
|
-
point,
|
248
|
-
i = data.length,
|
249
|
-
x,
|
250
|
-
y;
|
251
|
-
|
252
|
-
// In the original pie label anticollision logic, the slots are distributed
|
253
|
-
// from one labelDistance above to one labelDistance below the pie. In funnels
|
254
|
-
// we don't want this.
|
255
|
-
this.center[2] -= 2 * labelDistance;
|
256
|
-
|
257
|
-
// Set the label position array for each point.
|
258
|
-
while (i--) {
|
259
|
-
point = data[i];
|
260
|
-
leftSide = point.half;
|
261
|
-
sign = leftSide ? 1 : -1;
|
262
|
-
y = point.plotY;
|
263
|
-
x = this.getX(y, leftSide);
|
264
|
-
|
265
|
-
// set the anchor point for data labels
|
266
|
-
point.labelPos = [
|
267
|
-
0, // first break of connector
|
268
|
-
y, // a/a
|
269
|
-
x + (labelDistance - 5) * sign, // second break, right outside point shape
|
270
|
-
y, // a/a
|
271
|
-
x + labelDistance * sign, // landing point for connector
|
272
|
-
y, // a/a
|
273
|
-
leftSide ? 'right' : 'left', // alignment
|
274
|
-
0 // center angle
|
275
|
-
];
|
276
|
-
}
|
277
|
-
|
278
|
-
seriesTypes.pie.prototype.drawDataLabels.call(this);
|
279
|
-
}
|
280
|
-
|
281
|
-
});
|
282
|
-
|
283
|
-
|
284
|
-
}(Highcharts));
|
1
|
+
/*
|
2
|
+
|
3
|
+
Highcharts funnel module, Beta
|
4
|
+
|
5
|
+
(c) 2010-2012 Torstein Hønsi
|
6
|
+
|
7
|
+
License: www.highcharts.com/license
|
8
|
+
*/
|
9
|
+
(function(d){var u=d.getOptions().plotOptions,p=d.seriesTypes,D=d.merge,B=function(){},z=d.each;u.funnel=D(u.pie,{center:["50%","50%"],width:"90%",neckWidth:"30%",height:"100%",neckHeight:"25%",dataLabels:{connectorWidth:1,connectorColor:"#606060"},size:!0,states:{select:{color:"#C0C0C0",borderColor:"#000000",shadow:!1}}});p.funnel=d.extendClass(p.pie,{type:"funnel",animate:B,translate:function(){var a=function(k,a){return/%$/.test(k)?a*parseInt(k,10)/100:parseInt(k,10)},g=0,e=this.chart,f=e.plotWidth,
|
10
|
+
e=e.plotHeight,h=0,c=this.options,C=c.center,b=a(C[0],f),d=a(C[0],e),p=a(c.width,f),i,q,j=a(c.height,e),r=a(c.neckWidth,f),s=a(c.neckHeight,e),v=j-s,a=this.data,w,x,u=c.dataLabels.position==="left"?1:0,y,m,A,n,l,t,o;this.getWidthAt=q=function(k){return k>j-s||j===s?r:r+(p-r)*((j-s-k)/(j-s))};this.getX=function(k,a){return b+(a?-1:1)*(q(k)/2+c.dataLabels.distance)};this.center=[b,d,j];this.centerX=b;z(a,function(a){g+=a.y});z(a,function(a){o=null;x=g?a.y/g:0;m=d-j/2+h*j;l=m+x*j;i=q(m);y=b-i/2;A=y+
|
11
|
+
i;i=q(l);n=b-i/2;t=n+i;m>v?(y=n=b-r/2,A=t=b+r/2):l>v&&(o=l,i=q(v),n=b-i/2,t=n+i,l=v);w=["M",y,m,"L",A,m,t,l];o&&w.push(t,o,n,o);w.push(n,l,"Z");a.shapeType="path";a.shapeArgs={d:w};a.percentage=x*100;a.plotX=b;a.plotY=(m+(o||l))/2;a.tooltipPos=[b,a.plotY];a.slice=B;a.half=u;h+=x});this.setTooltipPoints()},drawPoints:function(){var a=this,g=a.options,e=a.chart.renderer;z(a.data,function(f){var h=f.graphic,c=f.shapeArgs;h?h.animate(c):f.graphic=e.path(c).attr({fill:f.color,stroke:g.borderColor,"stroke-width":g.borderWidth}).add(a.group)})},
|
12
|
+
drawDataLabels:function(){var a=this.data,g=this.options.dataLabels.distance,e,f,h,c=a.length,d,b;for(this.center[2]-=2*g;c--;)h=a[c],f=(e=h.half)?1:-1,b=h.plotY,d=this.getX(b,e),h.labelPos=[0,b,d+(g-5)*f,b,d+g*f,b,e?"right":"left",0];p.pie.prototype.drawDataLabels.call(this)}})})(Highcharts);
|
@@ -1,57 +1 @@
|
|
1
|
-
(function (
|
2
|
-
var seriesTypes = Highcharts.seriesTypes,
|
3
|
-
each = Highcharts.each;
|
4
|
-
|
5
|
-
seriesTypes.heatmap = Highcharts.extendClass(seriesTypes.map, {
|
6
|
-
colorKey: 'z',
|
7
|
-
pointArrayMap: ['y', 'z'],
|
8
|
-
translate: function () {
|
9
|
-
var series = this,
|
10
|
-
options = series.options,
|
11
|
-
dataMin = Number.MAX_VALUE,
|
12
|
-
dataMax = Number.MIN_VALUE,
|
13
|
-
opacity,
|
14
|
-
minOpacity = options.minOpacity,
|
15
|
-
path,
|
16
|
-
color;
|
17
|
-
|
18
|
-
|
19
|
-
series.generatePoints();
|
20
|
-
|
21
|
-
each(series.data, function (point) {
|
22
|
-
var x = point.x,
|
23
|
-
y = point.y,
|
24
|
-
value = point.z,
|
25
|
-
xPad = (series.options.colsize || 1) / 2,
|
26
|
-
yPad = (series.options.rowsize || 1) / 2;
|
27
|
-
|
28
|
-
point.path = [
|
29
|
-
'M', x - xPad, y - yPad,
|
30
|
-
'L', x + xPad, y - yPad,
|
31
|
-
'L', x + xPad, y + yPad,
|
32
|
-
'L', x - xPad, y + yPad,
|
33
|
-
'Z'
|
34
|
-
];
|
35
|
-
|
36
|
-
point.shapeType = 'path';
|
37
|
-
point.shapeArgs = {
|
38
|
-
d: series.translatePath(point.path)
|
39
|
-
};
|
40
|
-
|
41
|
-
if (typeof value === 'number') {
|
42
|
-
if (value > dataMax) {
|
43
|
-
dataMax = value;
|
44
|
-
} else if (value < dataMin) {
|
45
|
-
dataMin = value;
|
46
|
-
}
|
47
|
-
}
|
48
|
-
});
|
49
|
-
|
50
|
-
series.translateColors(dataMin, dataMax);
|
51
|
-
},
|
52
|
-
|
53
|
-
getBox: function () {}
|
54
|
-
|
55
|
-
});
|
56
|
-
|
57
|
-
}(Highcharts));
|
1
|
+
(function(b){var k=b.seriesTypes,l=b.each;k.heatmap=b.extendClass(k.map,{colorKey:"z",pointArrayMap:["y","z"],translate:function(){var c=this,b=c.options,i=Number.MAX_VALUE,j=Number.MIN_VALUE;c.generatePoints();l(c.data,function(a){var e=a.x,f=a.y,d=a.z,g=(b.colsize||1)/2,h=(b.rowsize||1)/2;a.path=["M",e-g,f-h,"L",e+g,f-h,"L",e+g,f+h,"L",e-g,f+h,"Z"];a.shapeType="path";a.shapeArgs={d:c.translatePath(a.path)};typeof d==="number"&&(d>j?j=d:d<i&&(i=d))});c.translateColors(i,j)},getBox:function(){}})})(Highcharts);
|
@@ -1,576 +1,21 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
(function
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
pick = Highcharts.pick,
|
23
|
-
numberFormat = Highcharts.numberFormat,
|
24
|
-
plotOptions = Highcharts.getOptions().plotOptions,
|
25
|
-
Color = Highcharts.Color,
|
26
|
-
noop = function () {};
|
27
|
-
|
28
|
-
/**
|
29
|
-
* Utility for reading SVG paths directly.
|
30
|
-
*
|
31
|
-
* @todo This is moved to the Data plugin. Make sure it is deleted here.
|
32
|
-
*/
|
33
|
-
Highcharts.pathToArray = function (path) {
|
34
|
-
var i;
|
35
|
-
|
36
|
-
// Move letters apart
|
37
|
-
path = path.replace(/([A-Za-z])/g, ' $1 ');
|
38
|
-
// Trim
|
39
|
-
path = path.replace(/^\s*/, "").replace(/\s*$/, "");
|
40
|
-
|
41
|
-
// Split on spaces and commas
|
42
|
-
path = path.split(/[ ,]+/);
|
43
|
-
|
44
|
-
for (i = 0; i < path.length; i++) {
|
45
|
-
if (!/[a-zA-Z]/.test(path[i])) {
|
46
|
-
path[i] = parseFloat(path[i]);
|
47
|
-
}
|
48
|
-
}
|
49
|
-
return path;
|
50
|
-
};
|
51
|
-
|
52
|
-
/**
|
53
|
-
* Extend the Axis object with methods specific to maps
|
54
|
-
*/
|
55
|
-
Highcharts.wrap(Axis.prototype, 'init', function (proceed, chart, userOptions) {
|
56
|
-
|
57
|
-
if (chart.options.chart.type === 'map') {
|
58
|
-
extend(this, {
|
59
|
-
|
60
|
-
/**
|
61
|
-
* Override to use the extreme coordinates from the SVG shape, not the
|
62
|
-
* data values
|
63
|
-
*/
|
64
|
-
getSeriesExtremes: function () {
|
65
|
-
var isXAxis = this.isXAxis,
|
66
|
-
dataMin = Number.MAX_VALUE,
|
67
|
-
dataMax = Number.MIN_VALUE;
|
68
|
-
each(this.series, function (series) {
|
69
|
-
dataMin = Math.min(dataMin, series[isXAxis ? 'minX' : 'minY']);
|
70
|
-
dataMax = Math.max(dataMax, series[isXAxis ? 'maxX' : 'maxY']);
|
71
|
-
});
|
72
|
-
this.dataMin = dataMin;
|
73
|
-
this.dataMax = dataMax;
|
74
|
-
},
|
75
|
-
|
76
|
-
/**
|
77
|
-
* Override axis translation to make sure the aspect ratio is always kept
|
78
|
-
*/
|
79
|
-
setAxisTranslation: function () {
|
80
|
-
var chart = this.chart,
|
81
|
-
mapRatio,
|
82
|
-
plotRatio = chart.plotWidth / chart.plotHeight,
|
83
|
-
isXAxis = this.isXAxis,
|
84
|
-
adjustedAxisLength,
|
85
|
-
xAxis = chart.xAxis[0],
|
86
|
-
padAxis;
|
87
|
-
|
88
|
-
// Run the parent method
|
89
|
-
Axis.prototype.setAxisTranslation.call(this);
|
90
|
-
|
91
|
-
// On Y axis, handle both
|
92
|
-
if (!isXAxis && xAxis.transA !== UNDEFINED) {
|
93
|
-
|
94
|
-
// Use the same translation for both axes
|
95
|
-
this.transA = xAxis.transA = Math.min(this.transA, xAxis.transA);
|
96
|
-
|
97
|
-
mapRatio = (xAxis.max - xAxis.min) / (this.max - this.min);
|
98
|
-
|
99
|
-
// What axis to pad to put the map in the middle
|
100
|
-
padAxis = mapRatio > plotRatio ? this : xAxis;
|
101
|
-
|
102
|
-
// Pad it
|
103
|
-
adjustedAxisLength = (padAxis.max - padAxis.min) * padAxis.transA;
|
104
|
-
padAxis.minPixelPadding = (padAxis.len - adjustedAxisLength) / 2;
|
105
|
-
}
|
106
|
-
|
107
|
-
}
|
108
|
-
});
|
109
|
-
}
|
110
|
-
|
111
|
-
return proceed.call(this, chart, userOptions);
|
112
|
-
});
|
113
|
-
|
114
|
-
/**
|
115
|
-
* Extend the default options with map options
|
116
|
-
*/
|
117
|
-
plotOptions.map = merge(
|
118
|
-
plotOptions.scatter,
|
119
|
-
{
|
120
|
-
animation: false, // makes the complex shapes slow
|
121
|
-
minOpacity: 0.2,
|
122
|
-
nullColor: '#F8F8F8',
|
123
|
-
borderColor: 'silver',
|
124
|
-
borderWidth: 1,
|
125
|
-
marker: null,
|
126
|
-
stickyTracking: false,
|
127
|
-
tooltip: {
|
128
|
-
followPointer: true,
|
129
|
-
headerFormat: '<span style="font-size:10px">{point.key}</span><br/>',
|
130
|
-
pointFormat: '{series.name}: {point.y}<br/>'
|
131
|
-
}
|
132
|
-
}
|
133
|
-
);
|
134
|
-
|
135
|
-
/**
|
136
|
-
* Add the series type
|
137
|
-
*/
|
138
|
-
Highcharts.seriesTypes.map = Highcharts.extendClass(Highcharts.seriesTypes.scatter, {
|
139
|
-
type: 'map',
|
140
|
-
pointAttrToOptions: { // mapping between SVG attributes and the corresponding options
|
141
|
-
stroke: 'borderColor',
|
142
|
-
'stroke-width': 'borderWidth',
|
143
|
-
fill: 'color'
|
144
|
-
},
|
145
|
-
colorKey: 'y',
|
146
|
-
trackerGroups: ['group', 'markerGroup'],
|
147
|
-
getSymbol: noop,
|
148
|
-
getExtremesFromAll: true,
|
149
|
-
init: function (chart) {
|
150
|
-
var series = this,
|
151
|
-
valueDecimals = chart.options.legend.valueDecimals,
|
152
|
-
legendItems = [],
|
153
|
-
name,
|
154
|
-
from,
|
155
|
-
to,
|
156
|
-
fromLabel,
|
157
|
-
toLabel,
|
158
|
-
colorRange,
|
159
|
-
gradientColor,
|
160
|
-
grad,
|
161
|
-
tmpLabel,
|
162
|
-
horizontal = chart.options.legend.layout === 'horizontal';
|
163
|
-
|
164
|
-
|
165
|
-
Highcharts.Series.prototype.init.apply(this, arguments);
|
166
|
-
colorRange = series.options.colorRange;
|
167
|
-
|
168
|
-
if (series.options.valueRanges) {
|
169
|
-
each(series.options.valueRanges, function (range) {
|
170
|
-
from = range.from;
|
171
|
-
to = range.to;
|
172
|
-
|
173
|
-
// Assemble the default name. This can be overridden by legend.options.labelFormatter
|
174
|
-
name = '';
|
175
|
-
if (from === UNDEFINED) {
|
176
|
-
name = '< ';
|
177
|
-
} else if (to === UNDEFINED) {
|
178
|
-
name = '> ';
|
179
|
-
}
|
180
|
-
if (from !== UNDEFINED) {
|
181
|
-
name += numberFormat(from, valueDecimals);
|
182
|
-
}
|
183
|
-
if (from !== UNDEFINED && to !== UNDEFINED) {
|
184
|
-
name += ' - ';
|
185
|
-
}
|
186
|
-
if (to !== UNDEFINED) {
|
187
|
-
name += numberFormat(to, valueDecimals);
|
188
|
-
}
|
189
|
-
|
190
|
-
// Add a mock object to the legend items
|
191
|
-
legendItems.push(Highcharts.extend({
|
192
|
-
chart: series.chart,
|
193
|
-
name: name,
|
194
|
-
options: {},
|
195
|
-
drawLegendSymbol: Highcharts.seriesTypes.area.prototype.drawLegendSymbol,
|
196
|
-
visible: true,
|
197
|
-
setState: function () {},
|
198
|
-
setVisible: function () {}
|
199
|
-
}, range));
|
200
|
-
});
|
201
|
-
series.legendItems = legendItems;
|
202
|
-
|
203
|
-
} else if (colorRange) {
|
204
|
-
|
205
|
-
from = colorRange.from;
|
206
|
-
to = colorRange.to;
|
207
|
-
fromLabel = colorRange.fromLabel;
|
208
|
-
toLabel = colorRange.toLabel;
|
209
|
-
|
210
|
-
// Flips linearGradient variables and label text.
|
211
|
-
grad = horizontal ? [0, 0, 1, 0] : [0, 1, 0, 0];
|
212
|
-
if (!horizontal) {
|
213
|
-
tmpLabel = fromLabel;
|
214
|
-
fromLabel = toLabel;
|
215
|
-
toLabel = tmpLabel;
|
216
|
-
}
|
217
|
-
|
218
|
-
// Creates color gradient.
|
219
|
-
gradientColor = {
|
220
|
-
linearGradient: { x1: grad[0], y1: grad[1], x2: grad[2], y2: grad[3] },
|
221
|
-
stops:
|
222
|
-
[
|
223
|
-
[0, from],
|
224
|
-
[1, to]
|
225
|
-
]
|
226
|
-
};
|
227
|
-
|
228
|
-
// Add a mock object to the legend items.
|
229
|
-
legendItems = [{
|
230
|
-
chart: series.chart,
|
231
|
-
options: {},
|
232
|
-
fromLabel: fromLabel,
|
233
|
-
toLabel: toLabel,
|
234
|
-
color: gradientColor,
|
235
|
-
drawLegendSymbol: this.drawLegendSymbol,
|
236
|
-
visible: true,
|
237
|
-
setState: function () {},
|
238
|
-
setVisible: function () {}
|
239
|
-
}];
|
240
|
-
|
241
|
-
series.legendItems = legendItems;
|
242
|
-
}
|
243
|
-
},
|
244
|
-
|
245
|
-
/**
|
246
|
-
* Gets the series' symbol in the legend and extended legend with more information.
|
247
|
-
*
|
248
|
-
* @param {Object} legend The legend object
|
249
|
-
* @param {Object} item The series (this) or point
|
250
|
-
*/
|
251
|
-
drawLegendSymbol: function (legend, item) {
|
252
|
-
|
253
|
-
var spacing = legend.options.symbolPadding,
|
254
|
-
padding = pick(legend.options.padding, 8),
|
255
|
-
positionY,
|
256
|
-
positionX,
|
257
|
-
gradientSize = this.chart.renderer.fontMetrics(legend.options.itemStyle.fontSize).h,
|
258
|
-
horizontal = legend.options.layout === 'horizontal',
|
259
|
-
box1,
|
260
|
-
box2,
|
261
|
-
box3,
|
262
|
-
rectangleLength = pick(legend.options.rectangleLength, 200);
|
263
|
-
|
264
|
-
// Set local variables based on option.
|
265
|
-
if (horizontal) {
|
266
|
-
positionY = -(spacing / 2);
|
267
|
-
positionX = 0;
|
268
|
-
} else {
|
269
|
-
positionY = -rectangleLength + legend.baseline - (spacing / 2);
|
270
|
-
positionX = padding + gradientSize;
|
271
|
-
}
|
272
|
-
|
273
|
-
// Creates the from text.
|
274
|
-
item.fromText = this.chart.renderer.text(
|
275
|
-
item.fromLabel, // Text.
|
276
|
-
positionX, // Lower left x.
|
277
|
-
positionY // Lower left y.
|
278
|
-
).attr({
|
279
|
-
zIndex: 2
|
280
|
-
}).add(item.legendGroup);
|
281
|
-
box1 = item.fromText.getBBox();
|
282
|
-
|
283
|
-
// Creates legend symbol.
|
284
|
-
// Ternary changes variables based on option.
|
285
|
-
item.legendSymbol = this.chart.renderer.rect(
|
286
|
-
horizontal ? box1.x + box1.width + spacing : box1.x - gradientSize - spacing, // Upper left x.
|
287
|
-
box1.y, // Upper left y.
|
288
|
-
horizontal ? rectangleLength : gradientSize, // Width.
|
289
|
-
horizontal ? gradientSize : rectangleLength, // Height.
|
290
|
-
2 // Corner radius.
|
291
|
-
).attr({
|
292
|
-
zIndex: 1
|
293
|
-
}).add(item.legendGroup);
|
294
|
-
box2 = item.legendSymbol.getBBox();
|
295
|
-
|
296
|
-
// Creates the to text.
|
297
|
-
// Vertical coordinate changed based on option.
|
298
|
-
item.toText = this.chart.renderer.text(
|
299
|
-
item.toLabel,
|
300
|
-
box2.x + box2.width + spacing,
|
301
|
-
horizontal ? positionY : box2.y + box2.height - spacing
|
302
|
-
).attr({
|
303
|
-
zIndex: 2
|
304
|
-
}).add(item.legendGroup);
|
305
|
-
box3 = item.toText.getBBox();
|
306
|
-
|
307
|
-
// Changes legend box settings based on option.
|
308
|
-
if (horizontal) {
|
309
|
-
legend.offsetWidth = box1.width + box2.width + box3.width + (spacing * 2) + padding;
|
310
|
-
legend.itemY = gradientSize + padding;
|
311
|
-
} else {
|
312
|
-
legend.offsetWidth = Math.max(box1.width, box3.width) + (spacing) + box2.width + padding;
|
313
|
-
legend.itemY = box2.height + padding;
|
314
|
-
legend.itemX = spacing;
|
315
|
-
}
|
316
|
-
},
|
317
|
-
|
318
|
-
/**
|
319
|
-
* Get the bounding box of all paths in the map combined.
|
320
|
-
*/
|
321
|
-
getBox: function () {
|
322
|
-
var chart = this.chart,
|
323
|
-
maxX = -Math.pow(2, 31),
|
324
|
-
minX = Math.pow(2, 31) - 1,
|
325
|
-
maxY = -Math.pow(2, 31),
|
326
|
-
minY = Math.pow(2, 31) - 1,
|
327
|
-
xyRatio,
|
328
|
-
ratioCorrection,
|
329
|
-
plotWidth = chart.plotWidth,
|
330
|
-
plotHeight = chart.plotHeight,
|
331
|
-
pad;
|
332
|
-
|
333
|
-
|
334
|
-
// Find the bounding box
|
335
|
-
each(this.options.data, function (point) {
|
336
|
-
var path = point.path,
|
337
|
-
i = path.length,
|
338
|
-
even = false; // while loop reads from the end
|
339
|
-
|
340
|
-
while (i--) {
|
341
|
-
if (typeof path[i] === 'number') {
|
342
|
-
if (even) { // even = x
|
343
|
-
maxX = Math.max(maxX, path[i]);
|
344
|
-
minX = Math.min(minX, path[i]);
|
345
|
-
} else { // odd = Y
|
346
|
-
maxY = Math.max(maxY, path[i]);
|
347
|
-
minY = Math.min(minY, path[i]);
|
348
|
-
}
|
349
|
-
even = !even;
|
350
|
-
}
|
351
|
-
}
|
352
|
-
});
|
353
|
-
this.minY = minY;
|
354
|
-
this.maxY = maxY;
|
355
|
-
this.minX = minX;
|
356
|
-
this.maxX = maxX;
|
357
|
-
|
358
|
-
},
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
/**
|
363
|
-
* Translate the path so that it automatically fits into the plot area box
|
364
|
-
* @param {Object} path
|
365
|
-
*/
|
366
|
-
translatePath: function (path) {
|
367
|
-
|
368
|
-
var series = this,
|
369
|
-
chart = series.chart,
|
370
|
-
even = false, // while loop reads from the end
|
371
|
-
xAxis = series.xAxis,
|
372
|
-
yAxis = series.yAxis;
|
373
|
-
|
374
|
-
// Preserve the original
|
375
|
-
path = [].concat(path);
|
376
|
-
|
377
|
-
// Do the translation
|
378
|
-
i = path.length;
|
379
|
-
while (i--) {
|
380
|
-
if (typeof path[i] === 'number') {
|
381
|
-
if (even) { // even = x
|
382
|
-
path[i] = Math.round(xAxis.translate(path[i]));
|
383
|
-
} else { // odd = Y
|
384
|
-
path[i] = Math.round(yAxis.len - yAxis.translate(path[i]));
|
385
|
-
}
|
386
|
-
even = !even;
|
387
|
-
}
|
388
|
-
}
|
389
|
-
return path;
|
390
|
-
},
|
391
|
-
|
392
|
-
setData: function () {
|
393
|
-
Highcharts.Series.prototype.setData.apply(this, arguments);
|
394
|
-
this.getBox();
|
395
|
-
},
|
396
|
-
|
397
|
-
/**
|
398
|
-
* Add the path option for data points. Find the max value for color calculation.
|
399
|
-
*/
|
400
|
-
translate: function () {
|
401
|
-
var series = this,
|
402
|
-
options = series.options,
|
403
|
-
dataMin = Number.MAX_VALUE,
|
404
|
-
dataMax = Number.MIN_VALUE,
|
405
|
-
opacity,
|
406
|
-
minOpacity = options.minOpacity,
|
407
|
-
path,
|
408
|
-
color;
|
409
|
-
|
410
|
-
series.generatePoints();
|
411
|
-
|
412
|
-
each(series.data, function (point) {
|
413
|
-
|
414
|
-
point.shapeType = 'path';
|
415
|
-
point.shapeArgs = {
|
416
|
-
d: series.translatePath(point.path)
|
417
|
-
};
|
418
|
-
|
419
|
-
// TODO: do point colors in drawPoints instead of point.init
|
420
|
-
if (typeof point.y === 'number') {
|
421
|
-
if (point.y > dataMax) {
|
422
|
-
dataMax = point.y;
|
423
|
-
} else if (point.y < dataMin) {
|
424
|
-
dataMin = point.y;
|
425
|
-
}
|
426
|
-
}
|
427
|
-
});
|
428
|
-
|
429
|
-
series.translateColors(dataMin, dataMax);
|
430
|
-
},
|
431
|
-
|
432
|
-
/**
|
433
|
-
* In choropleth maps, the color is a result of the value, so this needs translation tood
|
434
|
-
*/
|
435
|
-
translateColors: function (dataMin, dataMax) {
|
436
|
-
|
437
|
-
var seriesOptions = this.options,
|
438
|
-
valueRanges = seriesOptions.valueRanges,
|
439
|
-
colorRange = seriesOptions.colorRange,
|
440
|
-
colorKey = this.colorKey;
|
441
|
-
|
442
|
-
each(this.data, function (point) {
|
443
|
-
var value = point[colorKey],
|
444
|
-
rgba = [],
|
445
|
-
range,
|
446
|
-
from,
|
447
|
-
to,
|
448
|
-
i,
|
449
|
-
pos;
|
450
|
-
|
451
|
-
if (valueRanges) {
|
452
|
-
i = valueRanges.length;
|
453
|
-
while (i--) {
|
454
|
-
range = valueRanges[i];
|
455
|
-
from = range.from;
|
456
|
-
to = range.to;
|
457
|
-
if ((from === UNDEFINED || value >= from) && (to === UNDEFINED || value <= to)) {
|
458
|
-
point.options.color = range.color;
|
459
|
-
break;
|
460
|
-
}
|
461
|
-
|
462
|
-
}
|
463
|
-
} else if (colorRange && value !== undefined) {
|
464
|
-
from = Color(colorRange.from);
|
465
|
-
to = Color(colorRange.to);
|
466
|
-
pos = (dataMax - value) / (dataMax - dataMin);
|
467
|
-
i = 4;
|
468
|
-
while (i--) {
|
469
|
-
rgba[i] = Math.round(
|
470
|
-
to.rgba[i] + (from.rgba[i] - to.rgba[i]) * pos
|
471
|
-
);
|
472
|
-
}
|
473
|
-
point.options.color = 'rgba(' + rgba.join(',') + ')';
|
474
|
-
}
|
475
|
-
});
|
476
|
-
},
|
477
|
-
|
478
|
-
drawGraph: noop,
|
479
|
-
|
480
|
-
/**
|
481
|
-
* We need the points' bounding boxes in order to draw the data labels, so
|
482
|
-
* we skip it now and call if from drawPoints instead.
|
483
|
-
*/
|
484
|
-
drawDataLabels: noop,
|
485
|
-
|
486
|
-
/**
|
487
|
-
* Use the drawPoints method of column, that is able to handle simple shapeArgs.
|
488
|
-
* Extend it by assigning the tooltip position.
|
489
|
-
*/
|
490
|
-
drawPoints: function () {
|
491
|
-
var series = this,
|
492
|
-
chart = series.chart,
|
493
|
-
saturation,
|
494
|
-
bBox,
|
495
|
-
colorKey = series.colorKey;
|
496
|
-
|
497
|
-
// Make points pass test in drawing
|
498
|
-
each(series.data, function (point) {
|
499
|
-
point.plotY = 1; // pass null test in column.drawPoints
|
500
|
-
if (point[colorKey] === null) {
|
501
|
-
point[colorKey] = 0;
|
502
|
-
point.isNull = true;
|
503
|
-
}
|
504
|
-
});
|
505
|
-
|
506
|
-
// Draw them
|
507
|
-
Highcharts.seriesTypes.column.prototype.drawPoints.apply(series);
|
508
|
-
|
509
|
-
each(series.data, function (point) {
|
510
|
-
|
511
|
-
bBox = point.graphic.getBBox();
|
512
|
-
// for tooltip
|
513
|
-
point.tooltipPos = [
|
514
|
-
bBox.x + bBox.width / 2,
|
515
|
-
bBox.y + bBox.height / 2
|
516
|
-
];
|
517
|
-
// for data labels
|
518
|
-
point.plotX = point.tooltipPos[0];
|
519
|
-
point.plotY = point.tooltipPos[1];
|
520
|
-
|
521
|
-
// Reset escaped null points
|
522
|
-
if (point.isNull) {
|
523
|
-
point[colorKey] = null;
|
524
|
-
}
|
525
|
-
});
|
526
|
-
|
527
|
-
// Now draw the data labels
|
528
|
-
Highcharts.Series.prototype.drawDataLabels.call(series);
|
529
|
-
|
530
|
-
}
|
531
|
-
});
|
532
|
-
|
533
|
-
/**
|
534
|
-
* A wrapper for Chart with all the default values for a Map
|
535
|
-
*/
|
536
|
-
Highcharts.Map = function (options, callback) {
|
537
|
-
|
538
|
-
var hiddenAxis = {
|
539
|
-
endOnTick: false,
|
540
|
-
gridLineWidth: 0,
|
541
|
-
labels: {
|
542
|
-
enabled: false
|
543
|
-
},
|
544
|
-
lineWidth: 0,
|
545
|
-
minPadding: 0,
|
546
|
-
maxPadding: 0,
|
547
|
-
startOnTick: false,
|
548
|
-
tickWidth: 0,
|
549
|
-
title: null
|
550
|
-
};
|
551
|
-
|
552
|
-
// Don't merge the data
|
553
|
-
seriesOptions = options.series;
|
554
|
-
options.series = null;
|
555
|
-
|
556
|
-
options = merge({
|
557
|
-
chart: {
|
558
|
-
type: 'map'
|
559
|
-
},
|
560
|
-
xAxis: hiddenAxis,
|
561
|
-
yAxis: merge(hiddenAxis, { reversed: true })
|
562
|
-
},
|
563
|
-
options, // user's options
|
564
|
-
|
565
|
-
{ // forced options
|
566
|
-
chart: {
|
567
|
-
inverted: false
|
568
|
-
}
|
569
|
-
});
|
570
|
-
|
571
|
-
options.series = seriesOptions;
|
572
|
-
|
573
|
-
|
574
|
-
return new Highcharts.Chart(options, callback);
|
575
|
-
};
|
576
|
-
}(Highcharts));
|
1
|
+
/*
|
2
|
+
Map plugin v0.1 for Highcharts
|
3
|
+
|
4
|
+
(c) 2011-2013 Torstein Hønsi
|
5
|
+
|
6
|
+
License: www.highcharts.com/license
|
7
|
+
*/
|
8
|
+
(function(f){var s=f.Axis,t=f.Chart,k=f.each,q=f.extend,p=f.merge,n=f.pick,u=f.numberFormat,v=f.getOptions(),w=v.plotOptions,x=f.Color,r=function(){};v.mapNavigation={enabled:!1,buttonOptions:{align:"right",verticalAlign:"bottom",x:0,width:18,height:18,style:{fontSize:"15px",fontWeight:"bold",textAlign:"center"}},buttons:{zoomIn:{onclick:function(){this.mapZoom(0.5)},text:"+",y:-32},zoomOut:{onclick:function(){this.mapZoom(2)},text:"-",y:0}}};f.splitPath=function(a){var b,a=a.replace(/([A-Za-z])/g,
|
9
|
+
" $1 "),a=a.replace(/^\s*/,"").replace(/\s*$/,""),a=a.split(/[ ,]+/);for(b=0;b<a.length;b++)/[a-zA-Z]/.test(a[b])||(a[b]=parseFloat(a[b]));return a};f.maps={};f.wrap(s.prototype,"init",function(a,b,c){b.options.chart.type==="map"&&q(this,{getSeriesExtremes:function(){var d=this.isXAxis,a=Number.MAX_VALUE,b=Number.MIN_VALUE;k(this.series,function(c){a=Math.min(a,c[d?"minX":"minY"]);b=Math.max(b,c[d?"maxX":"maxY"])});this.dataMin=a;this.dataMax=b},setAxisTranslation:function(){var a=this.chart,b,c=
|
10
|
+
a.plotWidth/a.plotHeight;b=this.isXAxis;a=a.xAxis[0];s.prototype.setAxisTranslation.call(this);if(!b&&a.transA!==void 0)this.transA=a.transA=Math.min(this.transA,a.transA),b=(a.max-a.min)/(this.max-this.min),b=b>c?this:a,c=(b.max-b.min)*b.transA,b.minPixelPadding=(b.len-c)/2}});return a.call(this,b,c)});f.wrap(t.prototype,"render",function(a){a.call(this);this.renderMapNavigation()});q(t.prototype,{renderMapNavigation:function(){var a=this,b=this.options.mapNavigation,c=b.buttons,d,e,h,i=function(){this.handler.call(a)};
|
11
|
+
if(n(b.enabled,!0))for(d in c)if(c.hasOwnProperty(d))h=p(b.buttonOptions,c[d]),e=a.renderer.button(h.text,0,0,i).attr({width:h.width,height:h.height}).css(h.style).add(),e.handler=h.onclick,e.align(q(h,{width:e.width,height:e.height}),null,"spacingBox")},fitToBox:function(a,b){k([["x","width"],["y","height"]],function(c){var d=c[0],c=c[1];a[d]+a[c]>b[d]+b[c]&&(a[c]>b[c]?(a[c]=b[c],a[d]=b[d]):a[d]=b[d]+b[c]-a[c]);a[d]<b[d]&&(a[d]=b[d])});return a},mapZoom:function(a){var b=this.xAxis[0],c=b.max-b.min,
|
12
|
+
d=c*a,e=this.yAxis[0],h=e.max-e.min;a*=h;c=this.fitToBox({x:b.min+c/2-d/2,y:e.min+h/2-a/2,width:d,height:a},{x:b.dataMin,y:e.dataMin,width:b.dataMax-b.dataMin,height:e.dataMax-e.dataMin});b.setExtremes(c.x,c.x+c.width,!1);e.setExtremes(c.y,c.y+c.height,!1);this.redraw()}});w.map=p(w.scatter,{animation:!1,minOpacity:0.2,nullColor:"#F8F8F8",borderColor:"silver",borderWidth:1,marker:null,stickyTracking:!1,dataLabels:{verticalAlign:"middle"},tooltip:{followPointer:!0,headerFormat:'<span style="font-size:10px">{point.key}</span><br/>',
|
13
|
+
pointFormat:"{series.name}: {point.y}<br/>"}});f.seriesTypes.map=f.extendClass(f.seriesTypes.scatter,{type:"map",pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color"},colorKey:"y",trackerGroups:["group","markerGroup","dataLabelsGroup"],getSymbol:r,getExtremesFromAll:!0,init:function(a){var b=this,c=a.options.legend.valueDecimals,d=[],e,h,i,j,g,o,l;l=a.options.legend.layout==="horizontal";f.Series.prototype.init.apply(this,arguments);g=b.options.colorRange;if(b.options.valueRanges)k(b.options.valueRanges,
|
14
|
+
function(a){h=a.from;i=a.to;e="";h===void 0?e="< ":i===void 0&&(e="> ");h!==void 0&&(e+=u(h,c));h!==void 0&&i!==void 0&&(e+=" - ");i!==void 0&&(e+=u(i,c));d.push(f.extend({chart:b.chart,name:e,options:{},drawLegendSymbol:f.seriesTypes.area.prototype.drawLegendSymbol,visible:!0,setState:function(){},setVisible:function(){}},a))}),b.legendItems=d;else if(g)h=g.from,i=g.to,j=g.fromLabel,g=g.toLabel,o=l?[0,0,1,0]:[0,1,0,0],l||(l=j,j=g,g=l),o={linearGradient:{x1:o[0],y1:o[1],x2:o[2],y2:o[3]},stops:[[0,
|
15
|
+
h],[1,i]]},d=[{chart:b.chart,options:{},fromLabel:j,toLabel:g,color:o,drawLegendSymbol:this.drawLegendSymbol,visible:!0,setState:function(){},setVisible:function(){}}],b.legendItems=d},drawLegendSymbol:function(a,b){var c=a.options.symbolPadding,d=n(a.options.padding,8),e,h,i=this.chart.renderer.fontMetrics(a.options.itemStyle.fontSize).h,j=a.options.layout==="horizontal",g;g=n(a.options.rectangleLength,200);j?(e=-(c/2),h=0):(e=-g+a.baseline-c/2,h=d+i);b.fromText=this.chart.renderer.text(b.fromLabel,
|
16
|
+
h,e).attr({zIndex:2}).add(b.legendGroup);h=b.fromText.getBBox();b.legendSymbol=this.chart.renderer.rect(j?h.x+h.width+c:h.x-i-c,h.y,j?g:i,j?i:g,2).attr({zIndex:1}).add(b.legendGroup);g=b.legendSymbol.getBBox();b.toText=this.chart.renderer.text(b.toLabel,g.x+g.width+c,j?e:g.y+g.height-c).attr({zIndex:2}).add(b.legendGroup);e=b.toText.getBBox();j?(a.offsetWidth=h.width+g.width+e.width+c*2+d,a.itemY=i+d):(a.offsetWidth=Math.max(h.width,e.width)+c+g.width+d,a.itemY=g.height+d,a.itemX=c)},getBox:function(a){var b=
|
17
|
+
Number.MIN_VALUE,c=Number.MAX_VALUE,d=Number.MIN_VALUE,e=Number.MAX_VALUE;k(a||this.options.data,function(a){for(var i=a.path,j=i.length,g=!1,f=Number.MIN_VALUE,l=Number.MAX_VALUE,m=Number.MIN_VALUE,k=Number.MAX_VALUE;j--;)typeof i[j]==="number"&&(g?(f=Math.max(f,i[j]),l=Math.min(l,i[j])):(m=Math.max(m,i[j]),k=Math.min(k,i[j])),g=!g);a._maxX=f;a._minX=l;a._maxY=m;a._minY=k;b=Math.max(b,f);c=Math.min(c,l);d=Math.max(d,m);e=Math.min(e,k)});this.minY=e;this.maxY=d;this.minX=c;this.maxX=b},translatePath:function(a){var b=
|
18
|
+
!1,c=this.xAxis,d=this.yAxis,e,a=[].concat(a);for(e=a.length;e--;)typeof a[e]==="number"&&(a[e]=b?Math.round(c.translate(a[e])):Math.round(d.len-d.translate(a[e])),b=!b);return a},setData:function(){f.Series.prototype.setData.apply(this,arguments);this.getBox()},translate:function(){var a=this,b=Number.MAX_VALUE,c=Number.MIN_VALUE;a.generatePoints();k(a.data,function(d){d.shapeType="path";d.shapeArgs={d:a.translatePath(d.path)};if(typeof d.y==="number")if(d.y>c)c=d.y;else if(d.y<b)b=d.y});a.translateColors(b,
|
19
|
+
c)},translateColors:function(a,b){var c=this.options,d=c.valueRanges,e=c.colorRange,h=this.colorKey,i,f;e&&(i=x(e.from),f=x(e.to));k(this.data,function(g){var k=g[h],l=[],m,n;if(d)for(m=d.length;m--;){if(l=d[m],i=l.from,f=l.to,(i===void 0||k>=i)&&(f===void 0||k<=f)){g.options.color=l.color;break}}else if(e&&k!==void 0){n=(b-k)/(b-a);for(m=4;m--;)l[m]=Math.round(f.rgba[m]+(i.rgba[m]-f.rgba[m])*n);g.options.color=k===null?c.nullColor:"rgba("+l.join(",")+")"}})},drawGraph:r,drawDataLabels:r,drawPoints:function(){var a=
|
20
|
+
this.xAxis,b=this.yAxis,c=this.colorKey;k(this.data,function(a){a.plotY=1;if(a[c]===null)a[c]=0,a.isNull=!0});f.seriesTypes.column.prototype.drawPoints.apply(this);k(this.data,function(d){var e=d.dataLabels,f=a.toPixels(d._minX,!0),i=a.toPixels(d._maxX,!0),j=b.toPixels(d._minY,!0),g=b.toPixels(d._maxY,!0);d.plotX=Math.round(f+(i-f)*n(e&&e.anchorX,0.5));d.plotY=Math.round(j+(g-j)*n(e&&e.anchorY,0.5));d.isNull&&(d[c]=null)});f.Series.prototype.drawDataLabels.call(this)}});f.Map=function(a,b){var c=
|
21
|
+
{endOnTick:!1,gridLineWidth:0,labels:{enabled:!1},lineWidth:0,minPadding:0,maxPadding:0,startOnTick:!1,tickWidth:0,title:null},d;d=a.series;a.series=null;a=p({chart:{type:"map",panning:"xy"},xAxis:c,yAxis:p(c,{reversed:!0})},a,{chart:{inverted:!1}});a.series=d;return new f.Chart(a,b)}})(Highcharts);
|