From eb235700b36a2d2898b30e961a9edbc61517db18 Mon Sep 17 00:00:00 2001 From: Ivan Tsenilov Date: Wed, 18 Jan 2023 11:01:01 +0400 Subject: [PATCH 01/13] feat: add some types to helpers.segment.ts --- ...{helpers.segment.js => helpers.segment.ts} | 43 +++++++++++-------- src/types/index.d.ts | 1 + 2 files changed, 27 insertions(+), 17 deletions(-) rename src/helpers/{helpers.segment.js => helpers.segment.ts} (85%) diff --git a/src/helpers/helpers.segment.js b/src/helpers/helpers.segment.ts similarity index 85% rename from src/helpers/helpers.segment.js rename to src/helpers/helpers.segment.ts index 0c6dbfd0ce2..76a9ff57452 100644 --- a/src/helpers/helpers.segment.js +++ b/src/helpers/helpers.segment.ts @@ -1,5 +1,13 @@ import {_angleBetween, _angleDiff, _isBetween, _normalizeAngle} from './helpers.math.js'; import {createContext} from './helpers.options.js'; +import type {LineElement, LineOptions, PointElement, Segment} from '../types/index.js'; +import type {Point} from '../types/geometric.js'; + +interface Bounds { + property: string; + start: number; + end: number; +} /** * @typedef { import('../elements/element.line.js').default } LineElement @@ -7,7 +15,7 @@ import {createContext} from './helpers.options.js'; * @typedef {{start: number, end: number, loop: boolean, style?: any}} Segment */ -function propertyFn(property) { +function propertyFn(property: string) { if (property === 'angle') { return { between: _angleBetween, @@ -17,8 +25,8 @@ function propertyFn(property) { } return { between: _isBetween, - compare: (a, b) => a - b, - normalize: x => x + compare: (a: number, b: number) => a - b, + normalize: (x) => x }; } @@ -31,13 +39,13 @@ function normalizeSegment({start, end, count, loop, style}) { }; } -function getSegment(segment, points, bounds) { +function getSegment(segment: Segment, points: Point[], bounds: Bounds) { const {property, start: startBound, end: endBound} = bounds; const {between, normalize} = propertyFn(property); const count = points.length; // eslint-disable-next-line prefer-const let {start, end, loop} = segment; - let i, ilen; + let i: number, ilen: number; if (loop) { start += count; @@ -73,7 +81,8 @@ function getSegment(segment, points, bounds) { * @param {number} bounds.end - end value of the property * @private **/ -export function _boundSegment(segment, points, bounds) { +// eslint-disable-next-line max-statements, complexity +export function _boundSegment(segment: Segment, points: PointElement[], bounds: Bounds) { if (!bounds) { return [segment]; } @@ -86,7 +95,7 @@ export function _boundSegment(segment, points, bounds) { const result = []; let inside = false; let subStart = null; - let value, point, prevValue; + let value: number, point: PointElement, prevValue: number; const startIsBefore = () => between(startBound, prevValue, value) && compare(startBound, prevValue) !== 0; const endIsBefore = () => compare(endBound, value) === 0 || between(endBound, prevValue, value); @@ -137,7 +146,7 @@ export function _boundSegment(segment, points, bounds) { * @param {number} bounds.end - end value of the `property` * @private */ -export function _boundSegments(line, bounds) { +export function _boundSegments(line: LineElement, bounds: Bounds) { const result = []; const segments = line.segments; @@ -153,7 +162,7 @@ export function _boundSegments(line, bounds) { /** * Find start and end index of a line. */ -function findStartAndEnd(points, count, loop, spanGaps) { +function findStartAndEnd(points: PointElement[], count: number, loop: boolean, spanGaps: number | boolean) { let start = 0; let end = count - 1; @@ -194,12 +203,12 @@ function findStartAndEnd(points, count, loop, spanGaps) { * @param {number} max - max index (can go past count on a loop) * @param {boolean} loop - boolean indicating that this would be a loop if no gaps are found */ -function solidSegments(points, start, max, loop) { +function solidSegments(points: PointElement[], start: number, max: number, loop: boolean) { const count = points.length; const result = []; let last = start; let prev = points[start]; - let end; + let end: number; for (end = start + 1; end <= max; ++end) { const cur = points[end % count]; @@ -234,7 +243,7 @@ function solidSegments(points, start, max, loop) { * @return {Segment[]} * @private */ -export function _computeSegments(line, segmentOptions) { +export function _computeSegments(line: LineElement, segmentOptions: any) { const points = line.points; const spanGaps = line.options.spanGaps; const count = points.length; @@ -261,7 +270,7 @@ export function _computeSegments(line, segmentOptions) { * @param {object} [segmentOptions] * @return {Segment[]} */ -function splitByStyles(line, segments, points, segmentOptions) { +function splitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: { setContext }) { if (!segmentOptions || !segmentOptions.setContext || !points) { return segments; } @@ -275,7 +284,7 @@ function splitByStyles(line, segments, points, segmentOptions) { * @param {object} [segmentOptions] * @return {Segment[]} */ -function doSplitByStyles(line, segments, points, segmentOptions) { +function doSplitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: { setContext: (arg0: any) => any; }) { const chartContext = line._chart.getContext(); const baseStyle = readStyle(line.options); const {_datasetIndex: datasetIndex, options: {spanGaps}} = line; @@ -285,7 +294,7 @@ function doSplitByStyles(line, segments, points, segmentOptions) { let start = segments[0].start; let i = start; - function addStyle(s, e, l, st) { + function addStyle(s: number, e: number, l: boolean, st: { backgroundColor: any; borderCapStyle: any; borderDash: any; borderDashOffset: any; borderJoinStyle: any; borderWidth: any; borderColor: any; }) { const dir = spanGaps ? -1 : 1; if (s === e) { return; @@ -308,7 +317,7 @@ function doSplitByStyles(line, segments, points, segmentOptions) { for (const segment of segments) { start = spanGaps ? start : segment.start; let prev = points[start % count]; - let style; + let style: Segment['style']; for (i = start + 1; i <= segment.end; i++) { const pt = points[i % count]; style = readStyle(segmentOptions.setContext(createContext(chartContext, { @@ -333,7 +342,7 @@ function doSplitByStyles(line, segments, points, segmentOptions) { return result; } -function readStyle(options) { +function readStyle(options: LineOptions) { return { backgroundColor: options.backgroundColor, borderCapStyle: options.borderCapStyle, diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 28de6bd6818..abbd3d572f0 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -1685,6 +1685,7 @@ export interface Segment { start: number; end: number; loop: boolean; + style?: AnyObject; } export interface ArcBorderRadius { From 011dbea51aac1eab1ef6ff78be68e2c5b46788aa Mon Sep 17 00:00:00 2001 From: Ivan Tsenilov Date: Fri, 27 Jan 2023 12:47:16 +0400 Subject: [PATCH 02/13] feat: add more types --- src/helpers/helpers.segment.ts | 10 +++++----- src/types/index.d.ts | 8 ++++++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/helpers/helpers.segment.ts b/src/helpers/helpers.segment.ts index 76a9ff57452..d1d69b9cf86 100644 --- a/src/helpers/helpers.segment.ts +++ b/src/helpers/helpers.segment.ts @@ -270,7 +270,7 @@ export function _computeSegments(line: LineElement, segmentOptions: any) { * @param {object} [segmentOptions] * @return {Segment[]} */ -function splitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: { setContext }) { +function splitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: any) { if (!segmentOptions || !segmentOptions.setContext || !points) { return segments; } @@ -284,7 +284,7 @@ function splitByStyles(line: LineElement, segments: Segment[], points: PointElem * @param {object} [segmentOptions] * @return {Segment[]} */ -function doSplitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: { setContext: (arg0: any) => any; }) { +function doSplitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: any) { const chartContext = line._chart.getContext(); const baseStyle = readStyle(line.options); const {_datasetIndex: datasetIndex, options: {spanGaps}} = line; @@ -294,7 +294,7 @@ function doSplitByStyles(line: LineElement, segments: Segment[], points: PointEl let start = segments[0].start; let i = start; - function addStyle(s: number, e: number, l: boolean, st: { backgroundColor: any; borderCapStyle: any; borderDash: any; borderDashOffset: any; borderJoinStyle: any; borderWidth: any; borderColor: any; }) { + function addStyle(s: number, e: number, l: boolean, st: Segment['style']) { const dir = spanGaps ? -1 : 1; if (s === e) { return; @@ -342,7 +342,7 @@ function doSplitByStyles(line: LineElement, segments: Segment[], points: PointEl return result; } -function readStyle(options: LineOptions) { +function readStyle(options: LineOptions): Segment['style'] { return { backgroundColor: options.backgroundColor, borderCapStyle: options.borderCapStyle, @@ -354,6 +354,6 @@ function readStyle(options: LineOptions) { }; } -function styleChanged(style, prevStyle) { +function styleChanged(style: Segment['style'], prevStyle: Segment['style']) { return prevStyle && JSON.stringify(style) !== JSON.stringify(prevStyle); } diff --git a/src/types/index.d.ts b/src/types/index.d.ts index abbd3d572f0..b5b0438f2c0 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -1685,7 +1685,7 @@ export interface Segment { start: number; end: number; loop: boolean; - style?: AnyObject; + style?: LineOptions['segment']; } export interface ArcBorderRadius { @@ -1809,13 +1809,17 @@ export interface LineElement, VisualElement { updateControlPoints(chartArea: ChartArea, indexAxis?: 'x' | 'y'): void; - points: Point[]; + points: PointElement[]; readonly segments: Segment[]; first(): Point | false; last(): Point | false; interpolate(point: Point, property: 'x' | 'y'): undefined | Point | Point[]; pathSegment(ctx: CanvasRenderingContext2D, segment: Segment, params: AnyObject): undefined | boolean; path(ctx: CanvasRenderingContext2D): boolean; + _loop: boolean; + _fullLoop: boolean; + _datasetIndex: number; + _chart: AnyObject; } export declare const LineElement: ChartComponent & { From 03f001d55a8edd4e931844342e1e4c8ffb816ddb Mon Sep 17 00:00:00 2001 From: Ivan Tsenilov Date: Mon, 30 Jan 2023 16:42:21 +0400 Subject: [PATCH 03/13] fix: _chart type --- src/types/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/index.d.ts b/src/types/index.d.ts index b5b0438f2c0..4f8f5e7600f 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -1819,7 +1819,7 @@ export interface LineElement Date: Mon, 30 Jan 2023 16:43:22 +0400 Subject: [PATCH 04/13] feat: add getContext() type --- src/types/index.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 4f8f5e7600f..a8a128fce92 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -533,6 +533,7 @@ export declare class Chart< getDataVisibility(index: number): boolean; hide(datasetIndex: number, dataIndex?: number): void; show(datasetIndex: number, dataIndex?: number): void; + getContext(): ScriptableChartContext; getActiveElements(): ActiveElement[]; setActiveElements(active: ActiveDataPoint[]): void; From 04bb3bd93c9db5dc070f06294e99d0bc97c17c2f Mon Sep 17 00:00:00 2001 From: Ivan Tsenilov Date: Mon, 30 Jan 2023 22:59:42 +0400 Subject: [PATCH 05/13] feat: add types to helpers.canvas.ts --- .../{helpers.canvas.js => helpers.canvas.ts} | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) rename src/helpers/{helpers.canvas.js => helpers.canvas.ts} (85%) diff --git a/src/helpers/helpers.canvas.js b/src/helpers/helpers.canvas.ts similarity index 85% rename from src/helpers/helpers.canvas.js rename to src/helpers/helpers.canvas.ts index 217c3f1edce..8e56b2e6de9 100644 --- a/src/helpers/helpers.canvas.js +++ b/src/helpers/helpers.canvas.ts @@ -1,5 +1,8 @@ +import type {Chart, ChartArea, FontSpec, Point} from 'src/types.js'; +import type { RoundedRect} from 'src/types/geometric.js'; import {isArray, isNullOrUndef} from './helpers.core.js'; import {PI, TAU, HALF_PI, QUARTER_PI, TWO_THIRDS_PI, RAD_PER_DEG} from './helpers.math.js'; +import type {BackdropOptions, CanvasFontSpec, DrawPointOptions, RenderTextOpts, SplinePoint} from './types.js'; /** * Note: typedefs are auto-exported, so use a made-up `canvas` namespace where @@ -19,7 +22,7 @@ import {PI, TAU, HALF_PI, QUARTER_PI, TWO_THIRDS_PI, RAD_PER_DEG} from './helper * @return {string|null} The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font * @private */ -export function toFontString(font) { +export function toFontString(font: FontSpec): string | null { if (!font || isNullOrUndef(font.size) || isNullOrUndef(font.family)) { return null; } @@ -33,7 +36,7 @@ export function toFontString(font) { /** * @private */ -export function _measureText(ctx, data, gc, longest, string) { +export function _measureText(ctx: CanvasRenderingContext2D, data, gc, longest: number, string) { let textWidth = data[string]; if (!textWidth) { textWidth = data[string] = ctx.measureText(string).width; @@ -48,7 +51,8 @@ export function _measureText(ctx, data, gc, longest, string) { /** * @private */ -export function _longestText(ctx, font, arrayOfThings, cache) { +// eslint-disable-next-line complexity +export function _longestText(ctx: CanvasRenderingContext2D, font, arrayOfThings: T[], cache) { cache = cache || {}; let data = cache.data = cache.data || {}; let gc = cache.garbageCollect = cache.garbageCollect || []; @@ -64,7 +68,7 @@ export function _longestText(ctx, font, arrayOfThings, cache) { ctx.font = font; let longest = 0; const ilen = arrayOfThings.length; - let i, j, jlen, thing, nestedThing; + let i: number, j: number, jlen: number, thing: T, nestedThing; for (i = 0; i < ilen; i++) { thing = arrayOfThings[i]; @@ -104,7 +108,7 @@ export function _longestText(ctx, font, arrayOfThings, cache) { * @returns {number} The aligned pixel value. * @private */ -export function _alignPixel(chart, pixel, width) { +export function _alignPixel(chart: Chart, pixel: number, width: number) { const devicePixelRatio = chart.currentDevicePixelRatio; const halfWidth = width !== 0 ? Math.max(width / 2, 0.5) : 0; return Math.round((pixel - halfWidth) * devicePixelRatio) / devicePixelRatio + halfWidth; @@ -115,7 +119,7 @@ export function _alignPixel(chart, pixel, width) { * @param {HTMLCanvasElement} canvas * @param {CanvasRenderingContext2D} [ctx] */ -export function clearCanvas(canvas, ctx) { +export function clearCanvas(canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D) { ctx = ctx || canvas.getContext('2d'); ctx.save(); @@ -126,12 +130,13 @@ export function clearCanvas(canvas, ctx) { ctx.restore(); } -export function drawPoint(ctx, options, x, y) { +export function drawPoint(ctx: CanvasRenderingContext2D, options: DrawPointOptions, x: number, y: number) { drawPointLegend(ctx, options, x, y, null); } -export function drawPointLegend(ctx, options, x, y, w) { - let type, xOffset, yOffset, size, cornerRadius, width, xOffsetW, yOffsetW; +// eslint-disable-next-line complexity +export function drawPointLegend(ctx: CanvasRenderingContext2D, options: DrawPointOptions, x: number, y: number, w: number) { + let type: string, xOffset: number, yOffset: number, size: number, cornerRadius: number, width: number, xOffsetW: number, yOffsetW: number; const style = options.pointStyle; const rotation = options.rotation; const radius = options.radius; @@ -275,28 +280,28 @@ export function drawPointLegend(ctx, options, x, y, w) { * @returns {boolean} * @private */ -export function _isPointInArea(point, area, margin) { +export function _isPointInArea(point: Point, area: ChartArea, margin: number) { margin = margin || 0.5; // margin - default is to match rounded decimals return !area || (point && point.x > area.left - margin && point.x < area.right + margin && point.y > area.top - margin && point.y < area.bottom + margin); } -export function clipArea(ctx, area) { +export function clipArea(ctx: CanvasRenderingContext2D, area: ChartArea) { ctx.save(); ctx.beginPath(); ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top); ctx.clip(); } -export function unclipArea(ctx) { +export function unclipArea(ctx: CanvasRenderingContext2D) { ctx.restore(); } /** * @private */ -export function _steppedLineTo(ctx, previous, target, flip, mode) { +export function _steppedLineTo(ctx: CanvasRenderingContext2D, previous: Point, target: Point, flip, mode) { if (!previous) { return ctx.lineTo(target.x, target.y); } @@ -315,7 +320,7 @@ export function _steppedLineTo(ctx, previous, target, flip, mode) { /** * @private */ -export function _bezierCurveTo(ctx, previous, target, flip) { +export function _bezierCurveTo(ctx: CanvasRenderingContext2D, previous: SplinePoint, target: SplinePoint, flip) { if (!previous) { return ctx.lineTo(target.x, target.y); } @@ -331,10 +336,10 @@ export function _bezierCurveTo(ctx, previous, target, flip) { /** * Render text onto the canvas */ -export function renderText(ctx, text, x, y, font, opts = {}) { +export function renderText(ctx: CanvasRenderingContext2D, text: string | string[], x: number, y: number, font: CanvasFontSpec, opts: RenderTextOpts = {}) { const lines = isArray(text) ? text : [text]; const stroke = opts.strokeWidth > 0 && opts.strokeColor !== ''; - let i, line; + let i: number, line: string; ctx.save(); ctx.font = font.string; @@ -368,7 +373,7 @@ export function renderText(ctx, text, x, y, font, opts = {}) { ctx.restore(); } -function setRenderOpts(ctx, opts) { +function setRenderOpts(ctx: CanvasRenderingContext2D, opts: RenderTextOpts) { if (opts.translation) { ctx.translate(opts.translation[0], opts.translation[1]); } @@ -390,7 +395,7 @@ function setRenderOpts(ctx, opts) { } } -function decorateText(ctx, x, y, line, opts) { +function decorateText(ctx: CanvasRenderingContext2D, x: number, y: number, line: string, opts: RenderTextOpts) { if (opts.strikethrough || opts.underline) { /** * Now that IE11 support has been dropped, we can use more @@ -415,7 +420,7 @@ function decorateText(ctx, x, y, line, opts) { } } -function drawBackdrop(ctx, opts) { +function drawBackdrop(ctx: CanvasRenderingContext2D, opts: BackdropOptions) { const oldColor = ctx.fillStyle; ctx.fillStyle = opts.color; @@ -428,7 +433,7 @@ function drawBackdrop(ctx, opts) { * @param {CanvasRenderingContext2D} ctx Context * @param {*} rect Bounding rect */ -export function addRoundedRectPath(ctx, rect) { +export function addRoundedRectPath(ctx: CanvasRenderingContext2D, rect: RoundedRect) { const {x, y, w, h, radius} = rect; // top left arc From 288a5256846a9fee656b4b3896302495a395fdda Mon Sep 17 00:00:00 2001 From: Ivan Tsenilov Date: Fri, 3 Feb 2023 11:25:08 +0400 Subject: [PATCH 06/13] Revert "feat: add types to helpers.canvas.ts" This reverts commit 04bb3bd93c9db5dc070f06294e99d0bc97c17c2f. --- .../{helpers.canvas.ts => helpers.canvas.js} | 45 +++++++++---------- 1 file changed, 20 insertions(+), 25 deletions(-) rename src/helpers/{helpers.canvas.ts => helpers.canvas.js} (85%) diff --git a/src/helpers/helpers.canvas.ts b/src/helpers/helpers.canvas.js similarity index 85% rename from src/helpers/helpers.canvas.ts rename to src/helpers/helpers.canvas.js index 8e56b2e6de9..217c3f1edce 100644 --- a/src/helpers/helpers.canvas.ts +++ b/src/helpers/helpers.canvas.js @@ -1,8 +1,5 @@ -import type {Chart, ChartArea, FontSpec, Point} from 'src/types.js'; -import type { RoundedRect} from 'src/types/geometric.js'; import {isArray, isNullOrUndef} from './helpers.core.js'; import {PI, TAU, HALF_PI, QUARTER_PI, TWO_THIRDS_PI, RAD_PER_DEG} from './helpers.math.js'; -import type {BackdropOptions, CanvasFontSpec, DrawPointOptions, RenderTextOpts, SplinePoint} from './types.js'; /** * Note: typedefs are auto-exported, so use a made-up `canvas` namespace where @@ -22,7 +19,7 @@ import type {BackdropOptions, CanvasFontSpec, DrawPointOptions, RenderTextOpts, * @return {string|null} The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font * @private */ -export function toFontString(font: FontSpec): string | null { +export function toFontString(font) { if (!font || isNullOrUndef(font.size) || isNullOrUndef(font.family)) { return null; } @@ -36,7 +33,7 @@ export function toFontString(font: FontSpec): string | null { /** * @private */ -export function _measureText(ctx: CanvasRenderingContext2D, data, gc, longest: number, string) { +export function _measureText(ctx, data, gc, longest, string) { let textWidth = data[string]; if (!textWidth) { textWidth = data[string] = ctx.measureText(string).width; @@ -51,8 +48,7 @@ export function _measureText(ctx: CanvasRenderingContext2D, data, gc, longest: n /** * @private */ -// eslint-disable-next-line complexity -export function _longestText(ctx: CanvasRenderingContext2D, font, arrayOfThings: T[], cache) { +export function _longestText(ctx, font, arrayOfThings, cache) { cache = cache || {}; let data = cache.data = cache.data || {}; let gc = cache.garbageCollect = cache.garbageCollect || []; @@ -68,7 +64,7 @@ export function _longestText(ctx: CanvasRenderingContext2D, font, arrayOfThin ctx.font = font; let longest = 0; const ilen = arrayOfThings.length; - let i: number, j: number, jlen: number, thing: T, nestedThing; + let i, j, jlen, thing, nestedThing; for (i = 0; i < ilen; i++) { thing = arrayOfThings[i]; @@ -108,7 +104,7 @@ export function _longestText(ctx: CanvasRenderingContext2D, font, arrayOfThin * @returns {number} The aligned pixel value. * @private */ -export function _alignPixel(chart: Chart, pixel: number, width: number) { +export function _alignPixel(chart, pixel, width) { const devicePixelRatio = chart.currentDevicePixelRatio; const halfWidth = width !== 0 ? Math.max(width / 2, 0.5) : 0; return Math.round((pixel - halfWidth) * devicePixelRatio) / devicePixelRatio + halfWidth; @@ -119,7 +115,7 @@ export function _alignPixel(chart: Chart, pixel: number, width: number) { * @param {HTMLCanvasElement} canvas * @param {CanvasRenderingContext2D} [ctx] */ -export function clearCanvas(canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D) { +export function clearCanvas(canvas, ctx) { ctx = ctx || canvas.getContext('2d'); ctx.save(); @@ -130,13 +126,12 @@ export function clearCanvas(canvas: HTMLCanvasElement, ctx: CanvasRenderingConte ctx.restore(); } -export function drawPoint(ctx: CanvasRenderingContext2D, options: DrawPointOptions, x: number, y: number) { +export function drawPoint(ctx, options, x, y) { drawPointLegend(ctx, options, x, y, null); } -// eslint-disable-next-line complexity -export function drawPointLegend(ctx: CanvasRenderingContext2D, options: DrawPointOptions, x: number, y: number, w: number) { - let type: string, xOffset: number, yOffset: number, size: number, cornerRadius: number, width: number, xOffsetW: number, yOffsetW: number; +export function drawPointLegend(ctx, options, x, y, w) { + let type, xOffset, yOffset, size, cornerRadius, width, xOffsetW, yOffsetW; const style = options.pointStyle; const rotation = options.rotation; const radius = options.radius; @@ -280,28 +275,28 @@ export function drawPointLegend(ctx: CanvasRenderingContext2D, options: DrawPoin * @returns {boolean} * @private */ -export function _isPointInArea(point: Point, area: ChartArea, margin: number) { +export function _isPointInArea(point, area, margin) { margin = margin || 0.5; // margin - default is to match rounded decimals return !area || (point && point.x > area.left - margin && point.x < area.right + margin && point.y > area.top - margin && point.y < area.bottom + margin); } -export function clipArea(ctx: CanvasRenderingContext2D, area: ChartArea) { +export function clipArea(ctx, area) { ctx.save(); ctx.beginPath(); ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top); ctx.clip(); } -export function unclipArea(ctx: CanvasRenderingContext2D) { +export function unclipArea(ctx) { ctx.restore(); } /** * @private */ -export function _steppedLineTo(ctx: CanvasRenderingContext2D, previous: Point, target: Point, flip, mode) { +export function _steppedLineTo(ctx, previous, target, flip, mode) { if (!previous) { return ctx.lineTo(target.x, target.y); } @@ -320,7 +315,7 @@ export function _steppedLineTo(ctx: CanvasRenderingContext2D, previous: Point, t /** * @private */ -export function _bezierCurveTo(ctx: CanvasRenderingContext2D, previous: SplinePoint, target: SplinePoint, flip) { +export function _bezierCurveTo(ctx, previous, target, flip) { if (!previous) { return ctx.lineTo(target.x, target.y); } @@ -336,10 +331,10 @@ export function _bezierCurveTo(ctx: CanvasRenderingContext2D, previous: SplinePo /** * Render text onto the canvas */ -export function renderText(ctx: CanvasRenderingContext2D, text: string | string[], x: number, y: number, font: CanvasFontSpec, opts: RenderTextOpts = {}) { +export function renderText(ctx, text, x, y, font, opts = {}) { const lines = isArray(text) ? text : [text]; const stroke = opts.strokeWidth > 0 && opts.strokeColor !== ''; - let i: number, line: string; + let i, line; ctx.save(); ctx.font = font.string; @@ -373,7 +368,7 @@ export function renderText(ctx: CanvasRenderingContext2D, text: string | string[ ctx.restore(); } -function setRenderOpts(ctx: CanvasRenderingContext2D, opts: RenderTextOpts) { +function setRenderOpts(ctx, opts) { if (opts.translation) { ctx.translate(opts.translation[0], opts.translation[1]); } @@ -395,7 +390,7 @@ function setRenderOpts(ctx: CanvasRenderingContext2D, opts: RenderTextOpts) { } } -function decorateText(ctx: CanvasRenderingContext2D, x: number, y: number, line: string, opts: RenderTextOpts) { +function decorateText(ctx, x, y, line, opts) { if (opts.strikethrough || opts.underline) { /** * Now that IE11 support has been dropped, we can use more @@ -420,7 +415,7 @@ function decorateText(ctx: CanvasRenderingContext2D, x: number, y: number, line: } } -function drawBackdrop(ctx: CanvasRenderingContext2D, opts: BackdropOptions) { +function drawBackdrop(ctx, opts) { const oldColor = ctx.fillStyle; ctx.fillStyle = opts.color; @@ -433,7 +428,7 @@ function drawBackdrop(ctx: CanvasRenderingContext2D, opts: BackdropOptions) { * @param {CanvasRenderingContext2D} ctx Context * @param {*} rect Bounding rect */ -export function addRoundedRectPath(ctx: CanvasRenderingContext2D, rect: RoundedRect) { +export function addRoundedRectPath(ctx, rect) { const {x, y, w, h, radius} = rect; // top left arc From 22a87c884423355a5aca14150e549a150d6bf96f Mon Sep 17 00:00:00 2001 From: Ivan Tsenilov Date: Fri, 3 Feb 2023 11:47:22 +0400 Subject: [PATCH 07/13] refactor: move SegmentStyle into a separate interface --- src/helpers/helpers.segment.ts | 17 +++++++++-------- src/types/index.d.ts | 22 ++++++++++++---------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/helpers/helpers.segment.ts b/src/helpers/helpers.segment.ts index d1d69b9cf86..baf2bca0354 100644 --- a/src/helpers/helpers.segment.ts +++ b/src/helpers/helpers.segment.ts @@ -1,7 +1,8 @@ import {_angleBetween, _angleDiff, _isBetween, _normalizeAngle} from './helpers.math.js'; import {createContext} from './helpers.options.js'; -import type {LineElement, LineOptions, PointElement, Segment} from '../types/index.js'; +import type {LineElement, LineOptions, PointElement, Segment, SegmentStyle} from '../types/index.js'; import type {Point} from '../types/geometric.js'; +import type { AnyObject } from 'src/types/basic.js'; interface Bounds { property: string; @@ -243,7 +244,7 @@ function solidSegments(points: PointElement[], start: number, max: number, loop: * @return {Segment[]} * @private */ -export function _computeSegments(line: LineElement, segmentOptions: any) { +export function _computeSegments(line: LineElement, segmentOptions: AnyObject) { const points = line.points; const spanGaps = line.options.spanGaps; const count = points.length; @@ -270,7 +271,7 @@ export function _computeSegments(line: LineElement, segmentOptions: any) { * @param {object} [segmentOptions] * @return {Segment[]} */ -function splitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: any) { +function splitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: AnyObject) { if (!segmentOptions || !segmentOptions.setContext || !points) { return segments; } @@ -284,7 +285,7 @@ function splitByStyles(line: LineElement, segments: Segment[], points: PointElem * @param {object} [segmentOptions] * @return {Segment[]} */ -function doSplitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: any) { +function doSplitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: AnyObject) { const chartContext = line._chart.getContext(); const baseStyle = readStyle(line.options); const {_datasetIndex: datasetIndex, options: {spanGaps}} = line; @@ -294,7 +295,7 @@ function doSplitByStyles(line: LineElement, segments: Segment[], points: PointEl let start = segments[0].start; let i = start; - function addStyle(s: number, e: number, l: boolean, st: Segment['style']) { + function addStyle(s: number, e: number, l: boolean, st: SegmentStyle) { const dir = spanGaps ? -1 : 1; if (s === e) { return; @@ -317,7 +318,7 @@ function doSplitByStyles(line: LineElement, segments: Segment[], points: PointEl for (const segment of segments) { start = spanGaps ? start : segment.start; let prev = points[start % count]; - let style: Segment['style']; + let style: SegmentStyle; for (i = start + 1; i <= segment.end; i++) { const pt = points[i % count]; style = readStyle(segmentOptions.setContext(createContext(chartContext, { @@ -342,7 +343,7 @@ function doSplitByStyles(line: LineElement, segments: Segment[], points: PointEl return result; } -function readStyle(options: LineOptions): Segment['style'] { +function readStyle(options: LineOptions): SegmentStyle { return { backgroundColor: options.backgroundColor, borderCapStyle: options.borderCapStyle, @@ -354,6 +355,6 @@ function readStyle(options: LineOptions): Segment['style'] { }; } -function styleChanged(style: Segment['style'], prevStyle: Segment['style']) { +function styleChanged(style: SegmentStyle, prevStyle: SegmentStyle) { return prevStyle && JSON.stringify(style) !== JSON.stringify(prevStyle); } diff --git a/src/types/index.d.ts b/src/types/index.d.ts index a8a128fce92..3258a5c17e3 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -1686,7 +1686,17 @@ export interface Segment { start: number; end: number; loop: boolean; - style?: LineOptions['segment']; + style?: SegmentStyle; +} + +export interface SegmentStyle { + backgroundColor: Scriptable, + borderColor: Scriptable, + borderCapStyle: Scriptable; + borderDash: Scriptable; + borderDashOffset: Scriptable; + borderJoinStyle: Scriptable; + borderWidth: Scriptable; } export interface ArcBorderRadius { @@ -1788,15 +1798,7 @@ export interface LineOptions extends CommonElementOptions { */ spanGaps: boolean | number; - segment: { - backgroundColor: Scriptable, - borderColor: Scriptable, - borderCapStyle: Scriptable; - borderDash: Scriptable; - borderDashOffset: Scriptable; - borderJoinStyle: Scriptable; - borderWidth: Scriptable; - }; + segment: SegmentStyle; } export interface LineHoverOptions extends CommonHoverOptions { From 71e1bc195df9b3566ace5324d5f4c86e8b86fc22 Mon Sep 17 00:00:00 2001 From: Ivan Tsenilov Date: Mon, 6 Feb 2023 16:19:01 +0400 Subject: [PATCH 08/13] refactor: move 'Bounds' to the types file, rename to 'SegmentBounds' --- src/helpers/helpers.segment.ts | 22 +++++----------------- src/types/index.d.ts | 20 +++++++++++++------- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/helpers/helpers.segment.ts b/src/helpers/helpers.segment.ts index baf2bca0354..3ee99cbb1ab 100644 --- a/src/helpers/helpers.segment.ts +++ b/src/helpers/helpers.segment.ts @@ -1,20 +1,8 @@ import {_angleBetween, _angleDiff, _isBetween, _normalizeAngle} from './helpers.math.js'; import {createContext} from './helpers.options.js'; -import type {LineElement, LineOptions, PointElement, Segment, SegmentStyle} from '../types/index.js'; +import type {LineElement, LineOptions, PointElement, Segment, SegmentStyle, SegmentBounds} from '../types/index.js'; import type {Point} from '../types/geometric.js'; -import type { AnyObject } from 'src/types/basic.js'; - -interface Bounds { - property: string; - start: number; - end: number; -} - -/** - * @typedef { import('../elements/element.line.js').default } LineElement - * @typedef { import('../elements/element.point.js').default } PointElement - * @typedef {{start: number, end: number, loop: boolean, style?: any}} Segment - */ +import type {AnyObject} from 'src/types/basic.js'; function propertyFn(property: string) { if (property === 'angle') { @@ -40,7 +28,7 @@ function normalizeSegment({start, end, count, loop, style}) { }; } -function getSegment(segment: Segment, points: Point[], bounds: Bounds) { +function getSegment(segment: Segment, points: Point[], bounds: SegmentBounds) { const {property, start: startBound, end: endBound} = bounds; const {between, normalize} = propertyFn(property); const count = points.length; @@ -83,7 +71,7 @@ function getSegment(segment: Segment, points: Point[], bounds: Bounds) { * @private **/ // eslint-disable-next-line max-statements, complexity -export function _boundSegment(segment: Segment, points: PointElement[], bounds: Bounds) { +export function _boundSegment(segment: Segment, points: PointElement[], bounds: SegmentBounds) { if (!bounds) { return [segment]; } @@ -147,7 +135,7 @@ export function _boundSegment(segment: Segment, points: PointElement[], bounds: * @param {number} bounds.end - end value of the `property` * @private */ -export function _boundSegments(line: LineElement, bounds: Bounds) { +export function _boundSegments(line: LineElement, bounds: SegmentBounds) { const result = []; const segments = line.segments; diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 3258a5c17e3..d669b87b648 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -1690,13 +1690,19 @@ export interface Segment { } export interface SegmentStyle { - backgroundColor: Scriptable, - borderColor: Scriptable, - borderCapStyle: Scriptable; - borderDash: Scriptable; - borderDashOffset: Scriptable; - borderJoinStyle: Scriptable; - borderWidth: Scriptable; + backgroundColor: Scriptable, + borderColor: Scriptable, + borderCapStyle: Scriptable; + borderDash: Scriptable; + borderDashOffset: Scriptable; + borderJoinStyle: Scriptable; + borderWidth: Scriptable; +} + +export interface SegmentBounds { + property: string; + start: number; + end: number; } export interface ArcBorderRadius { From a6ea3768fa04cc4775d35e375072486207b7f8fd Mon Sep 17 00:00:00 2001 From: Ivan Tsenilov Date: Tue, 7 Feb 2023 11:49:19 +0400 Subject: [PATCH 09/13] refactor: remove jsdoc types --- src/helpers/helpers.segment.ts | 39 +--------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) diff --git a/src/helpers/helpers.segment.ts b/src/helpers/helpers.segment.ts index 3ee99cbb1ab..67088cae9ef 100644 --- a/src/helpers/helpers.segment.ts +++ b/src/helpers/helpers.segment.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-use-before-define */ import {_angleBetween, _angleDiff, _isBetween, _normalizeAngle} from './helpers.math.js'; import {createContext} from './helpers.options.js'; import type {LineElement, LineOptions, PointElement, Segment, SegmentStyle, SegmentBounds} from '../types/index.js'; @@ -58,17 +59,6 @@ function getSegment(segment: Segment, points: Point[], bounds: SegmentBounds) { /** * Returns the sub-segment(s) of a line segment that fall in the given bounds - * @param {object} segment - * @param {number} segment.start - start index of the segment, referring the points array - * @param {number} segment.end - end index of the segment, referring the points array - * @param {boolean} segment.loop - indicates that the segment is a loop - * @param {object} [segment.style] - segment style - * @param {PointElement[]} points - the points that this segment refers to - * @param {object} [bounds] - * @param {string} bounds.property - the property of a `PointElement` we are bounding. `x`, `y` or `angle`. - * @param {number} bounds.start - start value of the property - * @param {number} bounds.end - end value of the property - * @private **/ // eslint-disable-next-line max-statements, complexity export function _boundSegment(segment: Segment, points: PointElement[], bounds: SegmentBounds) { @@ -128,12 +118,6 @@ export function _boundSegment(segment: Segment, points: PointElement[], bounds: /** * Returns the segments of the line that are inside given bounds - * @param {LineElement} line - * @param {object} [bounds] - * @param {string} bounds.property - the property we are bounding with. `x`, `y` or `angle`. - * @param {number} bounds.start - start value of the `property` - * @param {number} bounds.end - end value of the `property` - * @private */ export function _boundSegments(line: LineElement, bounds: SegmentBounds) { const result = []; @@ -187,10 +171,6 @@ function findStartAndEnd(points: PointElement[], count: number, loop: boolean, s /** * Compute solid segments from Points, when spanGaps === false - * @param {PointElement[]} points - the points - * @param {number} start - start index - * @param {number} max - max index (can go past count on a loop) - * @param {boolean} loop - boolean indicating that this would be a loop if no gaps are found */ function solidSegments(points: PointElement[], start: number, max: number, loop: boolean) { const count = points.length; @@ -227,10 +207,6 @@ function solidSegments(points: PointElement[], start: number, max: number, loop: /** * Compute the continuous segments that define the whole line * There can be skipped points within a segment, if spanGaps is true. - * @param {LineElement} line - * @param {object} [segmentOptions] - * @return {Segment[]} - * @private */ export function _computeSegments(line: LineElement, segmentOptions: AnyObject) { const points = line.points; @@ -253,12 +229,6 @@ export function _computeSegments(line: LineElement, segmentOptions: AnyObject) { return splitByStyles(line, solidSegments(points, start, max, completeLoop), points, segmentOptions); } -/** - * @param {Segment[]} segments - * @param {PointElement[]} points - * @param {object} [segmentOptions] - * @return {Segment[]} - */ function splitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: AnyObject) { if (!segmentOptions || !segmentOptions.setContext || !points) { return segments; @@ -266,13 +236,6 @@ function splitByStyles(line: LineElement, segments: Segment[], points: PointElem return doSplitByStyles(line, segments, points, segmentOptions); } -/** - * @param {LineElement} line - * @param {Segment[]} segments - * @param {PointElement[]} points - * @param {object} [segmentOptions] - * @return {Segment[]} - */ function doSplitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: AnyObject) { const chartContext = line._chart.getContext(); const baseStyle = readStyle(line.options); From ff37d78ea54045c56a51032489308bad1dde1ede Mon Sep 17 00:00:00 2001 From: Ivan Tsenilov Date: Tue, 7 Feb 2023 14:52:17 +0400 Subject: [PATCH 10/13] Revert "refactor: remove jsdoc types" This reverts commit a6ea3768fa04cc4775d35e375072486207b7f8fd. --- src/helpers/helpers.segment.ts | 39 +++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/helpers/helpers.segment.ts b/src/helpers/helpers.segment.ts index 67088cae9ef..3ee99cbb1ab 100644 --- a/src/helpers/helpers.segment.ts +++ b/src/helpers/helpers.segment.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-use-before-define */ import {_angleBetween, _angleDiff, _isBetween, _normalizeAngle} from './helpers.math.js'; import {createContext} from './helpers.options.js'; import type {LineElement, LineOptions, PointElement, Segment, SegmentStyle, SegmentBounds} from '../types/index.js'; @@ -59,6 +58,17 @@ function getSegment(segment: Segment, points: Point[], bounds: SegmentBounds) { /** * Returns the sub-segment(s) of a line segment that fall in the given bounds + * @param {object} segment + * @param {number} segment.start - start index of the segment, referring the points array + * @param {number} segment.end - end index of the segment, referring the points array + * @param {boolean} segment.loop - indicates that the segment is a loop + * @param {object} [segment.style] - segment style + * @param {PointElement[]} points - the points that this segment refers to + * @param {object} [bounds] + * @param {string} bounds.property - the property of a `PointElement` we are bounding. `x`, `y` or `angle`. + * @param {number} bounds.start - start value of the property + * @param {number} bounds.end - end value of the property + * @private **/ // eslint-disable-next-line max-statements, complexity export function _boundSegment(segment: Segment, points: PointElement[], bounds: SegmentBounds) { @@ -118,6 +128,12 @@ export function _boundSegment(segment: Segment, points: PointElement[], bounds: /** * Returns the segments of the line that are inside given bounds + * @param {LineElement} line + * @param {object} [bounds] + * @param {string} bounds.property - the property we are bounding with. `x`, `y` or `angle`. + * @param {number} bounds.start - start value of the `property` + * @param {number} bounds.end - end value of the `property` + * @private */ export function _boundSegments(line: LineElement, bounds: SegmentBounds) { const result = []; @@ -171,6 +187,10 @@ function findStartAndEnd(points: PointElement[], count: number, loop: boolean, s /** * Compute solid segments from Points, when spanGaps === false + * @param {PointElement[]} points - the points + * @param {number} start - start index + * @param {number} max - max index (can go past count on a loop) + * @param {boolean} loop - boolean indicating that this would be a loop if no gaps are found */ function solidSegments(points: PointElement[], start: number, max: number, loop: boolean) { const count = points.length; @@ -207,6 +227,10 @@ function solidSegments(points: PointElement[], start: number, max: number, loop: /** * Compute the continuous segments that define the whole line * There can be skipped points within a segment, if spanGaps is true. + * @param {LineElement} line + * @param {object} [segmentOptions] + * @return {Segment[]} + * @private */ export function _computeSegments(line: LineElement, segmentOptions: AnyObject) { const points = line.points; @@ -229,6 +253,12 @@ export function _computeSegments(line: LineElement, segmentOptions: AnyObject) { return splitByStyles(line, solidSegments(points, start, max, completeLoop), points, segmentOptions); } +/** + * @param {Segment[]} segments + * @param {PointElement[]} points + * @param {object} [segmentOptions] + * @return {Segment[]} + */ function splitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: AnyObject) { if (!segmentOptions || !segmentOptions.setContext || !points) { return segments; @@ -236,6 +266,13 @@ function splitByStyles(line: LineElement, segments: Segment[], points: PointElem return doSplitByStyles(line, segments, points, segmentOptions); } +/** + * @param {LineElement} line + * @param {Segment[]} segments + * @param {PointElement[]} points + * @param {object} [segmentOptions] + * @return {Segment[]} + */ function doSplitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: AnyObject) { const chartContext = line._chart.getContext(); const baseStyle = readStyle(line.options); From e2205195d194a9eca7a80bd5e30fd00822407986 Mon Sep 17 00:00:00 2001 From: Ivan Tsenilov Date: Tue, 7 Feb 2023 14:59:36 +0400 Subject: [PATCH 11/13] refactor: remove jsdoc types but keep the descriptions --- src/helpers/helpers.segment.ts | 63 +++++++++++++++++----------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/src/helpers/helpers.segment.ts b/src/helpers/helpers.segment.ts index 3ee99cbb1ab..46f369fc442 100644 --- a/src/helpers/helpers.segment.ts +++ b/src/helpers/helpers.segment.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-use-before-define */ import {_angleBetween, _angleDiff, _isBetween, _normalizeAngle} from './helpers.math.js'; import {createContext} from './helpers.options.js'; import type {LineElement, LineOptions, PointElement, Segment, SegmentStyle, SegmentBounds} from '../types/index.js'; @@ -58,16 +59,16 @@ function getSegment(segment: Segment, points: Point[], bounds: SegmentBounds) { /** * Returns the sub-segment(s) of a line segment that fall in the given bounds - * @param {object} segment - * @param {number} segment.start - start index of the segment, referring the points array - * @param {number} segment.end - end index of the segment, referring the points array - * @param {boolean} segment.loop - indicates that the segment is a loop - * @param {object} [segment.style] - segment style - * @param {PointElement[]} points - the points that this segment refers to - * @param {object} [bounds] - * @param {string} bounds.property - the property of a `PointElement` we are bounding. `x`, `y` or `angle`. - * @param {number} bounds.start - start value of the property - * @param {number} bounds.end - end value of the property + * @param segment + * @param segment.start - start index of the segment, referring the points array + * @param segment.end - end index of the segment, referring the points array + * @param segment.loop - indicates that the segment is a loop + * @param segment.style - segment style + * @param points - the points that this segment refers to + * @param bounds + * @param bounds.property - the property of a `PointElement` we are bounding. `x`, `y` or `angle`. + * @param bounds.start - start value of the property + * @param bounds.end - end value of the property * @private **/ // eslint-disable-next-line max-statements, complexity @@ -128,11 +129,11 @@ export function _boundSegment(segment: Segment, points: PointElement[], bounds: /** * Returns the segments of the line that are inside given bounds - * @param {LineElement} line - * @param {object} [bounds] - * @param {string} bounds.property - the property we are bounding with. `x`, `y` or `angle`. - * @param {number} bounds.start - start value of the `property` - * @param {number} bounds.end - end value of the `property` + * @param line + * @param bounds + * @param bounds.property - the property we are bounding with. `x`, `y` or `angle`. + * @param bounds.start - start value of the `property` + * @param bounds.end - end value of the `property` * @private */ export function _boundSegments(line: LineElement, bounds: SegmentBounds) { @@ -187,10 +188,10 @@ function findStartAndEnd(points: PointElement[], count: number, loop: boolean, s /** * Compute solid segments from Points, when spanGaps === false - * @param {PointElement[]} points - the points - * @param {number} start - start index - * @param {number} max - max index (can go past count on a loop) - * @param {boolean} loop - boolean indicating that this would be a loop if no gaps are found + * @param points - the points + * @param start - start index + * @param max - max index (can go past count on a loop) + * @param loop - boolean indicating that this would be a loop if no gaps are found */ function solidSegments(points: PointElement[], start: number, max: number, loop: boolean) { const count = points.length; @@ -227,9 +228,9 @@ function solidSegments(points: PointElement[], start: number, max: number, loop: /** * Compute the continuous segments that define the whole line * There can be skipped points within a segment, if spanGaps is true. - * @param {LineElement} line - * @param {object} [segmentOptions] - * @return {Segment[]} + * @param line + * @param segmentOptions + * @return Segment[] * @private */ export function _computeSegments(line: LineElement, segmentOptions: AnyObject) { @@ -254,10 +255,10 @@ export function _computeSegments(line: LineElement, segmentOptions: AnyObject) { } /** - * @param {Segment[]} segments - * @param {PointElement[]} points - * @param {object} [segmentOptions] - * @return {Segment[]} + * @param segments + * @param points + * @param segmentOptions + * @return Segment[] */ function splitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: AnyObject) { if (!segmentOptions || !segmentOptions.setContext || !points) { @@ -267,11 +268,11 @@ function splitByStyles(line: LineElement, segments: Segment[], points: PointElem } /** - * @param {LineElement} line - * @param {Segment[]} segments - * @param {PointElement[]} points - * @param {object} [segmentOptions] - * @return {Segment[]} + * @param line + * @param segments + * @param points + * @param segmentOptions + * @return Segment[] */ function doSplitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: AnyObject) { const chartContext = line._chart.getContext(); From 88f12c2429241f0d31719f3e4d8dd1df1574d5ef Mon Sep 17 00:00:00 2001 From: Ivan Tsenilov Date: Tue, 7 Feb 2023 15:47:27 +0400 Subject: [PATCH 12/13] refactor: remove jsdoc return types for Segment --- src/helpers/helpers.segment.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/helpers/helpers.segment.ts b/src/helpers/helpers.segment.ts index 46f369fc442..60d7ec68926 100644 --- a/src/helpers/helpers.segment.ts +++ b/src/helpers/helpers.segment.ts @@ -230,7 +230,6 @@ function solidSegments(points: PointElement[], start: number, max: number, loop: * There can be skipped points within a segment, if spanGaps is true. * @param line * @param segmentOptions - * @return Segment[] * @private */ export function _computeSegments(line: LineElement, segmentOptions: AnyObject) { @@ -258,7 +257,6 @@ export function _computeSegments(line: LineElement, segmentOptions: AnyObject) { * @param segments * @param points * @param segmentOptions - * @return Segment[] */ function splitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: AnyObject) { if (!segmentOptions || !segmentOptions.setContext || !points) { @@ -272,7 +270,6 @@ function splitByStyles(line: LineElement, segments: Segment[], points: PointElem * @param segments * @param points * @param segmentOptions - * @return Segment[] */ function doSplitByStyles(line: LineElement, segments: Segment[], points: PointElement[], segmentOptions: AnyObject) { const chartContext = line._chart.getContext(); From f515365654b47cbf282e417dd776fe64659b37e6 Mon Sep 17 00:00:00 2001 From: Ivan Tsenilov Date: Mon, 13 Feb 2023 22:17:56 +0400 Subject: [PATCH 13/13] fix: lint errors --- src/helpers/helpers.options.ts | 2 +- src/helpers/helpers.segment.ts | 1 - src/types/index.d.ts | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/helpers/helpers.options.ts b/src/helpers/helpers.options.ts index c476ccb5e1a..aead9b7a2ae 100644 --- a/src/helpers/helpers.options.ts +++ b/src/helpers/helpers.options.ts @@ -204,7 +204,7 @@ export function _addGrace(minmax: { min: number; max: number; }, grace: number | * @returns */ export function createContext(parentContext: null, context: T): T; -export function createContext(parentContext: P, context: T): P & T; +export function createContext(parentContext: P, context: T): P & T; export function createContext(parentContext: object, context: object) { return Object.assign(Object.create(parentContext), context); } diff --git a/src/helpers/helpers.segment.ts b/src/helpers/helpers.segment.ts index 60d7ec68926..d5fe687f612 100644 --- a/src/helpers/helpers.segment.ts +++ b/src/helpers/helpers.segment.ts @@ -206,7 +206,6 @@ function solidSegments(points: PointElement[], start: number, max: number, loop: if (!prev.skip) { loop = false; result.push({start: start % count, end: (end - 1) % count, loop}); - // @ts-ignore start = last = cur.stop ? end : null; } } else { diff --git a/src/types/index.d.ts b/src/types/index.d.ts index d669b87b648..48f99fa36c0 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -1816,7 +1816,7 @@ export interface LineHoverOptions extends CommonHoverOptions { export interface LineElement extends Element, - VisualElement { + Pick { updateControlPoints(chartArea: ChartArea, indexAxis?: 'x' | 'y'): void; points: PointElement[]; readonly segments: Segment[];