From 4f953ffc89fc95f83b152e914c5e65938b440f17 Mon Sep 17 00:00:00 2001
From: Xxxu <794772283@qq.com>
Date: 星期二, 07 七月 2020 10:03:02 +0800
Subject: [PATCH] 上传项目
---
static/plugins/ueditor-1.4.3.3/third-party/highcharts/modules/map.src.js | 1002 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 1,002 insertions(+), 0 deletions(-)
diff --git a/static/plugins/ueditor-1.4.3.3/third-party/highcharts/modules/map.src.js b/static/plugins/ueditor-1.4.3.3/third-party/highcharts/modules/map.src.js
new file mode 100644
index 0000000..6af8e21
--- /dev/null
+++ b/static/plugins/ueditor-1.4.3.3/third-party/highcharts/modules/map.src.js
@@ -0,0 +1,1002 @@
+/**
+ * @license Map plugin v0.1 for Highcharts
+ *
+ * (c) 2011-2013 Torstein H酶nsi
+ *
+ * License: www.highcharts.com/license
+ */
+
+/*
+ * See www.highcharts.com/studies/world-map.htm for use case.
+ *
+ * To do:
+ * - Optimize long variable names and alias adapter methods and Highcharts namespace variables
+ * - Zoom and pan GUI
+ */
+(function (Highcharts) {
+ var UNDEFINED,
+ Axis = Highcharts.Axis,
+ Chart = Highcharts.Chart,
+ Point = Highcharts.Point,
+ Pointer = Highcharts.Pointer,
+ each = Highcharts.each,
+ extend = Highcharts.extend,
+ merge = Highcharts.merge,
+ pick = Highcharts.pick,
+ numberFormat = Highcharts.numberFormat,
+ defaultOptions = Highcharts.getOptions(),
+ seriesTypes = Highcharts.seriesTypes,
+ plotOptions = defaultOptions.plotOptions,
+ wrap = Highcharts.wrap,
+ Color = Highcharts.Color,
+ noop = function () {};
+
+
+
+ /*
+ * Return an intermediate color between two colors, according to pos where 0
+ * is the from color and 1 is the to color
+ */
+ function tweenColors(from, to, pos) {
+ var i = 4,
+ rgba = [];
+
+ while (i--) {
+ rgba[i] = Math.round(
+ to.rgba[i] + (from.rgba[i] - to.rgba[i]) * (1 - pos)
+ );
+ }
+ return 'rgba(' + rgba.join(',') + ')';
+ }
+
+ // Set the default map navigation options
+ defaultOptions.mapNavigation = {
+ 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
+ }
+ }
+ // enableButtons: false,
+ // enableTouchZoom: false,
+ // zoomOnDoubleClick: false,
+ // zoomOnMouseWheel: false
+
+ };
+
+ /**
+ * Utility for reading SVG paths directly.
+ */
+ Highcharts.splitPath = function (path) {
+ var i;
+
+ // Move letters apart
+ path = path.replace(/([A-Za-z])/g, ' $1 ');
+ // Trim
+ path = path.replace(/^\s*/, "").replace(/\s*$/, "");
+
+ // Split on spaces and commas
+ path = path.split(/[ ,]+/);
+
+ // Parse numbers
+ for (i = 0; i < path.length; i++) {
+ if (!/[a-zA-Z]/.test(path[i])) {
+ path[i] = parseFloat(path[i]);
+ }
+ }
+ return path;
+ };
+
+ // A placeholder for map definitions
+ Highcharts.maps = {};
+
+ /**
+ * Override to use the extreme coordinates from the SVG shape, not the
+ * data values
+ */
+ wrap(Axis.prototype, 'getSeriesExtremes', function (proceed) {
+ var isXAxis = this.isXAxis,
+ dataMin,
+ dataMax,
+ xData = [];
+
+ // Remove the xData array and cache it locally so that the proceed method doesn't use it
+ each(this.series, function (series, i) {
+ if (series.useMapGeometry) {
+ xData[i] = series.xData;
+ series.xData = [];
+ }
+ });
+
+ // Call base to reach normal cartesian series (like mappoint)
+ proceed.call(this);
+
+ // Run extremes logic for map and mapline
+ dataMin = pick(this.dataMin, Number.MAX_VALUE);
+ dataMax = pick(this.dataMax, Number.MIN_VALUE);
+ each(this.series, function (series, i) {
+ if (series.useMapGeometry) {
+ dataMin = Math.min(dataMin, series[isXAxis ? 'minX' : 'minY']);
+ dataMax = Math.max(dataMax, series[isXAxis ? 'maxX' : 'maxY']);
+ series.xData = xData[i]; // Reset xData array
+ }
+ });
+
+ this.dataMin = dataMin;
+ this.dataMax = dataMax;
+ });
+
+ /**
+ * Override axis translation to make sure the aspect ratio is always kept
+ */
+ wrap(Axis.prototype, 'setAxisTranslation', function (proceed) {
+ var chart = this.chart,
+ mapRatio,
+ plotRatio = chart.plotWidth / chart.plotHeight,
+ isXAxis = this.isXAxis,
+ adjustedAxisLength,
+ xAxis = chart.xAxis[0],
+ padAxis;
+
+ // Run the parent method
+ proceed.call(this);
+
+ // On Y axis, handle both
+ if (chart.options.chart.type === 'map' && !isXAxis && xAxis.transA !== UNDEFINED) {
+
+ // Use the same translation for both axes
+ this.transA = xAxis.transA = Math.min(this.transA, xAxis.transA);
+
+ mapRatio = (xAxis.max - xAxis.min) / (this.max - this.min);
+
+ // What axis to pad to put the map in the middle
+ padAxis = mapRatio > plotRatio ? this : xAxis;
+
+ // Pad it
+ adjustedAxisLength = (padAxis.max - padAxis.min) * padAxis.transA;
+ padAxis.minPixelPadding = (padAxis.len - adjustedAxisLength) / 2;
+ }
+ });
+
+
+ //--- Start zooming and panning features
+
+ wrap(Chart.prototype, 'render', function (proceed) {
+ var chart = this,
+ mapNavigation = chart.options.mapNavigation;
+
+ proceed.call(chart);
+
+ // Render the plus and minus buttons
+ chart.renderMapNavigation();
+
+ // Add the double click event
+ if (mapNavigation.zoomOnDoubleClick) {
+ Highcharts.addEvent(chart.container, 'dblclick', function (e) {
+ chart.pointer.onContainerDblClick(e);
+ });
+ }
+
+ // Add the mousewheel event
+ if (mapNavigation.zoomOnMouseWheel) {
+ Highcharts.addEvent(chart.container, document.onmousewheel === undefined ? 'DOMMouseScroll' : 'mousewheel', function (e) {
+ chart.pointer.onContainerMouseWheel(e);
+ });
+ }
+ });
+
+ // Extend the Pointer
+ extend(Pointer.prototype, {
+
+ /**
+ * The event handler for the doubleclick event
+ */
+ onContainerDblClick: function (e) {
+ var chart = this.chart;
+
+ e = this.normalize(e);
+
+ if (chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) {
+ chart.mapZoom(
+ 0.5,
+ chart.xAxis[0].toValue(e.chartX),
+ chart.yAxis[0].toValue(e.chartY)
+ );
+ }
+ },
+
+ /**
+ * The event handler for the mouse scroll event
+ */
+ onContainerMouseWheel: function (e) {
+ var chart = this.chart,
+ delta;
+
+ e = this.normalize(e);
+
+ // Firefox uses e.detail, WebKit and IE uses wheelDelta
+ delta = e.detail || -(e.wheelDelta / 120);
+ if (chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) {
+ chart.mapZoom(
+ delta > 0 ? 2 : 0.5,
+ chart.xAxis[0].toValue(e.chartX),
+ chart.yAxis[0].toValue(e.chartY)
+ );
+ }
+ }
+ });
+ // Implement the pinchType option
+ wrap(Pointer.prototype, 'init', function (proceed, chart, options) {
+
+ proceed.call(this, chart, options);
+
+ // Pinch status
+ if (options.mapNavigation.enableTouchZoom) {
+ this.pinchX = this.pinchHor =
+ this.pinchY = this.pinchVert = true;
+ }
+ });
+
+ // Add events to the Chart object itself
+ extend(Chart.prototype, {
+ renderMapNavigation: function () {
+ var chart = this,
+ options = this.options.mapNavigation,
+ buttons = options.buttons,
+ n,
+ button,
+ buttonOptions,
+ outerHandler = function () {
+ this.handler.call(chart);
+ };
+
+ if (options.enableButtons) {
+ for (n in buttons) {
+ if (buttons.hasOwnProperty(n)) {
+ buttonOptions = merge(options.buttonOptions, buttons[n]);
+
+ button = chart.renderer.button(buttonOptions.text, 0, 0, outerHandler)
+ .attr({
+ width: buttonOptions.width,
+ height: buttonOptions.height
+ })
+ .css(buttonOptions.style)
+ .add();
+ button.handler = buttonOptions.onclick;
+ button.align(extend(buttonOptions, { width: button.width, height: button.height }), null, 'spacingBox');
+ }
+ }
+ }
+ },
+
+ /**
+ * Fit an inner box to an outer. If the inner box overflows left or right, align it to the sides of the
+ * outer. If it overflows both sides, fit it within the outer. This is a pattern that occurs more places
+ * in Highcharts, perhaps it should be elevated to a common utility function.
+ */
+ fitToBox: function (inner, outer) {
+ each([['x', 'width'], ['y', 'height']], function (dim) {
+ var pos = dim[0],
+ size = dim[1];
+ if (inner[pos] + inner[size] > outer[pos] + outer[size]) { // right overflow
+ if (inner[size] > outer[size]) { // the general size is greater, fit fully to outer
+ inner[size] = outer[size];
+ inner[pos] = outer[pos];
+ } else { // align right
+ inner[pos] = outer[pos] + outer[size] - inner[size];
+ }
+ }
+ if (inner[size] > outer[size]) {
+ inner[size] = outer[size];
+ }
+ if (inner[pos] < outer[pos]) {
+ inner[pos] = outer[pos];
+ }
+
+ });
+
+ return inner;
+ },
+
+ /**
+ * Zoom the map in or out by a certain amount. Less than 1 zooms in, greater than 1 zooms out.
+ */
+ mapZoom: function (howMuch, centerXArg, centerYArg) {
+
+ if (this.isMapZooming) {
+ return;
+ }
+
+ var chart = this,
+ xAxis = chart.xAxis[0],
+ xRange = xAxis.max - xAxis.min,
+ centerX = pick(centerXArg, xAxis.min + xRange / 2),
+ newXRange = xRange * howMuch,
+ yAxis = chart.yAxis[0],
+ yRange = yAxis.max - yAxis.min,
+ centerY = pick(centerYArg, yAxis.min + yRange / 2),
+ newYRange = yRange * howMuch,
+ newXMin = centerX - newXRange / 2,
+ newYMin = centerY - newYRange / 2,
+ animation = pick(chart.options.chart.animation, true),
+ delay,
+ newExt = chart.fitToBox({
+ x: newXMin,
+ y: newYMin,
+ width: newXRange,
+ height: newYRange
+ }, {
+ x: xAxis.dataMin,
+ y: yAxis.dataMin,
+ width: xAxis.dataMax - xAxis.dataMin,
+ height: yAxis.dataMax - yAxis.dataMin
+ });
+
+ xAxis.setExtremes(newExt.x, newExt.x + newExt.width, false);
+ yAxis.setExtremes(newExt.y, newExt.y + newExt.height, false);
+
+ // Prevent zooming until this one is finished animating
+ delay = animation ? animation.duration || 500 : 0;
+ if (delay) {
+ chart.isMapZooming = true;
+ setTimeout(function () {
+ chart.isMapZooming = false;
+ }, delay);
+ }
+
+ chart.redraw();
+ }
+ });
+
+ /**
+ * Extend the default options with map options
+ */
+ plotOptions.map = merge(plotOptions.scatter, {
+ animation: false, // makes the complex shapes slow
+ nullColor: '#F8F8F8',
+ borderColor: 'silver',
+ borderWidth: 1,
+ marker: null,
+ stickyTracking: false,
+ dataLabels: {
+ verticalAlign: 'middle'
+ },
+ turboThreshold: 0,
+ tooltip: {
+ followPointer: true,
+ pointFormat: '{point.name}: {point.y}<br/>'
+ },
+ states: {
+ normal: {
+ animation: true
+ }
+ }
+ });
+
+ var MapAreaPoint = Highcharts.extendClass(Point, {
+ /**
+ * Extend the Point object to split paths
+ */
+ applyOptions: function (options, x) {
+
+ var point = Point.prototype.applyOptions.call(this, options, x);
+
+ if (point.path && typeof point.path === 'string') {
+ point.path = point.options.path = Highcharts.splitPath(point.path);
+ }
+
+ return point;
+ },
+ /**
+ * Stop the fade-out
+ */
+ onMouseOver: function () {
+ clearTimeout(this.colorInterval);
+ Point.prototype.onMouseOver.call(this);
+ },
+ /**
+ * Custom animation for tweening out the colors. Animation reduces blinking when hovering
+ * over islands and coast lines. We run a custom implementation of animation becuase we
+ * need to be able to run this independently from other animations like zoom redraw. Also,
+ * adding color animation to the adapters would introduce almost the same amount of code.
+ */
+ onMouseOut: function () {
+ var point = this,
+ start = +new Date(),
+ normalColor = Color(point.options.color),
+ hoverColor = Color(point.pointAttr.hover.fill),
+ animation = point.series.options.states.normal.animation,
+ duration = animation && (animation.duration || 500);
+
+ if (duration && normalColor.rgba.length === 4 && hoverColor.rgba.length === 4) {
+ delete point.pointAttr[''].fill; // avoid resetting it in Point.setState
+
+ clearTimeout(point.colorInterval);
+ point.colorInterval = setInterval(function () {
+ var pos = (new Date() - start) / duration,
+ graphic = point.graphic;
+ if (pos > 1) {
+ pos = 1;
+ }
+ if (graphic) {
+ graphic.attr('fill', tweenColors(hoverColor, normalColor, pos));
+ }
+ if (pos >= 1) {
+ clearTimeout(point.colorInterval);
+ }
+ }, 13);
+ }
+ Point.prototype.onMouseOut.call(point);
+ }
+ });
+
+ /**
+ * Add the series type
+ */
+ seriesTypes.map = Highcharts.extendClass(seriesTypes.scatter, {
+ type: 'map',
+ pointAttrToOptions: { // mapping between SVG attributes and the corresponding options
+ stroke: 'borderColor',
+ 'stroke-width': 'borderWidth',
+ fill: 'color'
+ },
+ colorKey: 'y',
+ pointClass: MapAreaPoint,
+ trackerGroups: ['group', 'markerGroup', 'dataLabelsGroup'],
+ getSymbol: noop,
+ supportsDrilldown: true,
+ getExtremesFromAll: true,
+ useMapGeometry: true, // get axis extremes from paths, not values
+ init: function (chart) {
+ var series = this,
+ valueDecimals = chart.options.legend.valueDecimals,
+ legendItems = [],
+ name,
+ from,
+ to,
+ fromLabel,
+ toLabel,
+ colorRange,
+ valueRanges,
+ gradientColor,
+ grad,
+ tmpLabel,
+ horizontal = chart.options.legend.layout === 'horizontal';
+
+
+ Highcharts.Series.prototype.init.apply(this, arguments);
+ colorRange = series.options.colorRange;
+ valueRanges = series.options.valueRanges;
+
+ if (valueRanges) {
+ each(valueRanges, function (range) {
+ from = range.from;
+ to = range.to;
+
+ // Assemble the default name. This can be overridden by legend.options.labelFormatter
+ name = '';
+ if (from === UNDEFINED) {
+ name = '< ';
+ } else if (to === UNDEFINED) {
+ name = '> ';
+ }
+ if (from !== UNDEFINED) {
+ name += numberFormat(from, valueDecimals);
+ }
+ if (from !== UNDEFINED && to !== UNDEFINED) {
+ name += ' - ';
+ }
+ if (to !== UNDEFINED) {
+ name += numberFormat(to, valueDecimals);
+ }
+
+ // Add a mock object to the legend items
+ legendItems.push(Highcharts.extend({
+ chart: series.chart,
+ name: name,
+ options: {},
+ drawLegendSymbol: seriesTypes.area.prototype.drawLegendSymbol,
+ visible: true,
+ setState: function () {},
+ setVisible: function () {}
+ }, range));
+ });
+ series.legendItems = legendItems;
+
+ } else if (colorRange) {
+
+ from = colorRange.from;
+ to = colorRange.to;
+ fromLabel = colorRange.fromLabel;
+ toLabel = colorRange.toLabel;
+
+ // Flips linearGradient variables and label text.
+ grad = horizontal ? [0, 0, 1, 0] : [0, 1, 0, 0];
+ if (!horizontal) {
+ tmpLabel = fromLabel;
+ fromLabel = toLabel;
+ toLabel = tmpLabel;
+ }
+
+ // Creates color gradient.
+ gradientColor = {
+ linearGradient: { x1: grad[0], y1: grad[1], x2: grad[2], y2: grad[3] },
+ stops:
+ [
+ [0, from],
+ [1, to]
+ ]
+ };
+
+ // Add a mock object to the legend items.
+ legendItems = [{
+ chart: series.chart,
+ options: {},
+ fromLabel: fromLabel,
+ toLabel: toLabel,
+ color: gradientColor,
+ drawLegendSymbol: this.drawLegendSymbolGradient,
+ visible: true,
+ setState: function () {},
+ setVisible: function () {}
+ }];
+
+ series.legendItems = legendItems;
+ }
+ },
+
+ /**
+ * If neither valueRanges nor colorRanges are defined, use basic area symbol.
+ */
+ drawLegendSymbol: seriesTypes.area.prototype.drawLegendSymbol,
+
+ /**
+ * Gets the series' symbol in the legend and extended legend with more information.
+ *
+ * @param {Object} legend The legend object
+ * @param {Object} item The series (this) or point
+ */
+ drawLegendSymbolGradient: function (legend, item) {
+ var spacing = legend.options.symbolPadding,
+ padding = pick(legend.options.padding, 8),
+ positionY,
+ positionX,
+ gradientSize = this.chart.renderer.fontMetrics(legend.options.itemStyle.fontSize).h,
+ horizontal = legend.options.layout === 'horizontal',
+ box1,
+ box2,
+ box3,
+ rectangleLength = pick(legend.options.rectangleLength, 200);
+
+ // Set local variables based on option.
+ if (horizontal) {
+ positionY = -(spacing / 2);
+ positionX = 0;
+ } else {
+ positionY = -rectangleLength + legend.baseline - (spacing / 2);
+ positionX = padding + gradientSize;
+ }
+
+ // Creates the from text.
+ item.fromText = this.chart.renderer.text(
+ item.fromLabel, // Text.
+ positionX, // Lower left x.
+ positionY // Lower left y.
+ ).attr({
+ zIndex: 2
+ }).add(item.legendGroup);
+ box1 = item.fromText.getBBox();
+
+ // Creates legend symbol.
+ // Ternary changes variables based on option.
+ item.legendSymbol = this.chart.renderer.rect(
+ horizontal ? box1.x + box1.width + spacing : box1.x - gradientSize - spacing, // Upper left x.
+ box1.y, // Upper left y.
+ horizontal ? rectangleLength : gradientSize, // Width.
+ horizontal ? gradientSize : rectangleLength, // Height.
+ 2 // Corner radius.
+ ).attr({
+ zIndex: 1
+ }).add(item.legendGroup);
+ box2 = item.legendSymbol.getBBox();
+
+ // Creates the to text.
+ // Vertical coordinate changed based on option.
+ item.toText = this.chart.renderer.text(
+ item.toLabel,
+ box2.x + box2.width + spacing,
+ horizontal ? positionY : box2.y + box2.height - spacing
+ ).attr({
+ zIndex: 2
+ }).add(item.legendGroup);
+ box3 = item.toText.getBBox();
+
+ // Changes legend box settings based on option.
+ if (horizontal) {
+ legend.offsetWidth = box1.width + box2.width + box3.width + (spacing * 2) + padding;
+ legend.itemY = gradientSize + padding;
+ } else {
+ legend.offsetWidth = Math.max(box1.width, box3.width) + (spacing) + box2.width + padding;
+ legend.itemY = box2.height + padding;
+ legend.itemX = spacing;
+ }
+ },
+
+ /**
+ * Get the bounding box of all paths in the map combined.
+ */
+ getBox: function (paths) {
+ var maxX = Number.MIN_VALUE,
+ minX = Number.MAX_VALUE,
+ maxY = Number.MIN_VALUE,
+ minY = Number.MAX_VALUE;
+
+
+ // Find the bounding box
+ each(paths || this.options.data, function (point) {
+ var path = point.path,
+ i = path.length,
+ even = false, // while loop reads from the end
+ pointMaxX = Number.MIN_VALUE,
+ pointMinX = Number.MAX_VALUE,
+ pointMaxY = Number.MIN_VALUE,
+ pointMinY = Number.MAX_VALUE;
+
+ while (i--) {
+ if (typeof path[i] === 'number' && !isNaN(path[i])) {
+ if (even) { // even = x
+ pointMaxX = Math.max(pointMaxX, path[i]);
+ pointMinX = Math.min(pointMinX, path[i]);
+ } else { // odd = Y
+ pointMaxY = Math.max(pointMaxY, path[i]);
+ pointMinY = Math.min(pointMinY, path[i]);
+ }
+ even = !even;
+ }
+ }
+ // Cache point bounding box for use to position data labels
+ point._maxX = pointMaxX;
+ point._minX = pointMinX;
+ point._maxY = pointMaxY;
+ point._minY = pointMinY;
+
+ maxX = Math.max(maxX, pointMaxX);
+ minX = Math.min(minX, pointMinX);
+ maxY = Math.max(maxY, pointMaxY);
+ minY = Math.min(minY, pointMinY);
+ });
+ this.minY = minY;
+ this.maxY = maxY;
+ this.minX = minX;
+ this.maxX = maxX;
+
+ },
+
+
+
+ /**
+ * Translate the path so that it automatically fits into the plot area box
+ * @param {Object} path
+ */
+ translatePath: function (path) {
+
+ var series = this,
+ even = false, // while loop reads from the end
+ xAxis = series.xAxis,
+ yAxis = series.yAxis,
+ i;
+
+ // Preserve the original
+ path = [].concat(path);
+
+ // Do the translation
+ i = path.length;
+ while (i--) {
+ if (typeof path[i] === 'number') {
+ if (even) { // even = x
+ path[i] = Math.round(xAxis.translate(path[i]));
+ } else { // odd = Y
+ path[i] = Math.round(yAxis.len - yAxis.translate(path[i]));
+ }
+ even = !even;
+ }
+ }
+ return path;
+ },
+
+ setData: function () {
+ Highcharts.Series.prototype.setData.apply(this, arguments);
+ this.getBox();
+ },
+
+ /**
+ * Add the path option for data points. Find the max value for color calculation.
+ */
+ translate: function () {
+ var series = this,
+ dataMin = Number.MAX_VALUE,
+ dataMax = Number.MIN_VALUE;
+
+ series.generatePoints();
+
+ each(series.data, function (point) {
+
+ point.shapeType = 'path';
+ point.shapeArgs = {
+ d: series.translatePath(point.path)
+ };
+
+ // TODO: do point colors in drawPoints instead of point.init
+ if (typeof point.y === 'number') {
+ if (point.y > dataMax) {
+ dataMax = point.y;
+ } else if (point.y < dataMin) {
+ dataMin = point.y;
+ }
+ }
+ });
+
+ series.translateColors(dataMin, dataMax);
+ },
+
+ /**
+ * In choropleth maps, the color is a result of the value, so this needs translation too
+ */
+ translateColors: function (dataMin, dataMax) {
+
+ var seriesOptions = this.options,
+ valueRanges = seriesOptions.valueRanges,
+ colorRange = seriesOptions.colorRange,
+ colorKey = this.colorKey,
+ from,
+ to;
+
+ if (colorRange) {
+ from = Color(colorRange.from);
+ to = Color(colorRange.to);
+ }
+
+ each(this.data, function (point) {
+ var value = point[colorKey],
+ range,
+ color,
+ i,
+ pos;
+
+ if (valueRanges) {
+ i = valueRanges.length;
+ while (i--) {
+ range = valueRanges[i];
+ from = range.from;
+ to = range.to;
+ if ((from === UNDEFINED || value >= from) && (to === UNDEFINED || value <= to)) {
+ color = range.color;
+ break;
+ }
+
+ }
+ } else if (colorRange && value !== undefined) {
+
+ pos = 1 - ((dataMax - value) / (dataMax - dataMin));
+ color = value === null ? seriesOptions.nullColor : tweenColors(from, to, pos);
+ }
+
+ if (color) {
+ point.color = null; // reset from previous drilldowns, use of the same data options
+ point.options.color = color;
+ }
+ });
+ },
+
+ drawGraph: noop,
+
+ /**
+ * We need the points' bounding boxes in order to draw the data labels, so
+ * we skip it now and call if from drawPoints instead.
+ */
+ drawDataLabels: noop,
+
+ /**
+ * Use the drawPoints method of column, that is able to handle simple shapeArgs.
+ * Extend it by assigning the tooltip position.
+ */
+ drawPoints: function () {
+ var series = this,
+ xAxis = series.xAxis,
+ yAxis = series.yAxis,
+ colorKey = series.colorKey;
+
+ // Make points pass test in drawing
+ each(series.data, function (point) {
+ point.plotY = 1; // pass null test in column.drawPoints
+ if (point[colorKey] === null) {
+ point[colorKey] = 0;
+ point.isNull = true;
+ }
+ });
+
+ // Draw them
+ seriesTypes.column.prototype.drawPoints.apply(series);
+
+ each(series.data, function (point) {
+
+ var dataLabels = point.dataLabels,
+ minX = xAxis.toPixels(point._minX, true),
+ maxX = xAxis.toPixels(point._maxX, true),
+ minY = yAxis.toPixels(point._minY, true),
+ maxY = yAxis.toPixels(point._maxY, true);
+
+ point.plotX = Math.round(minX + (maxX - minX) * pick(dataLabels && dataLabels.anchorX, 0.5));
+ point.plotY = Math.round(minY + (maxY - minY) * pick(dataLabels && dataLabels.anchorY, 0.5));
+
+
+ // Reset escaped null points
+ if (point.isNull) {
+ point[colorKey] = null;
+ }
+ });
+
+ // Now draw the data labels
+ Highcharts.Series.prototype.drawDataLabels.call(series);
+
+ },
+
+ /**
+ * Animate in the new series from the clicked point in the old series.
+ * Depends on the drilldown.js module
+ */
+ animateDrilldown: function (init) {
+ var toBox = this.chart.plotBox,
+ level = this.chart.drilldownLevels[this.chart.drilldownLevels.length - 1],
+ fromBox = level.bBox,
+ animationOptions = this.chart.options.drilldown.animation,
+ scale;
+
+ if (!init) {
+
+ scale = Math.min(fromBox.width / toBox.width, fromBox.height / toBox.height);
+ level.shapeArgs = {
+ scaleX: scale,
+ scaleY: scale,
+ translateX: fromBox.x,
+ translateY: fromBox.y
+ };
+
+ // TODO: Animate this.group instead
+ each(this.points, function (point) {
+
+ point.graphic
+ .attr(level.shapeArgs)
+ .animate({
+ scaleX: 1,
+ scaleY: 1,
+ translateX: 0,
+ translateY: 0
+ }, animationOptions);
+
+ });
+
+ delete this.animate;
+ }
+
+ },
+
+ /**
+ * When drilling up, pull out the individual point graphics from the lower series
+ * and animate them into the origin point in the upper series.
+ */
+ animateDrillupFrom: function (level) {
+ seriesTypes.column.prototype.animateDrillupFrom.call(this, level);
+ },
+
+
+ /**
+ * When drilling up, keep the upper series invisible until the lower series has
+ * moved into place
+ */
+ animateDrillupTo: function (init) {
+ seriesTypes.column.prototype.animateDrillupTo.call(this, init);
+ }
+ });
+
+
+ // The mapline series type
+ plotOptions.mapline = merge(plotOptions.map, {
+ lineWidth: 1,
+ backgroundColor: 'none'
+ });
+ seriesTypes.mapline = Highcharts.extendClass(seriesTypes.map, {
+ type: 'mapline',
+ pointAttrToOptions: { // mapping between SVG attributes and the corresponding options
+ stroke: 'color',
+ 'stroke-width': 'lineWidth',
+ fill: 'backgroundColor'
+ },
+ drawLegendSymbol: seriesTypes.line.prototype.drawLegendSymbol
+ });
+
+ // The mappoint series type
+ plotOptions.mappoint = merge(plotOptions.scatter, {
+ dataLabels: {
+ enabled: true,
+ format: '{point.name}',
+ color: 'black',
+ style: {
+ textShadow: '0 0 5px white'
+ }
+ }
+ });
+ seriesTypes.mappoint = Highcharts.extendClass(seriesTypes.scatter, {
+ type: 'mappoint'
+ });
+
+
+
+ /**
+ * A wrapper for Chart with all the default values for a Map
+ */
+ Highcharts.Map = function (options, callback) {
+
+ var hiddenAxis = {
+ endOnTick: false,
+ gridLineWidth: 0,
+ labels: {
+ enabled: false
+ },
+ lineWidth: 0,
+ minPadding: 0,
+ maxPadding: 0,
+ startOnTick: false,
+ tickWidth: 0,
+ title: null
+ },
+ seriesOptions;
+
+ // Don't merge the data
+ seriesOptions = options.series;
+ options.series = null;
+
+ options = merge({
+ chart: {
+ type: 'map',
+ panning: 'xy'
+ },
+ xAxis: hiddenAxis,
+ yAxis: merge(hiddenAxis, { reversed: true })
+ },
+ options, // user's options
+
+ { // forced options
+ chart: {
+ inverted: false
+ }
+ });
+
+ options.series = seriesOptions;
+
+
+ return new Highcharts.Chart(options, callback);
+ };
+}(Highcharts));
--
Gitblit v1.9.3