Skip to content

Commit

Permalink
Enable sub elements
Browse files Browse the repository at this point in the history
  • Loading branch information
kurkle committed Dec 17, 2021
1 parent 70a2282 commit 8532960
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 43 deletions.
14 changes: 14 additions & 0 deletions docs/samples/polygon/basic.md
Expand Up @@ -123,6 +123,20 @@ var actions = [
});
chart.update();
}
},
{
name: 'Add a side to annotation 1',
handler: function(chart) {
chart.options.plugins.annotation.annotations.annotation1.sides++;
chart.update();
}
},
{
name: 'Remove a side to annotation 1',
handler: function(chart) {
chart.options.plugins.annotation.annotations.annotation1.sides--;
chart.update();
}
}
];

Expand Down
21 changes: 20 additions & 1 deletion src/annotation.js
Expand Up @@ -161,10 +161,29 @@ function updateElements(chart, state, options, mode) {
if (!el || !(el instanceof elementClass)) {
el = elements[i] = new elementClass();
}
const opts = resolveAnnotationOptions(annotation.setContext(getContext(chart, el, annotation)));
const resolver = annotation.setContext(getContext(chart, el, annotation));
const opts = resolveAnnotationOptions(resolver);
const properties = el.resolveElementProperties(chart, opts);
const subDefs = properties.elements;

properties.skip = isNaN(properties.x) || isNaN(properties.y);
properties.options = opts;

if (subDefs) {
const elems = el.elements || (el.elements = []);
elems.length = subDefs.length;
for (let j = 0; j < subDefs.length; j++) {
const def = subDefs[j];
const subProps = def.properties;
const subClass = annotationTypes[resolveType(def.type)];
const subEl = elems[j] || (elems[j] = new subClass());
const subOpts = resolveAnnotationOptions((resolver[def.optionScope]).override(def));
subProps.options = subOpts;
animations.update(subEl, subProps);
}
delete properties.elements;
}

animations.update(el, properties);
}
}
Expand Down
80 changes: 38 additions & 42 deletions src/types/polygon.js
@@ -1,30 +1,30 @@
import {Element} from 'chart.js';
import {PI, RAD_PER_DEG, isNumber} from 'chart.js/helpers';
import {PI, RAD_PER_DEG} from 'chart.js/helpers';
import {setBorderStyle, resolvePointPosition, getElementCenterPoint} from '../helpers';

export default class PolygonAnnotation extends Element {

inRange(mouseX, mouseY, useFinalPosition) {
const vertices = getVertices(this.getProps(['x', 'y'], useFinalPosition), this.options);
return vertices && vertices.length > 0 && pointIsInPolygon(vertices, mouseX, mouseY);
inRange(x, y) {
return pointIsInPolygon(this.elements, x, y);
}

getCenterPoint(useFinalPosition) {
return getElementCenterPoint(this, useFinalPosition);
}

draw(ctx) {
const {x, y, options} = this;
const vertices = getVertices({x, y}, options);
let vertex = vertices[0];
const {elements, options} = this;
ctx.save();
ctx.beginPath();
ctx.fillStyle = options.backgroundColor;
const stroke = setBorderStyle(ctx, options);
ctx.moveTo(vertex.x, vertex.y);
for (let i = 1; i < vertices.length; i++) {
vertex = vertices[i];
ctx.lineTo(vertex.x, vertex.y);
let first = true;
for (const el of elements) {
if (first) {
ctx.moveTo(el.x, el.y);
first = false;
} else {
ctx.lineTo(el.x, el.y);
}
}
ctx.closePath();
ctx.fill();
Expand All @@ -33,15 +33,30 @@ export default class PolygonAnnotation extends Element {
ctx.stroke();
}
ctx.restore();

for (const el of elements) {
el.draw(ctx);
}
}

resolveElementProperties(chart, options) {
if (isNumber(options.sides) && options.sides >= 1) {
return resolvePointPosition(chart, options);
const {x, y} = resolvePointPosition(chart, options);
const {sides, radius, rotation} = options;
const elements = [];
const angle = (2 * PI) / sides;
let rad = rotation * RAD_PER_DEG;
for (let i = 0; i < sides; i++, rad += angle) {
elements.push({
type: 'point',
optionScope: 'point',
properties: {
x: x + Math.sin(rad) * radius,
y: y - Math.cos(rad) * radius
}
});
}
return {options: {}};
return {x, y, elements};
}

}

PolygonAnnotation.id = 'polygonAnnotation';
Expand All @@ -54,6 +69,9 @@ PolygonAnnotation.defaults = {
borderJoinStyle: 'miter',
borderWidth: 1,
display: true,
point: {
radius: 0
},
radius: 10,
rotation: 0,
sides: 3,
Expand All @@ -74,33 +92,11 @@ PolygonAnnotation.defaultRoutes = {
backgroundColor: 'color'
};

function getVertices(point, options) {
const {sides, radius} = options;
let angle = (2 * PI) / sides;
let rad = options.rotation * RAD_PER_DEG;
const vertices = new Array();
addVertex(vertices, point, rad, radius);
for (let i = 0; i < sides; i++) {
rad += angle;
addVertex(vertices, point, rad, radius);
}
return vertices;
}

function addVertex(array, point, rad, radius) {
array.push({
x: point.x + Math.sin(rad) * radius,
y: point.y - Math.cos(rad) * radius
});
}

function pointIsInPolygon(vertices, x, y) {
function pointIsInPolygon(points, x, y) {
let isInside = false;
let i = 0;
let j = vertices.length - 1;
for (i, j; i < vertices.length; j = i++) {
if ((vertices[i].y > y) !== (vertices[j].y > y) &&
x < (vertices[j].x - vertices[i].x) * (y - vertices[i].y) / (vertices[j].y - vertices[i].y) + vertices[i].x) {
for (let i = 0, j = points.length - 1; i < points.length; j = i++) {
if ((points[i].y > y) !== (points[j].y > y) &&
x < (points[j].x - points[i].x) * (y - points[i].y) / (points[j].y - points[i].y) + points[i].x) {
isInside = !isInside;
}
}
Expand Down
52 changes: 52 additions & 0 deletions test/fixtures/polygon/hexagonWithPoints.js
@@ -0,0 +1,52 @@
module.exports = {
tolerance: 0.0055,
config: {
type: 'scatter',
options: {
scales: {
x: {
display: false,
min: -10,
max: 10
},
y: {
display: false,
min: -10,
max: 10
}
},
plugins: {
legend: false,
annotation: {
drawTime: 'afterDraw',
annotations: {
octagon: {
type: 'polygon',
xScaleID: 'x',
yScaleID: 'y',
xValue: 1,
yValue: 1,
sides: 6,
backgroundColor: 'rgba(153, 153, 102, 0.5)',
borderColor: 'rgb(153, 153, 102)',
borderWidth: 1,
radius: 50,
point: {
radius: 3,
backgroundColor: 'red',
borderColor: 'black',
borderWidth: 1
}
}
}
}
}
}
},
options: {
canvas: {
width: 256,
height: 256
}
}
};
Binary file added test/fixtures/polygon/hexagonWithPoints.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 8532960

Please sign in to comment.