Skip to content

Commit

Permalink
Callout position calculated when label is drawn (#731)
Browse files Browse the repository at this point in the history
* Callout position calculated when label is drawn

* adds sample to doc

* removes tolerance
  • Loading branch information
stockiNail authored May 16, 2022
1 parent 559780b commit 7e85eef
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 6 deletions.
8 changes: 7 additions & 1 deletion docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,13 @@ module.exports = {
'charts/line',
],
},
'interaction',
{
title: 'Interaction',
children: [
'interaction/interaction',
'interaction/dragging',
],
},
'utils',
]
}
Expand Down
195 changes: 195 additions & 0 deletions docs/samples/interaction/dragging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
# Dragging annotations

```js chart-editor
// <block:setup:6>
Utils.srand(8);

const data = {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [{
type: 'line',
label: 'Dataset 1',
borderColor: 'rgb(54, 162, 235)',
borderWidth: 2,
fill: false,
data: Utils.numbers({count: 7, min: 0, max: 100}),
}]
};
// </block:setup>

// <block:annotation1:1>
const annotation1 = {
type: 'box',
backgroundColor: 'rgba(165, 214, 167, 0.2)',
borderColor: 'rgb(165, 214, 167)',
borderWidth: 2,
label: {
display: true,
content: ['Box annotation', 'to drag'],
textAlign: 'center'
},
xMax: 'May',
xMin: 'April',
xScaleID: 'x',
yMax: 75,
yMin: 25,
yScaleID: 'y'
};
// </block:annotation1>

// <block:annotation2:2>
const annotation2 = {
type: 'label',
backgroundColor: 'rgba(255, 99, 132, 0.25)',
borderWidth: 3,
borderColor: 'black',
content: ['Label annotation', 'to drag'],
callout: {
display: true,
borderColor: 'black',
},
xValue: 1,
yValue: 40
};
// </block:annotation2>

// <block:annotation3:3>
const annotation3 = {
type: 'point',
backgroundColor: 'rgba(0, 255, 255, 0.4)',
borderWidth: 2,
borderColor: 'black',
radius: 20,
xValue: 'March',
yValue: 50
};
// </block:annotation3>

// <block:annotation4:4>
const annotation4 = {
type: 'polygon',
backgroundColor: 'rgba(150, 0, 0, 0.25)',
borderWidth: 2,
borderColor: 'black',
radius: 50,
sides: 6,
xValue: 'June',
yValue: 20
};
// </block:annotation4>

// <block:utils:7>
let element;
let lastEvent;

const drag = function(moveX, moveY) {
element.x += moveX;
element.y += moveY;
element.x2 += moveX;
element.y2 += moveY;
element.centerX += moveX;
element.centerY += moveY;
if (element.elements && element.elements.length) {
for (const subEl of element.elements) {
subEl.x += moveX;
subEl.y += moveY;
subEl.x2 += moveX;
subEl.y2 += moveY;
subEl.centerX += moveX;
subEl.centerY += moveY;
subEl.bX += moveX;
subEl.bY += moveY;
}
}
};

const handleElementDragging = function(event) {
if (!lastEvent || !element) {
return;
}
const moveX = event.x - lastEvent.x;
const moveY = event.y - lastEvent.y;
drag(moveX, moveY);
lastEvent = event;
return true;
};

const handleDrag = function(event) {
if (element) {
switch (event.type) {
case 'mousemove':
return handleElementDragging(event);
case 'mouseout':
case 'mouseup':
lastEvent = undefined;
break;
case 'mousedown':
lastEvent = event;
break;
default:
}
}
};
// </block:dragger>

// <block:dragger:5>
const dragger = {
id: 'dragger',
beforeEvent(chart, args, options) {
if (handleDrag(args.event)) {
args.changed = true;
return;
}
}
};
// </block:dragger>

/* <block:config:0> */
const config = {
type: 'line',
plugins: [dragger],
data,
options: {
events: ['mousedown', 'mouseup', 'mousemove', 'mouseout'],
scales: {
y: {
beginAtZero: true,
min: 0,
max: 100
}
},
plugins: {
annotation: {
enter(ctx) {
element = ctx.element;
},
leave() {
element = undefined;
lastEvent = undefined;
},
annotations: {
annotation1,
annotation2,
annotation3,
annotation4
}
}
}
}
};
/* </block:config> */

const actions = [
{
name: 'Reset dragging',
handler: function(chart) {
chart.update();
}
}
];

module.exports = {
actions: actions,
config: config,
};
```
File renamed without changes.
9 changes: 4 additions & 5 deletions src/types/label.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,12 @@ export default class LabelAnnotation extends Element {
const padding = toPadding(options.padding);
const labelSize = measureLabelSize(chart.ctx, options);
const boxSize = measureRect(point, labelSize, options, padding);
const properties = {
return {
pointX: point.x,
pointY: point.y,
...boxSize,
rotation: options.rotation
};
properties.calloutPosition = options.callout.display && resolveCalloutPosition(properties, options.callout, options.rotation);
return properties;
}
}

Expand Down Expand Up @@ -143,11 +141,12 @@ function calculatePosition(start, size, adjust = 0, position) {
}

function drawCallout(ctx, element) {
const {pointX, pointY, calloutPosition, options} = element;
const {pointX, pointY, options} = element;
const callout = options.callout;
const calloutPosition = callout && callout.display && resolveCalloutPosition(element, callout, options.rotation);
if (!calloutPosition || element.inRange(pointX, pointY)) {
return;
}
const callout = options.callout;

ctx.save();
ctx.beginPath();
Expand Down

0 comments on commit 7e85eef

Please sign in to comment.