1/* * 2 * 3 * (c) 2010-2024 Torstein Honsi 4 * 5 * License: www.highcharts.com/license 6 * 7 * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!! 8 * 9 * */ 10'use strict'; 11import Series from '../../Core/Series/Series.js'; 12import SeriesRegistry from '../../Core/Series/SeriesRegistry.js'; 13import U from '../../Core/Utilities.js'; 14const { defined, merge, isObject } = U; 15/* * 16 * 17 * Class 18 * 19 * */ 20/** 21 * The line series is the base type and is therefor the series base prototype. 22 * 23 * @private 24 */ 25class LineSeries extends Series { 26 /* * 27 * 28 * Functions 29 * 30 * */ 31 /** 32 * Draw the graph. Called internally when rendering line-like series 33 * types. The first time it generates the `series.graph` item and 34 * optionally other series-wide items like `series.area` for area 35 * charts. On subsequent calls these items are updated with new 36 * positions and attributes. 37 * 38 * @function Highcharts.Series#drawGraph 39 */ 40 drawGraph() { 41 const options = this.options, graphPath = (this.gappedPath || this.getGraphPath).call(this), styledMode = this.chart.styledMode; 42 // Draw the graph 43 [this, ...this.zones].forEach((owner, i) => { 44 let attribs, graph = owner.graph; 45 const verb = graph ? 'animate' : 'attr', dashStyle = owner.dashStyle || 46 options.dashStyle; 47 if (graph) { 48 graph.endX = this.preventGraphAnimation ? 49 null : 50 graphPath.xMap; 51 graph.animate({ d: graphPath }); 52 } 53 else if (graphPath.length) { // #1487 54 /** 55 * SVG element of line-based charts. Can be used for styling 56 * purposes. If zones are configured, this element will be 57 * hidden and replaced by multiple zone lines, accessible 58 * via `series.zones[i].graph`. 59 * 60 * @name Highcharts.Series#graph 61 * @type {Highcharts.SVGElement|undefined} 62 */ 63 owner.graph = graph = this.chart.renderer 64 .path(graphPath) 65 .addClass('highcharts-graph' + 66 (i ? ` highcharts-zone-graph-${i - 1} ` : ' ') + 67 ((i && owner.className) || '')) 68 .attr({ zIndex: 1 }) // #1069 69 .add(this.group); 70 } 71 if (graph && !styledMode) { 72 attribs = { 73 'stroke': ((!i && options.lineColor) || // Series only 74 owner.color || 75 this.color || 76 "#cccccc" /* Palette.neutralColor20 */), 77 'stroke-width': options.lineWidth || 0, 78 // Polygon series use filled graph 79 'fill': (this.fillGraph && this.color) || 'none' 80 }; 81 // Apply dash style 82 if (dashStyle) { 83 attribs.dashstyle = dashStyle; 84 // The reason for the `else if` is that linecaps don't mix well 85 // with dashstyle. The gaps get partially filled by the 86 // linecap. 87 } 88 else if (options.linecap !== 'square') { 89 attribs['stroke-linecap'] = 90 attribs['stroke-linejoin'] = 'round'; 91 } 92 graph[verb](attribs) 93 // Add shadow to normal series as well as zones 94 .shadow(options.shadow && 95 // If shadow is defined, call function with 96 // `filterUnits: 'userSpaceOnUse'` to avoid known 97 // SVG filter bug (#19093) 98 merge({ filterUnits: 'userSpaceOnUse' }, isObject(options.shadow) ? options.shadow : {})); 99 } 100 // Helpers for animation 101 if (graph) { 102 graph.startX = graphPath.xMap; 103 graph.isArea = graphPath.isArea; // For arearange animation 104 } 105 }); 106 } 107 // eslint-disable-next-line valid-jsdoc 108 /** 109 * Get the graph path. 110 * 111 * @private 112 */ 113 getGraphPath(points, nullsAsZeroes, connectCliffs) { 114 const series = this, options = series.options, graphPath = [], xMap = []; 115 let gap, step = options.step; 116 points = points || series.points; 117 // Bottom of a stack is reversed 118 const reversed = points.reversed; 119 if (reversed) { 120 points.reverse(); 121 } 122 // Reverse the steps (#5004) 123 step = { 124 right: 1, 125 center: 2 126 }[step] || (step && 3); 127 if (step && reversed) { 128 step = 4 - step; 129 } 130 // Remove invalid points, especially in spline (#5015) 131 points = this.getValidPoints(points, false, !(options.connectNulls && !nullsAsZeroes && !connectCliffs)); 132 // Build the line
vendor: 5,808 bytes, lines 133-312
133 points.forEach(function (point, i) { 134 const plotX = point.plotX, plotY = point.plotY, lastPoint = points[i - 1], isNull = point.isNull || typeof plotY !== 'number'; 135 // The path to this point from the previous 136 let pathToPoint; 137 if ((point.leftCliff || (lastPoint && lastPoint.rightCliff)) && 138 !connectCliffs) { 139 gap = true; // ... and continue 140 } 141 // Line series, nullsAsZeroes is not handled 142 if (isNull && !defined(nullsAsZeroes) && i > 0) { 143 gap = !options.connectNulls; 144 // Area series, nullsAsZeroes is set 145 } 146 else if (isNull && !nullsAsZeroes) { 147 gap = true; 148 } 149 else { 150 if (i === 0 || gap) { 151 pathToPoint = [[ 152 'M', 153 point.plotX, 154 point.plotY 155 ]]; 156 // Generate the spline as defined in the SplineSeries object 157 } 158 else if (series.getPointSpline) { 159 pathToPoint = [series.getPointSpline(points, point, i)]; 160 } 161 else if (step) { 162 if (step === 1) { // Right 163 pathToPoint = [[ 164 'L', 165 lastPoint.plotX, 166 plotY 167 ]]; 168 } 169 else if (step === 2) { // Center 170 pathToPoint = [[ 171 'L', 172 (lastPoint.plotX + plotX) / 2, 173 lastPoint.plotY 174 ], [ 175 'L', 176 (lastPoint.plotX + plotX) / 2, 177 plotY 178 ]]; 179 } 180 else { 181 pathToPoint = [[ 182 'L', 183 plotX, 184 lastPoint.plotY 185 ]]; 186 } 187 pathToPoint.push([ 188 'L', 189 plotX, 190 plotY 191 ]); 192 } 193 else { 194 // Normal line to next point 195 pathToPoint = [[ 196 'L', 197 plotX, 198 plotY 199 ]]; 200 } 201 // Prepare for animation. When step is enabled, there are 202 // two path nodes for each x value. 203 xMap.push(point.x); 204 if (step) { 205 xMap.push(point.x); 206 if (step === 2) { // Step = center (#8073) 207 xMap.push(point.x); 208 } 209 } 210 graphPath.push.apply(graphPath, pathToPoint); 211 gap = false; 212 } 213 }); 214 graphPath.xMap = xMap; 215 series.graphPath = graphPath; 216 return graphPath; 217 } 218} 219/* * 220 * 221 * Static Functions 222 * 223 * */ 224LineSeries.defaultOptions = merge(Series.defaultOptions, 225/** 226 * General options for all series types. 227 * 228 * @optionparent plotOptions.series 229 */ 230{ 231 legendSymbol: 'lineMarker' 232}); 233SeriesRegistry.registerSeriesType('line', LineSeries); 234/* * 235 * 236 * Default Export 237 * 238 * */ 239export default LineSeries; 240/* * 241 * 242 * API Options 243 * 244 * */ 245/** 246 * A line series displays information as a series of data points connected by 247 * straight line segments. 248 * 249 * @sample {highcharts} highcharts/demo/line-chart/ 250 * Line chart 251 * @sample {highstock} stock/demo/basic-line/ 252 * Line chart 253 * 254 * @extends plotOptions.series 255 * @product highcharts highstock 256 * @apioption plotOptions.line 257 */ 258/** 259 * The SVG value used for the `stroke-linecap` and `stroke-linejoin` 260 * of a line graph. Round means that lines are rounded in the ends and 261 * bends. 262 * 263 * @type {Highcharts.SeriesLinecapValue} 264 * @default round 265 * @since 3.0.7 266 * @apioption plotOptions.line.linecap 267 */ 268/** 269 * A `line` series. If the [type](#series.line.type) option is not 270 * specified, it is inherited from [chart.type](#chart.type). 271 * 272 * @extends series,plotOptions.line 273 * @excluding dataParser,dataURL 274 * @product highcharts highstock 275 * @apioption series.line 276 */ 277/** 278 * An array of data points for the series. For the `line` series type, 279 * points can be given in the following ways: 280 * 281 * 1. An array of numerical values. In this case, the numerical values will be 282 * interpreted as `y` options. The `x` values will be automatically 283 * calculated, either starting at 0 and incremented by 1, or from 284 * `pointStart` and `pointInterval` given in the series options. If the axis 285 * has categories, these will be used. Example: 286 * ```js 287 * data: [0, 5, 3, 5] 288 * ``` 289 * 290 * 2. An array of arrays with 2 values. In this case, the values correspond to 291 * `x,y`. If the first value is a string, it is applied as the name of the 292 * point, and the `x` value is inferred. 293 * ```js 294 * data: [ 295 * [0, 1], 296 * [1, 2], 297 * [2, 8] 298 * ] 299 * ``` 300 * 301 * 3. An array of objects with named values. The following snippet shows only a 302 * few settings, see the complete options set below. If the total number of 303 * data points exceeds the series' 304 * [turboThreshold](#series.line.turboThreshold), 305 * this option is not available. 306 * ```js 307 * data: [{ 308 * x: 1, 309 * y: 9, 310 * name: "Point2", 311 * color: "#00FF00" 312 * }, {
313 * x: 1, 314 * y: 6, 315 * name: "Point1", 316 * color: "#FF00FF" 317 * }] 318 * ``` 319 * 320 * **Note:** In TypeScript you have to extend `PointOptionsObject` with an 321 * additional declaration to allow custom data types: 322 * ```ts 323 * declare module `highcharts` { 324 * interface PointOptionsObject { 325 * custom: Record<string, (boolean|number|string)>; 326 * } 327 * } 328 * ``` 329 * 330 * @sample {highcharts} highcharts/chart/reflow-true/ 331 * Numerical values 332 * @sample {highcharts} highcharts/series/data-array-of-arrays/ 333 * Arrays of numeric x and y 334 * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/ 335 * Arrays of datetime x and y 336 * @sample {highcharts} highcharts/series/data-array-of-name-value/ 337 * Arrays of point.name and y 338 * @sample {highcharts} highcharts/series/data-array-of-objects/ 339 * Config objects 340 * 341 * @declare Highcharts.PointOptionsObject 342 * @type {Array<number|Array<(number|string),(number|null)>|null|*>} 343 * @apioption series.line.data 344 */ 345/** 346 * An additional, individual class name for the data point's graphic 347 * representation. Changes to a point's color will also be reflected in a 348 * chart's legend and tooltip. 349 * 350 * @sample {highcharts} highcharts/css/point-series-classname 351 * Series and point class name 352 * 353 * @type {string} 354 * @since 5.0.0 355 * @product highcharts gantt 356 * @apioption series.line.data.className 357 */ 358/** 359 * Individual color for the point. By default the color is pulled from 360 * the global `colors` array. 361 * 362 * In styled mode, the `color` option doesn't take effect. Instead, use 363 * `colorIndex`. 364 * 365 * @sample {highcharts} highcharts/point/color/ 366 * Mark the highest point 367 * 368 * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject} 369 * @product highcharts highstock gantt 370 * @apioption series.line.data.color 371 */ 372/** 373 * A specific color index to use for the point, so its graphic representations 374 * are given the class name `highcharts-color-{n}`. In styled mode this will 375 * change the color of the graphic. In non-styled mode, the color is set by the 376 * `fill` attribute, so the change in class name won't have a visual effect by 377 * default. 378 * 379 * Since v11, CSS variables on the form `--highcharts-color-{n}` make changing 380 * the color scheme very convenient. 381 * 382 * @sample {highcharts} highcharts/css/colorindex/ 383 * Series and point color index 384 * 385 * @type {number} 386 * @since 5.0.0 387 * @product highcharts gantt 388 * @apioption series.line.data.colorIndex 389 */ 390/** 391 * A reserved subspace to store options and values for customized functionality. 392 * Here you can add additional data for your own event callbacks and formatter 393 * callbacks. 394 * 395 * @sample {highcharts} highcharts/point/custom/ 396 * Point and series with custom data 397 * 398 * @type {Highcharts.Dictionary<*>} 399 * @apioption series.line.data.custom 400 */ 401/** 402 * Individual data label for each point. The options are the same as 403 * the ones for [plotOptions.series.dataLabels]( 404 * #plotOptions.series.dataLabels). 405 * 406 * @sample highcharts/point/datalabels/ 407 * Show a label for the last value 408 * 409 * @type {*|Array<*>} 410 * @declare Highcharts.DataLabelsOptions 411 * @extends plotOptions.line.dataLabels 412 * @product highcharts highstock gantt 413 * @apioption series.line.data.dataLabels 414 */ 415/** 416 * A description of the point to add to the screen reader information 417 * about the point. 418 * 419 * @type {string} 420 * @since 5.0.0 421 * @requires modules/accessibility 422 * @apioption series.line.data.description 423 */ 424/** 425 * An id for the point. This can be used after render time to get a 426 * pointer to the point object through `chart.get()`. 427 * 428 * @sample {highcharts} highcharts/point/id/ 429 * Remove an id'd point 430 * 431 * @type {string} 432 * @since 1.2.0 433 * @product highcharts highstock gantt 434 * @apioption series.line.data.id 435 */ 436/** 437 * The rank for this point's data label in case of collision. If two 438 * data labels are about to overlap, only the one with the highest `labelrank` 439 * will be drawn. 440 * 441 * @type {number} 442 * @apioption series.line.data.labelrank 443 */ 444/** 445 * The name of the point as shown in the legend, tooltip, dataLabels, etc. 446 * 447 * @see [xAxis.uniqueNames](#xAxis.uniqueNames) 448 * 449 * @sample {highcharts} highcharts/series/data-array-of-objects/ 450 * Point names 451 * 452 * @type {string} 453 * @apioption series.line.data.name 454 */ 455/** 456 * Whether the data point is selected initially. 457 * 458 * @type {boolean} 459 * @default false 460 * @product highcharts highstock gantt 461 * @apioption series.line.data.selected 462 */ 463/** 464 * The x value of the point. 465 * 466 * For datetime axes, a number value is the timestamp in milliseconds since 467 * 1970, while a date string is parsed according to the [current time zone] 468 * (https://api.highcharts.com/highcharts/time.timezone) of the 469 * chart. Date strings are supported since v12. 470 * 471 * @type {number|string} 472 * @product highcharts highstock 473 * @apioption series.line.data.x 474 */ 475/** 476 * The y value of the point. 477 * 478 * @type {number|null} 479 * @product highcharts highstock 480 * @apioption series.line.data.y 481 */ 482/** 483 * The individual point events. 484 * 485 * @extends plotOptions.series.point.events 486 * @product highcharts highstock gantt 487 * @apioption series.line.data.events 488 */ 489/** 490 * Options for the point markers of line-like series. 491 * 492 * @declare Highcharts.PointMarkerOptionsObject 493 * @extends plotOptions.series.marker 494 * @product highcharts highstock 495 * @apioption series.line.data.marker 496 */ 497''; // Include precedent doclets in transpiled
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.