}
// Update Line
+ line._chart = this.chart;
line._datasetIndex = this.index;
line._decimated = !!_dataset._decimated;
line.points = points;
updateElements(points, start, count, mode) {
const reset = mode === 'reset';
- const {iScale, vScale, _stacked} = this._cachedMeta;
+ const {iScale, vScale, _stacked, _dataset} = this._cachedMeta;
const firstOpts = this.resolveDataElementOptions(start, mode);
const sharedOptions = this.getSharedOptions(firstOpts);
const includeOptions = this.includeOptions(mode, sharedOptions);
const iAxis = iScale.axis;
const vAxis = vScale.axis;
- const spanGaps = this.options.spanGaps;
+ const {spanGaps, segment} = this.options;
const maxGapLength = isNumber(spanGaps) ? spanGaps : Number.POSITIVE_INFINITY;
const directUpdate = this.chart._animationsDisabled || reset || mode === 'none';
let prevParsed = start > 0 && this.getParsed(start - 1);
properties.skip = isNaN(iPixel) || isNaN(vPixel) || nullData;
properties.stop = i > 0 && (parsed[iAxis] - prevParsed[iAxis]) > maxGapLength;
- properties.parsed = parsed;
+ if (segment) {
+ properties.parsed = parsed;
+ properties.raw = _dataset.data[i];
+ }
if (includeOptions) {
properties.options = sharedOptions || this.resolveDataElementOptions(i, point.active ? 'active' : mode);
import Config, {determineAxis, getIndexAxis} from './core.config';
import {retinaScale, _isDomSupported} from '../helpers/helpers.dom';
import {each, callback as callCallback, uid, valueOrDefault, _elementsEqual, isNullOrUndef, setsEqual, defined, isFunction} from '../helpers/helpers.core';
-import {clearCanvas, clipArea, unclipArea, _isPointInArea} from '../helpers/helpers.canvas';
+import {clearCanvas, clipArea, createContext, unclipArea, _isPointInArea} from '../helpers';
// @ts-ignore
import {version} from '../../package.json';
import {debounce} from '../helpers/helpers.extras';
}
getContext() {
- return this.$context || (this.$context = {chart: this, type: 'chart'});
+ return this.$context || (this.$context = createContext(null, {chart: this, type: 'chart'}));
}
getVisibleDatasetCount() {
import defaults from './core.defaults';
import {isArray, isFinite, isObject, valueOrDefault, resolveObjectKey, defined} from '../helpers/helpers.core';
import {listenArrayEvents, unlistenArrayEvents} from '../helpers/helpers.collection';
-import {sign} from '../helpers/helpers.math';
+import {createContext, sign} from '../helpers';
/**
* @typedef { import("./core.controller").default } Chart
}
function createDatasetContext(parent, index) {
- return Object.assign(Object.create(parent),
+ return createContext(parent,
{
active: false,
dataset: undefined,
}
function createDataContext(parent, index, element) {
- return Object.assign(Object.create(parent), {
+ return createContext(parent, {
active: false,
dataIndex: index,
parsed: undefined,
import {callback as call, each, finiteOrDefault, isArray, isFinite, isNullOrUndef, isObject, valueOrDefault} from '../helpers/helpers.core';
import {toDegrees, toRadians, _int16Range, _limitValue, HALF_PI} from '../helpers/helpers.math';
import {_alignStartEnd, _toLeftRightCenter} from '../helpers/helpers.extras';
-import {toFont, toPadding, _addGrace} from '../helpers/helpers.options';
+import {createContext, toFont, toPadding, _addGrace} from '../helpers/helpers.options';
import './core.scale.defaults';
}
function createScaleContext(parent, scale) {
- return Object.assign(Object.create(parent), {
+ return createContext(parent, {
scale,
type: 'scale'
});
}
function createTickContext(parent, index, tick) {
- return Object.assign(Object.create(parent), {
+ return createContext(parent, {
tick,
index,
type: 'tick'
this.animated = true;
this.options = undefined;
+ this._chart = undefined;
this._loop = undefined;
this._fullLoop = undefined;
this._path = undefined;
max: keepZero(max, change)
};
}
+
+/**
+ * Create a context inheriting parentContext
+ * @param {object|null} parentContext
+ * @param {object} context
+ * @returns {object}
+ */
+export function createContext(parentContext, context) {
+ return Object.assign(Object.create(parentContext), context);
+}
import {_angleBetween, _angleDiff, _normalizeAngle} from './helpers.math';
+import {createContext} from './helpers.options';
/**
* @typedef { import("../elements/element.line").default } LineElement
* @return {Segment[]}
*/
function doSplitByStyles(line, segments, points, segmentOptions) {
+ const chartContext = line._chart.getContext();
const baseStyle = readStyle(line.options);
const {_datasetIndex: datasetIndex, options: {spanGaps}} = line;
const count = points.length;
let style;
for (i = start + 1; i <= segment.end; i++) {
const pt = points[i % count];
- style = readStyle(segmentOptions.setContext({
+ style = readStyle(segmentOptions.setContext(createContext(chartContext, {
type: 'segment',
p0: prev,
p1: pt,
p0DataIndex: (i - 1) % count,
p1DataIndex: i % count,
datasetIndex
- }));
+ })));
if (styleChanged(style, prevStyle)) {
addStyle(start, i - 1, segment.loop, prevStyle);
}
import {toFont, toPadding, toTRBLCorners} from '../helpers/helpers.options';
import {getRtlAdapter, overrideTextDirection, restoreTextDirection} from '../helpers/helpers.rtl';
import {distanceBetweenPoints, _limitValue} from '../helpers/helpers.math';
-import {drawPoint} from '../helpers';
+import {createContext, drawPoint} from '../helpers';
/**
* @typedef { import("../platform/platform.base").ChartEvent } ChartEvent
}
function createTooltipContext(parent, tooltip, tooltipItems) {
- return Object.assign(Object.create(parent), {
+ return createContext(parent, {
tooltip,
tooltipItems,
type: 'tooltip'
import LinearScaleBase from './scale.linearbase';
import Ticks from '../core/core.ticks';
import {valueOrDefault, isArray, isFinite, callback as callCallback, isNullOrUndef} from '../helpers/helpers.core';
-import {toFont, toPadding} from '../helpers/helpers.options';
+import {createContext, toFont, toPadding} from '../helpers/helpers.options';
function getTickBackdropHeight(opts) {
const tickOpts = opts.ticks;
}
function createPointLabelContext(parent, index, label) {
- return Object.assign(Object.create(parent), {
+ return createContext(parent, {
label,
index,
type: 'pointLabel'
index?: number,
info?: { cacheable?: boolean }
): T | undefined;
+
+
+/**
+ * Create a context inheriting parentContext
+ * @since 3.6.0
+ */
+export function createContext<P, T>(parentContext: P, context: T): P extends null ? T : P & T;
--- /dev/null
+import { createContext } from '../../helpers/helpers.options';
+
+const context1 = createContext(null, { type: 'test1', parent: true });
+const context2 = createContext(context1, { type: 'test2' });
+
+const sSest: string = context1.type + context2.type;
+const bTest: boolean = context1.parent && context2.parent;
+
+// @ts-expect-error Property 'notThere' does not exist on type '{ type: string; parent: boolean; } & { type: string; }'
+context2.notThere = '';