Skip to content

Commit

Permalink
Polygon: change event tests to inRange tests (#651)
Browse files Browse the repository at this point in the history
* Polygon: change event tests to inRange tests

* fixes polygon inRange checking the radius

* adds borderWidth: 0 on some annotations

* removes cycles on borderwidth because useless

* uses getCenterPoint

* removes storing of the vertices
  • Loading branch information
stockiNail authored Jan 23, 2022
1 parent 45f0e15 commit eeae492
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 78 deletions.
2 changes: 1 addition & 1 deletion src/types/polygon.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {setBorderStyle, resolvePointPosition, getElementCenterPoint, setShadowSt

export default class PolygonAnnotation extends Element {
inRange(mouseX, mouseY, useFinalPosition) {
return this.elements.length > 1 && pointIsInPolygon(this.elements, mouseX, mouseY, useFinalPosition);
return this.options.radius >= 0.1 && this.elements.length > 1 && pointIsInPolygon(this.elements, mouseX, mouseY, useFinalPosition);
}

getCenterPoint(useFinalPosition) {
Expand Down
178 changes: 101 additions & 77 deletions test/specs/polygon.spec.js
Original file line number Diff line number Diff line change
@@ -1,91 +1,115 @@
describe('Polygon annotation', function() {
describe('auto', jasmine.fixtures('polygon'));

const eventIn = function(xScale, yScale, element) {
const options = element.options;
const adjust = options.borderWidth / 2 - 1;
return {x: element.x, y: element.y - element.height / 2 - adjust};
};
const eventOut = function(xScale, yScale, element) {
const options = element.options;
const adjust = options.borderWidth / 2 + 1;
return {x: element.x, y: element.y - element.height / 2 - adjust};
};

window.testEvents({
type: 'polygon',
id: 'test',
xValue: 5,
yValue: 5,
rotation: 0,
radius: 30
}, eventIn, eventOut);

describe('events, removing borderWidth by callback, ', function() {
const chartConfig = {
type: 'scatter',
options: {
animation: false,
scales: {
x: {
display: false,
min: 0,
max: 10
},
y: {
display: false,
min: 0,
max: 10
}
},
plugins: {
legend: false,
annotation: {
annotations: {
polygon: {
type: 'polygon',
xValue: 5,
yValue: 5,
radius: 20,
borderWidth: 10
}
}
}
}
},
describe('inRange', function() {
const annotation1 = {
type: 'polygon',
xValue: 1,
yValue: 1,
borderWidth: 0,
sides: 3,
radius: 30
};
const annotation2 = {
type: 'polygon',
xValue: 2,
yValue: 2,
borderWidth: 10,
sides: 4,
radius: 5
};
const annotation3 = {
type: 'polygon',
xValue: 3,
yValue: 3,
borderWidth: 0,
sides: 5,
radius: 27
};
const annotation4 = {
type: 'polygon',
xValue: 4,
yValue: 4,
sides: 3,
borderWidth: 10,
rotation: 21,
radius: 20
};
const annotation5 = {
type: 'polygon',
xValue: 5,
yValue: 5,
sides: 4,
borderWidth: 0,
rotation: 131,
radius: 33
};
const annotation6 = {
type: 'polygon',
xValue: 6,
yValue: 6,
sides: 5,
borderWidth: 10,
rotation: 241,
radius: 24
};
const annotation7 = {
type: 'polygon',
xValue: 7,
yValue: 7,
sides: 5,
radius: 0
};
const annotation8 = {
type: 'polygon',
xValue: 8,
yValue: 8,
borderWidth: 10,
sides: 5,
radius: 0
};

const polygonOpts = chartConfig.options.plugins.annotation.annotations.polygon;
const chart = window.scatter10x10({annotation1, annotation2, annotation3, annotation4, annotation5, annotation6, annotation7, annotation8});
const elems = window.getAnnotationElements(chart).filter(el => el.options.radius > 0);
const elemsNoRad = window.getAnnotationElements(chart).filter(el => el.options.radius === 0);

it('should detect click event', function(done) {
const clickSpy = jasmine.createSpy('click');
elems.forEach(function(element) {
const center = element.getCenterPoint();
const rotation = element.options.rotation;
const sides = element.options.sides;
const borderWidth = element.options.borderWidth;
const radius = element.height / 2;
const angle = (2 * Math.PI) / sides;

polygonOpts.click = function(ctx) {
if (ctx.element.options.borderWidth) {
delete ctx.element.options.borderWidth;
ctx.chart.draw();
} else {
ctx.element.options.click = clickSpy;
it(`should return true inside element '${element.options.id}'`, function() {
const halfBorder = borderWidth / 2;
let rad = rotation * (Math.PI / 180);
for (let i = 0; i < sides; i++, rad += angle) {
const sin = Math.sin(rad);
const cos = Math.cos(rad);
const x = center.x + sin * (radius + halfBorder - 1);
const y = center.y - cos * (radius + halfBorder - 1);
expect(element.inRange(x, y)).withContext(`sides: ${sides}, rotation: ${rotation}, radius: ${radius}, borderWidth: ${borderWidth}, {x: ${x.toFixed(1)}, y: ${y.toFixed(1)}}`).toEqual(true);
}
};

const chart = window.acquireChart(chartConfig);
const xScale = chart.scales.x;
const yScale = chart.scales.y;
const eventPoint = {x: xScale.getPixelForValue(5), y: yScale.getPixelForValue(5)};

window.afterEvent(chart, 'click', function() {
expect(clickSpy.calls.count()).toBe(0);
});

window.afterEvent(chart, 'click', function() {
expect(clickSpy.calls.count()).toBe(1);
delete polygonOpts.click;
done();
});
window.triggerMouseEvent(chart, 'click', eventPoint);
it(`should return false outside element '${element.options.id}'`, function() {
const halfBorder = borderWidth / 2;
let rad = rotation * (Math.PI / 180);
for (let i = 0; i < sides; i++, rad += angle) {
const sin = Math.sin(rad);
const cos = Math.cos(rad);
const x = center.x + sin * (radius + halfBorder + 1);
const y = center.y - cos * (radius + halfBorder + 1);
expect(element.inRange(x, y)).withContext(`sides: ${sides}, rotation: ${rotation}, radius: ${radius}, borderWidth: ${borderWidth}, {x: ${x.toFixed(1)}, y: ${y.toFixed(1)}}`).toEqual(false);
}
});
window.triggerMouseEvent(chart, 'click', eventPoint);
});

elemsNoRad.forEach(function(element) {
it(`should return false radius is 0 element '${element.options.id}'`, function() {
expect(element.inRange(element.x, element.y)).toEqual(false);
});
});
});
});

0 comments on commit eeae492

Please sign in to comment.