544 lines
18 KiB
JavaScript
544 lines
18 KiB
JavaScript
/* *
|
|
*
|
|
* (c) 2010-2021 Torstein Honsi
|
|
*
|
|
* License: www.highcharts.com/license
|
|
*
|
|
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
*
|
|
* */
|
|
'use strict';
|
|
var __extends = (this && this.__extends) || (function () {
|
|
var extendStatics = function (d, b) {
|
|
extendStatics = Object.setPrototypeOf ||
|
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
return extendStatics(d, b);
|
|
};
|
|
return function (d, b) {
|
|
if (typeof b !== "function" && b !== null)
|
|
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
extendStatics(d, b);
|
|
function __() { this.constructor = d; }
|
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
};
|
|
})();
|
|
import Series from '../../Core/Series/Series.js';
|
|
import SeriesRegistry from '../../Core/Series/SeriesRegistry.js';
|
|
import U from '../../Core/Utilities.js';
|
|
var defined = U.defined, merge = U.merge;
|
|
/* *
|
|
*
|
|
* Class
|
|
*
|
|
* */
|
|
/**
|
|
* The line series is the base type and is therefor the series base prototype.
|
|
*
|
|
* @private
|
|
*/
|
|
var LineSeries = /** @class */ (function (_super) {
|
|
__extends(LineSeries, _super);
|
|
function LineSeries() {
|
|
/* *
|
|
*
|
|
* Static Functions
|
|
*
|
|
* */
|
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
/* *
|
|
*
|
|
* Properties
|
|
*
|
|
* */
|
|
_this.data = void 0;
|
|
_this.options = void 0;
|
|
_this.points = void 0;
|
|
return _this;
|
|
}
|
|
/* *
|
|
*
|
|
* Functions
|
|
*
|
|
* */
|
|
/**
|
|
* Draw the graph. Called internally when rendering line-like series
|
|
* types. The first time it generates the `series.graph` item and
|
|
* optionally other series-wide items like `series.area` for area
|
|
* charts. On subsequent calls these items are updated with new
|
|
* positions and attributes.
|
|
*
|
|
* @function Highcharts.Series#drawGraph
|
|
*/
|
|
LineSeries.prototype.drawGraph = function () {
|
|
var series = this, options = this.options, graphPath = (this.gappedPath || this.getGraphPath).call(this), styledMode = this.chart.styledMode;
|
|
var props = [[
|
|
'graph',
|
|
'highcharts-graph'
|
|
]];
|
|
// Presentational properties
|
|
if (!styledMode) {
|
|
props[0].push((options.lineColor ||
|
|
this.color ||
|
|
"#cccccc" /* Palette.neutralColor20 */ // when colorByPoint = true
|
|
), options.dashStyle);
|
|
}
|
|
props = series.getZonesGraphs(props);
|
|
// Draw the graph
|
|
props.forEach(function (prop, i) {
|
|
var graphKey = prop[0];
|
|
var attribs, graph = series[graphKey];
|
|
var verb = graph ? 'animate' : 'attr';
|
|
if (graph) {
|
|
graph.endX = series.preventGraphAnimation ?
|
|
null :
|
|
graphPath.xMap;
|
|
graph.animate({ d: graphPath });
|
|
}
|
|
else if (graphPath.length) { // #1487
|
|
/**
|
|
* SVG element of area-based charts. Can be used for styling
|
|
* purposes. If zones are configured, this element will be
|
|
* hidden and replaced by multiple zone areas, accessible
|
|
* via `series['zone-area-x']` (where x is a number,
|
|
* starting with 0).
|
|
*
|
|
* @name Highcharts.Series#area
|
|
* @type {Highcharts.SVGElement|undefined}
|
|
*/
|
|
/**
|
|
* SVG element of line-based charts. Can be used for styling
|
|
* purposes. If zones are configured, this element will be
|
|
* hidden and replaced by multiple zone lines, accessible
|
|
* via `series['zone-graph-x']` (where x is a number,
|
|
* starting with 0).
|
|
*
|
|
* @name Highcharts.Series#graph
|
|
* @type {Highcharts.SVGElement|undefined}
|
|
*/
|
|
series[graphKey] = graph = series.chart.renderer
|
|
.path(graphPath)
|
|
.addClass(prop[1])
|
|
.attr({ zIndex: 1 }) // #1069
|
|
.add(series.group);
|
|
}
|
|
if (graph && !styledMode) {
|
|
attribs = {
|
|
'stroke': prop[2],
|
|
'stroke-width': options.lineWidth,
|
|
// Polygon series use filled graph
|
|
'fill': (series.fillGraph && series.color) || 'none'
|
|
};
|
|
if (prop[3]) {
|
|
attribs.dashstyle = prop[3];
|
|
}
|
|
else if (options.linecap !== 'square') {
|
|
attribs['stroke-linecap'] =
|
|
attribs['stroke-linejoin'] = 'round';
|
|
}
|
|
graph[verb](attribs)
|
|
// Add shadow to normal series (0) or to first
|
|
// zone (1) #3932
|
|
.shadow((i < 2) && options.shadow);
|
|
}
|
|
// Helpers for animation
|
|
if (graph) {
|
|
graph.startX = graphPath.xMap;
|
|
graph.isArea = graphPath.isArea; // For arearange animation
|
|
}
|
|
});
|
|
};
|
|
// eslint-disable-next-line valid-jsdoc
|
|
/**
|
|
* Get the graph path.
|
|
*
|
|
* @private
|
|
*/
|
|
LineSeries.prototype.getGraphPath = function (points, nullsAsZeroes, connectCliffs) {
|
|
var series = this, options = series.options, graphPath = [], xMap = [];
|
|
var gap, step = options.step;
|
|
points = points || series.points;
|
|
// Bottom of a stack is reversed
|
|
var reversed = points.reversed;
|
|
if (reversed) {
|
|
points.reverse();
|
|
}
|
|
// Reverse the steps (#5004)
|
|
step = {
|
|
right: 1,
|
|
center: 2
|
|
}[step] || (step && 3);
|
|
if (step && reversed) {
|
|
step = 4 - step;
|
|
}
|
|
// Remove invalid points, especially in spline (#5015)
|
|
points = this.getValidPoints(points, false, !(options.connectNulls && !nullsAsZeroes && !connectCliffs));
|
|
// Build the line
|
|
points.forEach(function (point, i) {
|
|
var plotX = point.plotX, plotY = point.plotY, lastPoint = points[i - 1];
|
|
// the path to this point from the previous
|
|
var pathToPoint;
|
|
if ((point.leftCliff || (lastPoint && lastPoint.rightCliff)) &&
|
|
!connectCliffs) {
|
|
gap = true; // ... and continue
|
|
}
|
|
// Line series, nullsAsZeroes is not handled
|
|
if (point.isNull && !defined(nullsAsZeroes) && i > 0) {
|
|
gap = !options.connectNulls;
|
|
// Area series, nullsAsZeroes is set
|
|
}
|
|
else if (point.isNull && !nullsAsZeroes) {
|
|
gap = true;
|
|
}
|
|
else {
|
|
if (i === 0 || gap) {
|
|
pathToPoint = [[
|
|
'M',
|
|
point.plotX,
|
|
point.plotY
|
|
]];
|
|
// Generate the spline as defined in the SplineSeries object
|
|
}
|
|
else if (series.getPointSpline) {
|
|
pathToPoint = [series.getPointSpline(points, point, i)];
|
|
}
|
|
else if (step) {
|
|
if (step === 1) { // right
|
|
pathToPoint = [[
|
|
'L',
|
|
lastPoint.plotX,
|
|
plotY
|
|
]];
|
|
}
|
|
else if (step === 2) { // center
|
|
pathToPoint = [[
|
|
'L',
|
|
(lastPoint.plotX + plotX) / 2,
|
|
lastPoint.plotY
|
|
], [
|
|
'L',
|
|
(lastPoint.plotX + plotX) / 2,
|
|
plotY
|
|
]];
|
|
}
|
|
else {
|
|
pathToPoint = [[
|
|
'L',
|
|
plotX,
|
|
lastPoint.plotY
|
|
]];
|
|
}
|
|
pathToPoint.push([
|
|
'L',
|
|
plotX,
|
|
plotY
|
|
]);
|
|
}
|
|
else {
|
|
// normal line to next point
|
|
pathToPoint = [[
|
|
'L',
|
|
plotX,
|
|
plotY
|
|
]];
|
|
}
|
|
// Prepare for animation. When step is enabled, there are
|
|
// two path nodes for each x value.
|
|
xMap.push(point.x);
|
|
if (step) {
|
|
xMap.push(point.x);
|
|
if (step === 2) { // step = center (#8073)
|
|
xMap.push(point.x);
|
|
}
|
|
}
|
|
graphPath.push.apply(graphPath, pathToPoint);
|
|
gap = false;
|
|
}
|
|
});
|
|
graphPath.xMap = xMap;
|
|
series.graphPath = graphPath;
|
|
return graphPath;
|
|
};
|
|
// eslint-disable-next-line valid-jsdoc
|
|
/**
|
|
* Get zones properties for building graphs. Extendable by series with
|
|
* multiple lines within one series.
|
|
*
|
|
* @private
|
|
*/
|
|
LineSeries.prototype.getZonesGraphs = function (props) {
|
|
// Add the zone properties if any
|
|
this.zones.forEach(function (zone, i) {
|
|
var propset = [
|
|
'zone-graph-' + i,
|
|
'highcharts-graph highcharts-zone-graph-' + i + ' ' +
|
|
(zone.className || '')
|
|
];
|
|
if (!this.chart.styledMode) {
|
|
propset.push((zone.color || this.color), (zone.dashStyle || this.options.dashStyle));
|
|
}
|
|
props.push(propset);
|
|
}, this);
|
|
return props;
|
|
};
|
|
/**
|
|
* General options for all series types.
|
|
*
|
|
* @optionparent plotOptions.series
|
|
*/
|
|
LineSeries.defaultOptions = merge(Series.defaultOptions, {
|
|
// nothing here yet
|
|
});
|
|
return LineSeries;
|
|
}(Series));
|
|
SeriesRegistry.registerSeriesType('line', LineSeries);
|
|
/* *
|
|
*
|
|
* Default Export
|
|
*
|
|
* */
|
|
export default LineSeries;
|
|
/* *
|
|
*
|
|
* API Options
|
|
*
|
|
* */
|
|
/**
|
|
* A line series displays information as a series of data points connected by
|
|
* straight line segments.
|
|
*
|
|
* @sample {highcharts} highcharts/demo/line-basic/
|
|
* Line chart
|
|
* @sample {highstock} stock/demo/basic-line/
|
|
* Line chart
|
|
*
|
|
* @extends plotOptions.series
|
|
* @product highcharts highstock
|
|
* @apioption plotOptions.line
|
|
*/
|
|
/**
|
|
* The SVG value used for the `stroke-linecap` and `stroke-linejoin`
|
|
* of a line graph. Round means that lines are rounded in the ends and
|
|
* bends.
|
|
*
|
|
* @type {Highcharts.SeriesLinecapValue}
|
|
* @default round
|
|
* @since 3.0.7
|
|
* @apioption plotOptions.line.linecap
|
|
*/
|
|
/**
|
|
* A `line` series. If the [type](#series.line.type) option is not
|
|
* specified, it is inherited from [chart.type](#chart.type).
|
|
*
|
|
* @extends series,plotOptions.line
|
|
* @excluding dataParser,dataURL
|
|
* @product highcharts highstock
|
|
* @apioption series.line
|
|
*/
|
|
/**
|
|
* An array of data points for the series. For the `line` series type,
|
|
* points can be given in the following ways:
|
|
*
|
|
* 1. An array of numerical values. In this case, the numerical values will be
|
|
* interpreted as `y` options. The `x` values will be automatically
|
|
* calculated, either starting at 0 and incremented by 1, or from
|
|
* `pointStart` and `pointInterval` given in the series options. If the axis
|
|
* has categories, these will be used. Example:
|
|
* ```js
|
|
* data: [0, 5, 3, 5]
|
|
* ```
|
|
*
|
|
* 2. An array of arrays with 2 values. In this case, the values correspond to
|
|
* `x,y`. If the first value is a string, it is applied as the name of the
|
|
* point, and the `x` value is inferred.
|
|
* ```js
|
|
* data: [
|
|
* [0, 1],
|
|
* [1, 2],
|
|
* [2, 8]
|
|
* ]
|
|
* ```
|
|
*
|
|
* 3. An array of objects with named values. The following snippet shows only a
|
|
* few settings, see the complete options set below. If the total number of
|
|
* data points exceeds the series'
|
|
* [turboThreshold](#series.line.turboThreshold),
|
|
* this option is not available.
|
|
* ```js
|
|
* data: [{
|
|
* x: 1,
|
|
* y: 9,
|
|
* name: "Point2",
|
|
* color: "#00FF00"
|
|
* }, {
|
|
* x: 1,
|
|
* y: 6,
|
|
* name: "Point1",
|
|
* color: "#FF00FF"
|
|
* }]
|
|
* ```
|
|
*
|
|
* **Note:** In TypeScript you have to extend `PointOptionsObject` with an
|
|
* additional declaration to allow custom data types:
|
|
* ```ts
|
|
* declare module `highcharts` {
|
|
* interface PointOptionsObject {
|
|
* custom: Record<string, (boolean|number|string)>;
|
|
* }
|
|
* }
|
|
* ```
|
|
*
|
|
* @sample {highcharts} highcharts/chart/reflow-true/
|
|
* Numerical values
|
|
* @sample {highcharts} highcharts/series/data-array-of-arrays/
|
|
* Arrays of numeric x and y
|
|
* @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
|
|
* Arrays of datetime x and y
|
|
* @sample {highcharts} highcharts/series/data-array-of-name-value/
|
|
* Arrays of point.name and y
|
|
* @sample {highcharts} highcharts/series/data-array-of-objects/
|
|
* Config objects
|
|
*
|
|
* @declare Highcharts.PointOptionsObject
|
|
* @type {Array<number|Array<(number|string),(number|null)>|null|*>}
|
|
* @apioption series.line.data
|
|
*/
|
|
/**
|
|
* An additional, individual class name for the data point's graphic
|
|
* representation.
|
|
*
|
|
* @type {string}
|
|
* @since 5.0.0
|
|
* @product highcharts gantt
|
|
* @apioption series.line.data.className
|
|
*/
|
|
/**
|
|
* Individual color for the point. By default the color is pulled from
|
|
* the global `colors` array.
|
|
*
|
|
* In styled mode, the `color` option doesn't take effect. Instead, use
|
|
* `colorIndex`.
|
|
*
|
|
* @sample {highcharts} highcharts/point/color/
|
|
* Mark the highest point
|
|
*
|
|
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
* @product highcharts highstock gantt
|
|
* @apioption series.line.data.color
|
|
*/
|
|
/**
|
|
* A specific color index to use for the point, so its graphic representations
|
|
* are given the class name `highcharts-color-{n}`. In styled mode this will
|
|
* change the color of the graphic. In non-styled mode, the color by is set by
|
|
* the `fill` attribute, so the change in class name won't have a visual effect
|
|
* by default.
|
|
*
|
|
* @type {number}
|
|
* @since 5.0.0
|
|
* @product highcharts gantt
|
|
* @apioption series.line.data.colorIndex
|
|
*/
|
|
/**
|
|
* A reserved subspace to store options and values for customized functionality.
|
|
* Here you can add additional data for your own event callbacks and formatter
|
|
* callbacks.
|
|
*
|
|
* @sample {highcharts} highcharts/point/custom/
|
|
* Point and series with custom data
|
|
*
|
|
* @type {Highcharts.Dictionary<*>}
|
|
* @apioption series.line.data.custom
|
|
*/
|
|
/**
|
|
* Individual data label for each point. The options are the same as
|
|
* the ones for [plotOptions.series.dataLabels](
|
|
* #plotOptions.series.dataLabels).
|
|
*
|
|
* @sample highcharts/point/datalabels/
|
|
* Show a label for the last value
|
|
*
|
|
* @declare Highcharts.DataLabelsOptions
|
|
* @extends plotOptions.line.dataLabels
|
|
* @product highcharts highstock gantt
|
|
* @apioption series.line.data.dataLabels
|
|
*/
|
|
/**
|
|
* A description of the point to add to the screen reader information
|
|
* about the point.
|
|
*
|
|
* @type {string}
|
|
* @since 5.0.0
|
|
* @requires modules/accessibility
|
|
* @apioption series.line.data.description
|
|
*/
|
|
/**
|
|
* An id for the point. This can be used after render time to get a
|
|
* pointer to the point object through `chart.get()`.
|
|
*
|
|
* @sample {highcharts} highcharts/point/id/
|
|
* Remove an id'd point
|
|
*
|
|
* @type {string}
|
|
* @since 1.2.0
|
|
* @product highcharts highstock gantt
|
|
* @apioption series.line.data.id
|
|
*/
|
|
/**
|
|
* The rank for this point's data label in case of collision. If two
|
|
* data labels are about to overlap, only the one with the highest `labelrank`
|
|
* will be drawn.
|
|
*
|
|
* @type {number}
|
|
* @apioption series.line.data.labelrank
|
|
*/
|
|
/**
|
|
* The name of the point as shown in the legend, tooltip, dataLabels, etc.
|
|
*
|
|
* @see [xAxis.uniqueNames](#xAxis.uniqueNames)
|
|
*
|
|
* @sample {highcharts} highcharts/series/data-array-of-objects/
|
|
* Point names
|
|
*
|
|
* @type {string}
|
|
* @apioption series.line.data.name
|
|
*/
|
|
/**
|
|
* Whether the data point is selected initially.
|
|
*
|
|
* @type {boolean}
|
|
* @default false
|
|
* @product highcharts highstock gantt
|
|
* @apioption series.line.data.selected
|
|
*/
|
|
/**
|
|
* The x value of the point. For datetime axes, the X value is the timestamp
|
|
* in milliseconds since 1970.
|
|
*
|
|
* @type {number}
|
|
* @product highcharts highstock
|
|
* @apioption series.line.data.x
|
|
*/
|
|
/**
|
|
* The y value of the point.
|
|
*
|
|
* @type {number|null}
|
|
* @product highcharts highstock
|
|
* @apioption series.line.data.y
|
|
*/
|
|
/**
|
|
* The individual point events.
|
|
*
|
|
* @extends plotOptions.series.point.events
|
|
* @product highcharts highstock gantt
|
|
* @apioption series.line.data.events
|
|
*/
|
|
/**
|
|
* Options for the point markers of line-like series.
|
|
*
|
|
* @declare Highcharts.PointMarkerOptionsObject
|
|
* @extends plotOptions.series.marker
|
|
* @product highcharts highstock
|
|
* @apioption series.line.data.marker
|
|
*/
|
|
''; // include precedent doclets in transpilat
|