Convert the Arc element to TS (#10772)

* Convert the Arc element to TS

* Make max-statements and complexity warnings in TS files as well

* Increase size limit

* Update src/elements/element.arc.ts

Co-authored-by: Dan Onoshko <danon0404@gmail.com>

Co-authored-by: Dan Onoshko <danon0404@gmail.com>
This commit is contained in:
Evert Timberg 2022-10-12 07:08:37 -04:00 committed by GitHub
parent fbf3427ca2
commit c338942ebb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 64 additions and 67 deletions

View File

@ -47,6 +47,8 @@ overrides:
- plugin:@typescript-eslint/recommended - plugin:@typescript-eslint/recommended
rules: rules:
complexity: ["warn", 10]
max-statements: ["warn", 30]
# Replace stock eslint rules with typescript-eslint equivalents for proper # Replace stock eslint rules with typescript-eslint equivalents for proper
# TypeScript support. # TypeScript support.
indent: "off" indent: "off"

View File

@ -7,7 +7,7 @@ function modifyWebpackConfig(config) {
module.exports = [ module.exports = [
{ {
path: 'dist/chart.js', path: 'dist/chart.js',
limit: '77.5 KB', limit: '78.5 KB',
webpack: false, webpack: false,
running: false running: false
}, },

View File

@ -2,11 +2,10 @@ import Element from '../core/core.element';
import {_angleBetween, getAngleFromPoint, TAU, HALF_PI, valueOrDefault} from '../helpers/index'; import {_angleBetween, getAngleFromPoint, TAU, HALF_PI, valueOrDefault} from '../helpers/index';
import {PI, _isBetween, _limitValue} from '../helpers/helpers.math'; import {PI, _isBetween, _limitValue} from '../helpers/helpers.math';
import {_readValueToProps} from '../helpers/helpers.options'; import {_readValueToProps} from '../helpers/helpers.options';
import type {ArcOptions, Point} from '../../types';
/** @typedef {{ x: number, y: number, startAngle: number, endAngle: number, innerRadius: number, outerRadius: number, circumference: number }} ArcProps */
/** @typedef {import('../../types/geometric').Point} Point */
function clipArc(ctx, element, endAngle) { function clipArc(ctx: CanvasRenderingContext2D, element: ArcElement, endAngle: number) {
const {startAngle, pixelMargin, x, y, outerRadius, innerRadius} = element; const {startAngle, pixelMargin, x, y, outerRadius, innerRadius} = element;
let angleMargin = pixelMargin / outerRadius; let angleMargin = pixelMargin / outerRadius;
@ -30,13 +29,8 @@ function toRadiusCorners(value) {
/** /**
* Parse border radius from the provided options * Parse border radius from the provided options
* @param {ArcElement} arc
* @param {number} innerRadius
* @param {number} outerRadius
* @param {number} angleDelta Arc circumference in radians
* @returns
*/ */
function parseBorderRadius(arc, innerRadius, outerRadius, angleDelta) { function parseBorderRadius(arc: ArcElement, innerRadius: number, outerRadius: number, angleDelta: number) {
const o = toRadiusCorners(arc.options.borderRadius); const o = toRadiusCorners(arc.options.borderRadius);
const halfThickness = (outerRadius - innerRadius) / 2; const halfThickness = (outerRadius - innerRadius) / 2;
const innerLimit = Math.min(halfThickness, angleDelta * innerRadius / 2); const innerLimit = Math.min(halfThickness, angleDelta * innerRadius / 2);
@ -63,13 +57,8 @@ function parseBorderRadius(arc, innerRadius, outerRadius, angleDelta) {
/** /**
* Convert (r, 𝜃) to (x, y) * Convert (r, 𝜃) to (x, y)
* @param {number} r Radius from center point
* @param {number} theta Angle in radians
* @param {number} x Center X coordinate
* @param {number} y Center Y coordinate
* @returns {{ x: number; y: number }} Rectangular coordinate point
*/ */
function rThetaToXY(r, theta, x, y) { function rThetaToXY(r: number, theta: number, x: number, y: number) {
return { return {
x: x + r * Math.cos(theta), x: x + r * Math.cos(theta),
y: y + r * Math.sin(theta), y: y + r * Math.sin(theta),
@ -93,10 +82,15 @@ function rThetaToXY(r, theta, x, y) {
* 7 4 * 7 4
* \ / * \ /
* 6---------5 Inner * 6---------5 Inner
* @param {CanvasRenderingContext2D} ctx
* @param {ArcElement} element
*/ */
function pathArc(ctx, element, offset, spacing, end, circular) { function pathArc(
ctx: CanvasRenderingContext2D,
element: ArcElement,
offset: number,
spacing: number,
end: number,
circular: boolean,
) {
const {x, y, startAngle: start, pixelMargin, innerRadius: innerR} = element; const {x, y, startAngle: start, pixelMargin, innerRadius: innerR} = element;
const outerRadius = Math.max(element.outerRadius + spacing + offset - pixelMargin, 0); const outerRadius = Math.max(element.outerRadius + spacing + offset - pixelMargin, 0);
@ -187,7 +181,13 @@ function pathArc(ctx, element, offset, spacing, end, circular) {
ctx.closePath(); ctx.closePath();
} }
function drawArc(ctx, element, offset, spacing, circular) { function drawArc(
ctx: CanvasRenderingContext2D,
element: ArcElement,
offset: number,
spacing: number,
circular: boolean,
) {
const {fullCircles, startAngle, circumference} = element; const {fullCircles, startAngle, circumference} = element;
let endAngle = element.endAngle; let endAngle = element.endAngle;
if (fullCircles) { if (fullCircles) {
@ -209,7 +209,7 @@ function drawArc(ctx, element, offset, spacing, circular) {
return endAngle; return endAngle;
} }
function drawFullCircleBorders(ctx, element, inner) { function drawFullCircleBorders(ctx: CanvasRenderingContext2D, element: ArcElement, inner: boolean) {
const {x, y, startAngle, pixelMargin, fullCircles} = element; const {x, y, startAngle, pixelMargin, fullCircles} = element;
const outerRadius = Math.max(element.outerRadius - pixelMargin, 0); const outerRadius = Math.max(element.outerRadius - pixelMargin, 0);
const innerRadius = element.innerRadius + pixelMargin; const innerRadius = element.innerRadius + pixelMargin;
@ -233,7 +233,14 @@ function drawFullCircleBorders(ctx, element, inner) {
} }
} }
function drawBorder(ctx, element, offset, spacing, endAngle, circular) { function drawBorder(
ctx: CanvasRenderingContext2D,
element: ArcElement,
offset: number,
spacing: number,
endAngle: number,
circular: boolean,
) {
const {options} = element; const {options} = element;
const {borderWidth, borderJoinStyle} = options; const {borderWidth, borderJoinStyle} = options;
const inner = options.borderAlign === 'inner'; const inner = options.borderAlign === 'inner';
@ -262,13 +269,18 @@ function drawBorder(ctx, element, offset, spacing, endAngle, circular) {
ctx.stroke(); ctx.stroke();
} }
export default class ArcElement extends Element { export interface ArcProps extends Point {
startAngle: number;
endAngle: number;
innerRadius: number;
outerRadius: number;
circumference: number;
}
export default class ArcElement extends Element<ArcProps, ArcOptions> {
static id = 'arc'; static id = 'arc';
/**
* @type {any}
*/
static defaults = { static defaults = {
borderAlign: 'center', borderAlign: 'center',
borderColor: '#fff', borderColor: '#fff',
@ -281,13 +293,18 @@ export default class ArcElement extends Element {
circular: true, circular: true,
}; };
/**
* @type {any}
*/
static defaultRoutes = { static defaultRoutes = {
backgroundColor: 'backgroundColor' backgroundColor: 'backgroundColor'
}; };
circumference: number;
endAngle: number;
fullCircles: number;
innerRadius: number;
outerRadius: number;
pixelMargin: number;
startAngle: number;
constructor(cfg) { constructor(cfg) {
super(); super();
@ -305,22 +322,16 @@ export default class ArcElement extends Element {
} }
} }
/** inRange(chartX: number, chartY: number, useFinalPosition: boolean) {
* @param {number} chartX const point = this.getProps(['x', 'y'], useFinalPosition);
* @param {number} chartY
* @param {boolean} [useFinalPosition]
*/
inRange(chartX, chartY, useFinalPosition) {
// @ts-ignore This will be fixed when the arc element is converted to TS
const point = /** @type {Point} */ (this.getProps(['x', 'y'], useFinalPosition));
const {angle, distance} = getAngleFromPoint(point, {x: chartX, y: chartY}); const {angle, distance} = getAngleFromPoint(point, {x: chartX, y: chartY});
const {startAngle, endAngle, innerRadius, outerRadius, circumference} = /** @type {ArcProps} */ (this.getProps([ const {startAngle, endAngle, innerRadius, outerRadius, circumference} = this.getProps([
'startAngle', 'startAngle',
'endAngle', 'endAngle',
'innerRadius', 'innerRadius',
'outerRadius', 'outerRadius',
'circumference' 'circumference'
], useFinalPosition)); ], useFinalPosition);
const rAdjust = this.options.spacing / 2; const rAdjust = this.options.spacing / 2;
const _circumference = valueOrDefault(circumference, endAngle - startAngle); const _circumference = valueOrDefault(circumference, endAngle - startAngle);
const betweenAngles = _circumference >= TAU || _angleBetween(angle, startAngle, endAngle); const betweenAngles = _circumference >= TAU || _angleBetween(angle, startAngle, endAngle);
@ -329,11 +340,8 @@ export default class ArcElement extends Element {
return (betweenAngles && withinRadius); return (betweenAngles && withinRadius);
} }
/** getCenterPoint(useFinalPosition: boolean) {
* @param {boolean} [useFinalPosition] const {x, y, startAngle, endAngle, innerRadius, outerRadius} = this.getProps([
*/
getCenterPoint(useFinalPosition) {
const {x, y, startAngle, endAngle, innerRadius, outerRadius} = /** @type {ArcProps} */ (this.getProps([
'x', 'x',
'y', 'y',
'startAngle', 'startAngle',
@ -341,7 +349,7 @@ export default class ArcElement extends Element {
'innerRadius', 'innerRadius',
'outerRadius', 'outerRadius',
'circumference', 'circumference',
], useFinalPosition)); ], useFinalPosition);
const {offset, spacing} = this.options; const {offset, spacing} = this.options;
const halfAngle = (startAngle + endAngle) / 2; const halfAngle = (startAngle + endAngle) / 2;
const halfRadius = (innerRadius + outerRadius + spacing + offset) / 2; const halfRadius = (innerRadius + outerRadius + spacing + offset) / 2;
@ -351,14 +359,11 @@ export default class ArcElement extends Element {
}; };
} }
/** tooltipPosition(useFinalPosition: boolean) {
* @param {boolean} [useFinalPosition]
*/
tooltipPosition(useFinalPosition) {
return this.getCenterPoint(useFinalPosition); return this.getCenterPoint(useFinalPosition);
} }
draw(ctx) { draw(ctx: CanvasRenderingContext2D) {
const {options, circumference} = this; const {options, circumference} = this;
const offset = (options.offset || 0) / 4; const offset = (options.offset || 0) / 4;
const spacing = (options.spacing || 0) / 2; const spacing = (options.spacing || 0) / 2;

24
types/index.d.ts vendored
View File

@ -1,6 +1,7 @@
import { DeepPartial, DistributiveArray, UnionToIntersection } from './utils'; import { DeepPartial, DistributiveArray, UnionToIntersection } from './utils';
import { TimeUnit } from '../src/core/core.adapters'; import { TimeUnit } from '../src/core/core.adapters';
import ArcElement from '../src/elements/element.arc';
import PointElement from '../src/elements/element.point'; import PointElement from '../src/elements/element.point';
import { EasingFunction } from '../src/helpers/helpers.easing'; import { EasingFunction } from '../src/helpers/helpers.easing';
import { AnimationEvent } from './animation'; import { AnimationEvent } from './animation';
@ -11,6 +12,7 @@ import { ChartArea, Padding, Point } from './geometric';
import { LayoutItem, LayoutPosition } from './layout'; import { LayoutItem, LayoutPosition } from './layout';
export { EasingFunction } from '../src/helpers/helpers.easing'; export { EasingFunction } from '../src/helpers/helpers.easing';
export { default as ArcElement, ArcProps } from '../src/elements/element.arc';
export { default as PointElement, PointProps } from '../src/elements/element.point'; export { default as PointElement, PointProps } from '../src/elements/element.point';
export { Animation, Animations, Animator, AnimationEvent } from './animation'; export { Animation, Animations, Animator, AnimationEvent } from './animation';
export { Color } from './color'; export { Color } from './color';
@ -1676,14 +1678,6 @@ export interface Segment {
loop: boolean; loop: boolean;
} }
export interface ArcProps extends Point {
startAngle: number;
endAngle: number;
innerRadius: number;
outerRadius: number;
circumference: number;
}
export interface ArcBorderRadius { export interface ArcBorderRadius {
outerStart: number; outerStart: number;
outerEnd: number; outerEnd: number;
@ -1718,21 +1712,17 @@ export interface ArcOptions extends CommonElementOptions {
* @default true * @default true
*/ */
circular: boolean; circular: boolean;
/**
* Spacing between arcs
*/
spacing: number
} }
export interface ArcHoverOptions extends CommonHoverOptions { export interface ArcHoverOptions extends CommonHoverOptions {
hoverOffset: number; hoverOffset: number;
} }
export interface ArcElement<T extends ArcProps = ArcProps, O extends ArcOptions = ArcOptions>
extends Element<T, O>,
VisualElement {}
export declare const ArcElement: ChartComponent & {
prototype: ArcElement;
new (cfg: AnyObject): ArcElement;
};
export interface LineProps { export interface LineProps {
points: Point[] points: Point[]
} }