Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add getAnnotations function to plugin and remove _getState private one #892

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Next Next commit
add getAnnotation function
  • Loading branch information
stockiNail committed May 22, 2023
commit d5fe3c6d583bea2713e1e1388b047ebae0275eb9
5 changes: 3 additions & 2 deletions src/annotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@ export default {
chartStates.delete(chart);
},

_getState(chart) {
return chartStates.get(chart);
getAnnotations(chart) {
const state = chartStates.get(chart);
return state ? state.elements : [];
},

defaults: {
Expand Down
5 changes: 2 additions & 3 deletions src/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export const eventHooks = moveHooks.concat('click');
export function updateListeners(chart, state, options) {
state.listened = loadHooks(options, eventHooks, state.listeners);
state.moveListened = false;
state._getElements = getElements; // for testing

moveHooks.forEach(hook => {
if (isFunction(options[hook])) {
Expand Down Expand Up @@ -71,7 +70,7 @@ function handleMoveEvents(state, event, options) {
let elements;

if (event.type === 'mousemove') {
elements = getElements(state, event, options.interaction);
elements = getElements(state.visibleElements, event, options.interaction);
} else {
elements = [];
}
Expand All @@ -96,7 +95,7 @@ function dispatchMoveEvents({state, event}, hook, elements, checkElements) {

function handleClickEvents(state, event, options) {
const listeners = state.listeners;
const elements = getElements(state, event, options.interaction);
const elements = getElements(state.visibleElements, event, options.interaction);
let changed;
for (const element of elements) {
changed = dispatchEvent(element.options.click || listeners.click, element, event) || changed;
Expand Down
38 changes: 19 additions & 19 deletions src/interaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,58 +9,58 @@ const interaction = {
modes: {
/**
* Point mode returns all elements that hit test based on the event position
* @param {Object} state - the state of the plugin
* @param {AnnotationElement[]} visibleElements - annotation elements which are visible
* @param {ChartEvent} event - the event we are find things at
* @return {AnnotationElement[]} - elements that are found
*/
point(state, event) {
return filterElements(state, event, {intersect: true});
point(visibleElements, event) {
return filterElements(visibleElements, event, {intersect: true});
},

/**
* Nearest mode returns the element closest to the event position
* @param {Object} state - the state of the plugin
* @param {AnnotationElement[]} visibleElements - annotation elements which are visible
* @param {ChartEvent} event - the event we are find things at
* @param {Object} options - interaction options to use
* @return {AnnotationElement[]} - elements that are found (only 1 element)
*/
nearest(state, event, options) {
return getNearestItem(state, event, options);
nearest(visibleElements, event, options) {
return getNearestItem(visibleElements, event, options);
},
/**
* x mode returns the elements that hit-test at the current x coordinate
* @param {Object} state - the state of the plugin
* @param {AnnotationElement[]} visibleElements - annotation elements which are visible
* @param {ChartEvent} event - the event we are find things at
* @param {Object} options - interaction options to use
* @return {AnnotationElement[]} - elements that are found
*/
x(state, event, options) {
return filterElements(state, event, {intersect: options.intersect, axis: 'x'});
x(visibleElements, event, options) {
return filterElements(visibleElements, event, {intersect: options.intersect, axis: 'x'});
},

/**
* y mode returns the elements that hit-test at the current y coordinate
* @param {Object} state - the state of the plugin
* @param {AnnotationElement[]} visibleElements - annotation elements which are visible
* @param {ChartEvent} event - the event we are find things at
* @param {Object} options - interaction options to use
* @return {AnnotationElement[]} - elements that are found
*/
y(state, event, options) {
return filterElements(state, event, {intersect: options.intersect, axis: 'y'});
y(visibleElements, event, options) {
return filterElements(visibleElements, event, {intersect: options.intersect, axis: 'y'});
}
}
};

/**
* Returns all elements that hit test based on the event position
* @param {Object} state - the state of the plugin
* @param {AnnotationElement[]} visibleElements - annotation elements which are visible
* @param {ChartEvent} event - the event we are find things at
* @param {Object} options - interaction options to use
* @return {AnnotationElement[]} - elements that are found
*/
export function getElements(state, event, options) {
export function getElements(visibleElements, event, options) {
const mode = interaction.modes[options.mode] || interaction.modes.nearest;
return mode(state, event, options);
return mode(visibleElements, event, options);
}

function inRangeByAxis(element, event, axis) {
Expand All @@ -79,14 +79,14 @@ function getPointByAxis(event, center, axis) {
return center;
}

function filterElements(state, event, options) {
return state.visibleElements.filter((element) => options.intersect ? element.inRange(event.x, event.y) : inRangeByAxis(element, event, options.axis));
function filterElements(visibleElements, event, options) {
return visibleElements.filter((element) => options.intersect ? element.inRange(event.x, event.y) : inRangeByAxis(element, event, options.axis));
}

function getNearestItem(state, event, options) {
function getNearestItem(visibleElements, event, options) {
let minDistance = Number.POSITIVE_INFINITY;

return filterElements(state, event, options)
return filterElements(visibleElements, event, options)
.reduce((nearestItems, element) => {
const center = element.getCenterPoint();
const evenPoint = getPointByAxis(event, center, options.axis);
Expand Down
3 changes: 2 additions & 1 deletion test/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {acquireChart, addMatchers, releaseCharts, specsFromFixtures, triggerMouseEvent, afterEvent} from 'chartjs-test-utils';
import {testEvents, eventPoint0, getCenterPoint} from './events';
import {createCanvas, getAnnotationElements, scatterChart, stringifyObject, interactionData, getQuadraticXY, getQuadraticAngle, drawStar} from './utils';
import {createCanvas, getAnnotationElements, getAnnotationInteractedElements, scatterChart, stringifyObject, interactionData, getQuadraticXY, getQuadraticAngle, drawStar} from './utils';
import * as helpers from '../src/helpers';

window.helpers = helpers;
Expand All @@ -14,6 +14,7 @@ window.getCenterPoint = getCenterPoint;
window.createCanvas = createCanvas;
window.drawStar = drawStar;
window.getAnnotationElements = getAnnotationElements;
window.getAnnotationInteractedElements = getAnnotationInteractedElements;
window.scatterChart = scatterChart;
window.stringifyObject = stringifyObject;
window.interactionData = interactionData;
Expand Down
2 changes: 2 additions & 0 deletions test/integration/ts/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ const chart = new Chart('id', {
},
plugins: [Annotation]
});

const elements = Annotation.getAnnotations(chart);
11 changes: 6 additions & 5 deletions test/specs/box.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,11 @@ describe('Box annotation', function() {
};

const chart = window.scatterChart(10, 10, {outer, inner});
const state = window['chartjs-plugin-annotation']._getState(chart);
const elements = window.getAnnotationElements(chart);
const visible = elements.filter(el => !el.skip && el.options.display);
const interactionOpts = {};
const outerEl = window.getAnnotationElements(chart)[0];
const innerEl = window.getAnnotationElements(chart)[1];
const outerEl = elements[0];
const innerEl = elements[1];

it('should return the right amount of annotation elements', function() {
for (const interaction of window.interactionData) {
Expand All @@ -120,8 +121,8 @@ describe('Box annotation', function() {
for (let i = 0; i < points.length; i++) {
const point = points[i];
const elementsCount = elementsCounts[i];
const elements = state._getElements(state, point, interactionOpts);
expect(elements.length).withContext(`with interaction mode ${mode}, axis ${axis}, intersect ${intersect}, {x: ${point.x.toFixed(1)}, y: ${point.y.toFixed(1)}}`).toEqual(elementsCount);
const els = window.getAnnotationInteractedElements(visible, point, interactionOpts);
expect(els.length).withContext(`with interaction mode ${mode}, axis ${axis}, intersect ${intersect}, {x: ${point.x.toFixed(1)}, y: ${point.y.toFixed(1)}}`).toEqual(elementsCount);
}
});
}
Expand Down
11 changes: 6 additions & 5 deletions test/specs/ellipse.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,11 @@ describe('Ellipse annotation', function() {
};

const chart = window.scatterChart(10, 10, {outer, inner});
const state = window['chartjs-plugin-annotation']._getState(chart);
const elements = window.getAnnotationElements(chart);
const visible = elements.filter(el => !el.skip && el.options.display);
const interactionOpts = {};
const outerEl = window.getAnnotationElements(chart)[0];
const innerEl = window.getAnnotationElements(chart)[1];
const outerEl = elements[0];
const innerEl = elements[1];

it('should return the right amount of annotation elements', function() {
for (const interaction of window.interactionData) {
Expand All @@ -120,8 +121,8 @@ describe('Ellipse annotation', function() {
const point = points[i];
const elementsCount = elementsCounts[i];
const {x, y} = rotated(point, point.el.getCenterPoint(), rotation / 180 * Math.PI);
const elements = state._getElements(state, {x, y}, interactionOpts);
expect(elements.length).withContext(`with rotation ${rotation}, interaction mode ${mode}, axis ${axis}, intersect ${intersect}, {x: ${x.toFixed(1)}, y: ${y.toFixed(1)}`).toEqual(elementsCount);
const els = window.getAnnotationInteractedElements(visible, {x, y}, interactionOpts, true);
expect(els.length).withContext(`with rotation ${rotation}, interaction mode ${mode}, axis ${axis}, intersect ${intersect}, {x: ${x.toFixed(1)}, y: ${y.toFixed(1)}`).toEqual(elementsCount);
}
});
}
Expand Down
11 changes: 6 additions & 5 deletions test/specs/label.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,11 @@ describe('Label annotation', function() {
};

const chart = window.scatterChart(10, 10, {outer, inner});
const state = window['chartjs-plugin-annotation']._getState(chart);
const elements = window.getAnnotationElements(chart);
const visible = elements.filter(el => !el.skip && el.options.display);
const interactionOpts = {};
const outerEl = window.getAnnotationElements(chart)[0];
const innerEl = window.getAnnotationElements(chart)[1];
const outerEl = elements[0];
const innerEl = elements[1];

it('should return the right amount of annotation elements', function() {
for (const interaction of window.interactionData) {
Expand All @@ -101,8 +102,8 @@ describe('Label annotation', function() {
for (let i = 0; i < points.length; i++) {
const point = points[i];
const elementsCount = elementsCounts[i];
const elements = state._getElements(state, point, interactionOpts);
expect(elements.length).withContext(`with interaction mode ${mode}, axis ${axis}, intersect ${intersect}, {x: ${point.x.toFixed(1)}, y: ${point.y.toFixed(1)}`).toEqual(elementsCount);
const els = window.getAnnotationInteractedElements(visible, point, interactionOpts);
expect(els.length).withContext(`with interaction mode ${mode}, axis ${axis}, intersect ${intersect}, {x: ${point.x.toFixed(1)}, y: ${point.y.toFixed(1)}`).toEqual(elementsCount);
}
});
}
Expand Down
22 changes: 12 additions & 10 deletions test/specs/line.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,13 @@ describe('Line annotation', function() {
};

const chart = window.scatterChart(10, 10, {outer, inner});
const state = window['chartjs-plugin-annotation']._getState(chart);
const elements = window.getAnnotationElements(chart);
const visible = elements.filter(el => !el.skip && el.options.display);
const interactionOpts = {};
const outerEl = window.getAnnotationElements(chart)[0];
const outerEl = elements[0];
const outCenter = outerEl.getCenterPoint();
const outHBordeWidth = outerEl.options.borderWidth / 2;
const innerEl = window.getAnnotationElements(chart)[1];
const innerEl = elements[1];
const inCenter = outerEl.getCenterPoint();
const inHBordeWidth = innerEl.options.borderWidth / 2;

Expand All @@ -147,8 +148,8 @@ describe('Line annotation', function() {
for (let i = 0; i < points.length; i++) {
const point = points[i];
const elementsCount = elementsCounts[i];
const elements = state._getElements(state, point, interactionOpts);
expect(elements.length).withContext(`with interaction mode ${mode}, axis ${axis}, intersect ${intersect}, {x: ${point.x.toFixed(1)}, y: ${point.y.toFixed(1)}`).toEqual(elementsCount);
const els = window.getAnnotationInteractedElements(visible, point, interactionOpts);
expect(els.length).withContext(`with interaction mode ${mode}, axis ${axis}, intersect ${intersect}, {x: ${point.x.toFixed(1)}, y: ${point.y.toFixed(1)}`).toEqual(elementsCount);
}
});
}
Expand Down Expand Up @@ -186,11 +187,12 @@ describe('Line annotation', function() {
};

const chart = window.scatterChart(10, 10, {outer, inner});
const state = window['chartjs-plugin-annotation']._getState(chart);
const elements = window.getAnnotationElements(chart);
const visible = elements.filter(el => !el.skip && el.options.display);
const interactionOpts = {};
const outerEl = window.getAnnotationElements(chart)[0];
const outerEl = elements[0];
const outCenter = outerEl.getCenterPoint();
const innerEl = window.getAnnotationElements(chart)[1];
const innerEl = elements[1];

it('should return the right amount of annotation elements', function() {
for (const interaction of window.interactionData) {
Expand All @@ -211,8 +213,8 @@ describe('Line annotation', function() {
for (let i = 0; i < points.length; i++) {
const point = points[i];
const elementsCount = elementsCounts[i];
const elements = state._getElements(state, point, interactionOpts);
expect(elements.length).withContext(`with interaction mode ${mode}, axis ${axis}, intersect ${intersect}, {x: ${point.x.toFixed(1)}, y: ${point.y.toFixed(1)}`).toEqual(elementsCount);
const els = window.getAnnotationInteractedElements(visible, point, interactionOpts);
expect(els.length).withContext(`with interaction mode ${mode}, axis ${axis}, intersect ${intersect}, {x: ${point.x.toFixed(1)}, y: ${point.y.toFixed(1)}`).toEqual(elementsCount);
}
});
}
Expand Down
11 changes: 6 additions & 5 deletions test/specs/point.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,11 @@ describe('Point annotation', function() {
};

const chart = window.scatterChart(10, 10, {outer, inner});
const state = window['chartjs-plugin-annotation']._getState(chart);
const elements = window.getAnnotationElements(chart);
const visible = elements.filter(el => !el.skip && el.options.display);
const interactionOpts = {};
const outerEl = window.getAnnotationElements(chart)[0];
const innerEl = window.getAnnotationElements(chart)[1];
const outerEl = elements[0];
const innerEl = elements[1];

it('should return the right amount of annotation elements', function() {
for (const interaction of window.interactionData) {
Expand All @@ -116,8 +117,8 @@ describe('Point annotation', function() {
for (let i = 0; i < points.length; i++) {
const point = points[i];
const elementsCount = elementsCounts[i];
const elements = state._getElements(state, point, interactionOpts);
expect(elements.length).withContext(`with interaction mode ${mode}, axis ${axis}, intersect ${intersect}, {x: ${point.x.toFixed(1)}, y: ${point.y.toFixed(1)}`).toEqual(elementsCount);
const els = window.getAnnotationInteractedElements(visible, point, interactionOpts);
expect(els.length).withContext(`with interaction mode ${mode}, axis ${axis}, intersect ${intersect}, {x: ${point.x.toFixed(1)}, y: ${point.y.toFixed(1)}`).toEqual(elementsCount);
}
});
}
Expand Down
11 changes: 6 additions & 5 deletions test/specs/polygon.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,11 @@ describe('Polygon annotation', function() {
};

const chart = window.scatterChart(10, 10, {outer, inner});
const state = window['chartjs-plugin-annotation']._getState(chart);
const elements = window.getAnnotationElements(chart);
const visible = elements.filter(el => !el.skip && el.options.display);
const interactionOpts = {};
const outerEl = window.getAnnotationElements(chart)[0];
const innerEl = window.getAnnotationElements(chart)[1];
const outerEl = elements[0];
const innerEl = elements[1];

it('should return the right amount of annotation elements', function() {
for (const interaction of window.interactionData) {
Expand All @@ -162,8 +163,8 @@ describe('Polygon annotation', function() {
const point = points[i];
const elementsCount = elementsCounts[i];
const {x, y} = rotated(point, point.el.getCenterPoint(), rotation / 180 * Math.PI);
const elements = state._getElements(state, {x, y}, interactionOpts);
expect(elements.length).withContext(`with rotation ${rotation}, interaction mode ${mode}, axis ${axis}, intersect ${intersect}, {x: ${point.x.toFixed(1)}, y: ${point.y.toFixed(1)}`).toEqual(elementsCount);
const els = window.getAnnotationInteractedElements(visible, {x, y}, interactionOpts);
expect(els.length).withContext(`with rotation ${rotation}, interaction mode ${mode}, axis ${axis}, intersect ${intersect}, {x: ${point.x.toFixed(1)}, y: ${point.y.toFixed(1)}`).toEqual(elementsCount);
}
});
}
Expand Down
8 changes: 7 additions & 1 deletion test/utils.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {getElements} from '../src/interaction';

export function getQuadraticXY(t, sx, sy, cp1x, cp1y, ex, ey) {
return {
x: (1 - t) * (1 - t) * sx + 2 * (1 - t) * t * cp1x + t * t * ex,
Expand Down Expand Up @@ -46,7 +48,11 @@ export function drawStar(ctx, x, y, radius, spikes, inset) {
}

export function getAnnotationElements(chart) {
return window['chartjs-plugin-annotation']._getState(chart).elements;
return window['chartjs-plugin-annotation'].getAnnotations(chart);
}

export function getAnnotationInteractedElements(visibleElements, event, options) {
return getElements(visibleElements, event, options);
}

export function scatterChart(xMax, yMax, annotations) {
Expand Down
7 changes: 5 additions & 2 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ChartType, Plugin } from 'chart.js';
import { Chart, ChartType, Plugin } from 'chart.js';
import { AnnotationPluginOptions, BoxAnnotationOptions, EllipseAnnotationOptions, LabelAnnotationOptions, LineAnnotationOptions, PointAnnotationOptions, PolygonAnnotationOptions } from './options';
import { AnnotationElement } from './element';

declare module 'chart.js' {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand All @@ -17,7 +18,9 @@ declare module 'chart.js' {
}
}

declare const Annotation: Plugin;
declare const Annotation: Plugin & {
getAnnotations(chart: Chart): AnnotationElement[];
};

export default Annotation;

Expand Down
2 changes: 2 additions & 0 deletions types/tests/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,5 @@ const chart = new Chart('id', {
},
plugins: [Annotation]
});

const elements = Annotation.getAnnotations(chart);