Skip to content

Commit 7e85eef

Browse files
authored
Callout position calculated when label is drawn (#731)
* Callout position calculated when label is drawn * adds sample to doc * removes tolerance
1 parent 559780b commit 7e85eef

File tree

4 files changed

+206
-6
lines changed

4 files changed

+206
-6
lines changed

docs/.vuepress/config.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,13 @@ module.exports = {
173173
'charts/line',
174174
],
175175
},
176-
'interaction',
176+
{
177+
title: 'Interaction',
178+
children: [
179+
'interaction/interaction',
180+
'interaction/dragging',
181+
],
182+
},
177183
'utils',
178184
]
179185
}
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# Dragging annotations
2+
3+
```js chart-editor
4+
// <block:setup:6>
5+
Utils.srand(8);
6+
7+
const data = {
8+
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
9+
datasets: [{
10+
type: 'line',
11+
label: 'Dataset 1',
12+
borderColor: 'rgb(54, 162, 235)',
13+
borderWidth: 2,
14+
fill: false,
15+
data: Utils.numbers({count: 7, min: 0, max: 100}),
16+
}]
17+
};
18+
// </block:setup>
19+
20+
// <block:annotation1:1>
21+
const annotation1 = {
22+
type: 'box',
23+
backgroundColor: 'rgba(165, 214, 167, 0.2)',
24+
borderColor: 'rgb(165, 214, 167)',
25+
borderWidth: 2,
26+
label: {
27+
display: true,
28+
content: ['Box annotation', 'to drag'],
29+
textAlign: 'center'
30+
},
31+
xMax: 'May',
32+
xMin: 'April',
33+
xScaleID: 'x',
34+
yMax: 75,
35+
yMin: 25,
36+
yScaleID: 'y'
37+
};
38+
// </block:annotation1>
39+
40+
// <block:annotation2:2>
41+
const annotation2 = {
42+
type: 'label',
43+
backgroundColor: 'rgba(255, 99, 132, 0.25)',
44+
borderWidth: 3,
45+
borderColor: 'black',
46+
content: ['Label annotation', 'to drag'],
47+
callout: {
48+
display: true,
49+
borderColor: 'black',
50+
},
51+
xValue: 1,
52+
yValue: 40
53+
};
54+
// </block:annotation2>
55+
56+
// <block:annotation3:3>
57+
const annotation3 = {
58+
type: 'point',
59+
backgroundColor: 'rgba(0, 255, 255, 0.4)',
60+
borderWidth: 2,
61+
borderColor: 'black',
62+
radius: 20,
63+
xValue: 'March',
64+
yValue: 50
65+
};
66+
// </block:annotation3>
67+
68+
// <block:annotation4:4>
69+
const annotation4 = {
70+
type: 'polygon',
71+
backgroundColor: 'rgba(150, 0, 0, 0.25)',
72+
borderWidth: 2,
73+
borderColor: 'black',
74+
radius: 50,
75+
sides: 6,
76+
xValue: 'June',
77+
yValue: 20
78+
};
79+
// </block:annotation4>
80+
81+
// <block:utils:7>
82+
let element;
83+
let lastEvent;
84+
85+
const drag = function(moveX, moveY) {
86+
element.x += moveX;
87+
element.y += moveY;
88+
element.x2 += moveX;
89+
element.y2 += moveY;
90+
element.centerX += moveX;
91+
element.centerY += moveY;
92+
if (element.elements && element.elements.length) {
93+
for (const subEl of element.elements) {
94+
subEl.x += moveX;
95+
subEl.y += moveY;
96+
subEl.x2 += moveX;
97+
subEl.y2 += moveY;
98+
subEl.centerX += moveX;
99+
subEl.centerY += moveY;
100+
subEl.bX += moveX;
101+
subEl.bY += moveY;
102+
}
103+
}
104+
};
105+
106+
const handleElementDragging = function(event) {
107+
if (!lastEvent || !element) {
108+
return;
109+
}
110+
const moveX = event.x - lastEvent.x;
111+
const moveY = event.y - lastEvent.y;
112+
drag(moveX, moveY);
113+
lastEvent = event;
114+
return true;
115+
};
116+
117+
const handleDrag = function(event) {
118+
if (element) {
119+
switch (event.type) {
120+
case 'mousemove':
121+
return handleElementDragging(event);
122+
case 'mouseout':
123+
case 'mouseup':
124+
lastEvent = undefined;
125+
break;
126+
case 'mousedown':
127+
lastEvent = event;
128+
break;
129+
default:
130+
}
131+
}
132+
};
133+
// </block:dragger>
134+
135+
// <block:dragger:5>
136+
const dragger = {
137+
id: 'dragger',
138+
beforeEvent(chart, args, options) {
139+
if (handleDrag(args.event)) {
140+
args.changed = true;
141+
return;
142+
}
143+
}
144+
};
145+
// </block:dragger>
146+
147+
/* <block:config:0> */
148+
const config = {
149+
type: 'line',
150+
plugins: [dragger],
151+
data,
152+
options: {
153+
events: ['mousedown', 'mouseup', 'mousemove', 'mouseout'],
154+
scales: {
155+
y: {
156+
beginAtZero: true,
157+
min: 0,
158+
max: 100
159+
}
160+
},
161+
plugins: {
162+
annotation: {
163+
enter(ctx) {
164+
element = ctx.element;
165+
},
166+
leave() {
167+
element = undefined;
168+
lastEvent = undefined;
169+
},
170+
annotations: {
171+
annotation1,
172+
annotation2,
173+
annotation3,
174+
annotation4
175+
}
176+
}
177+
}
178+
}
179+
};
180+
/* </block:config> */
181+
182+
const actions = [
183+
{
184+
name: 'Reset dragging',
185+
handler: function(chart) {
186+
chart.update();
187+
}
188+
}
189+
];
190+
191+
module.exports = {
192+
actions: actions,
193+
config: config,
194+
};
195+
```
File renamed without changes.

src/types/label.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,12 @@ export default class LabelAnnotation extends Element {
4545
const padding = toPadding(options.padding);
4646
const labelSize = measureLabelSize(chart.ctx, options);
4747
const boxSize = measureRect(point, labelSize, options, padding);
48-
const properties = {
48+
return {
4949
pointX: point.x,
5050
pointY: point.y,
5151
...boxSize,
5252
rotation: options.rotation
5353
};
54-
properties.calloutPosition = options.callout.display && resolveCalloutPosition(properties, options.callout, options.rotation);
55-
return properties;
5654
}
5755
}
5856

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

145143
function drawCallout(ctx, element) {
146-
const {pointX, pointY, calloutPosition, options} = element;
144+
const {pointX, pointY, options} = element;
145+
const callout = options.callout;
146+
const calloutPosition = callout && callout.display && resolveCalloutPosition(element, callout, options.rotation);
147147
if (!calloutPosition || element.inRange(pointX, pointY)) {
148148
return;
149149
}
150-
const callout = options.callout;
151150

152151
ctx.save();
153152
ctx.beginPath();

0 commit comments

Comments
 (0)