Skip to content

Commit 9efd067

Browse files
petewalkercompwright
authored andcommitted
Added tooltip label to line chart (#31)
* Added tooltip label to line chart Originally based on #12. Added an optional Label option to Line Annotation. Updated the documentation to display this. Also added a sample showing how it can work. * Fixed calculations as per comments Moved rendering calculations to lineUpdate function, also fixed a minor reference bug that prevented animations from working at all. * Fixed font bug introduced by last commit * Fixed sample post-update
1 parent 1232eea commit 9efd067

File tree

6 files changed

+411
-7
lines changed

6 files changed

+411
-7
lines changed

README.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,36 @@ Vertical or horizontal lines are supported.
6060

6161
// Line Dash Offset
6262
// https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset
63-
borderDashOffset: 5
63+
borderDashOffset: 5,
64+
65+
label: {
66+
// Background color of label, default below
67+
backgroundColor: 'rgba(0,0,0,0.8)',
68+
// Font family of text, inherits from global
69+
fontFamily: "sans-serif",
70+
// Font size of text, inherits from global
71+
fontSize: 12,
72+
// Font style of text, default below
73+
fontStyle: "bold",
74+
// Font color of text, default below
75+
fontColor: "#fff",
76+
// Padding of label to add left/right, default below
77+
xPadding: 6,
78+
// Padding of label to add top/bottom, default below
79+
yPadding: 6,
80+
// Radius of label rectangle, default below
81+
cornerRadius: 6,
82+
// Anchor position of label on line, can be one of: top, bottom, left, right, center. Default below.
83+
position: "center",
84+
// Adjustment along x-axis (left-right) of label relative to above number (can be negative)
85+
xAdjust: 0,
86+
// Adjustment along y-axis (top-bottom) of label relative to above number (can be negative)
87+
yAdjust: 0,
88+
// Whether the label is enabled and should be displayed
89+
enabled: false,
90+
// Text to display in label - default is null
91+
content: "Test label"
92+
}
6493
}
6594
```
6695

chartjs-plugin-annotation.js

Lines changed: 108 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,27 @@ var annotationPlugin = {
139139
beforeInit: function(chartInstance) {
140140
var options = chartInstance.options;
141141
options.annotation = helpers.configMerge(Chart.Annotation.defaults, options.annotation);
142-
142+
var defaultLabelOptions = {
143+
backgroundColor: 'rgba(0,0,0,0.8)',
144+
fontFamily: options.defaultFontFamily,
145+
fontSize: options.defaultFontSize,
146+
fontStyle: "bold",
147+
fontColor: "#fff",
148+
xPadding: 6,
149+
yPadding: 6,
150+
cornerRadius: 6,
151+
position: "center",
152+
xAdjust: 0,
153+
yAdjust: 0,
154+
enabled: false,
155+
content: null
156+
};
143157
var annotationConfigs = options.annotation.annotations;
144158
if (isArray(annotationConfigs)) {
145159
var annotationObjects = chartInstance._annotationObjects = [];
146160

147161
annotationConfigs.forEach(function(configuration, i) {
162+
configuration.label = helpers.configMerge(defaultLabelOptions, configuration.label);
148163
var Constructor = annotationTypes[configuration.type];
149164
if (Constructor) {
150165
annotationObjects.push(new Constructor({
@@ -198,6 +213,11 @@ module.exports = annotationPlugin;
198213
Chart.pluginService.register(annotationPlugin);
199214

200215
},{"./box.js":2,"./line.js":4,"chart.js":1}],4:[function(require,module,exports){
216+
// Get the chart variable
217+
var Chart = require('chart.js');
218+
Chart = typeof(Chart) === 'function' ? Chart : window.Chart;
219+
var helpers = Chart.helpers;
220+
201221
// Line Annotation implementation
202222
module.exports = function(Chart) {
203223
var horizontalKeyword = 'horizontal';
@@ -224,22 +244,76 @@ module.exports = function(Chart) {
224244
ctx.lineTo(view.x2, view.y2);
225245
ctx.stroke();
226246
ctx.restore();
247+
248+
if (view.labelEnabled && view.labelContent) {
249+
ctx.fillStyle = view.labelBackgroundColor;
250+
// Draw the tooltip
251+
helpers.drawRoundedRectangle(
252+
ctx,
253+
view.labelX - view.labelXPadding, // x
254+
view.labelY - view.labelYPadding, // y
255+
view.labelWidth, // width
256+
view.labelHeight, // height
257+
view.labelCornerRadius // radius
258+
);
259+
ctx.fill();
260+
261+
// Draw the text
262+
ctx.font = helpers.fontString(
263+
view.labelFontSize,
264+
view.labelFontStyle,
265+
view.labelFontFamily
266+
);
267+
ctx.fillStyle = view.labelFontColor;
268+
ctx.textAlign = 'left';
269+
ctx.textBaseline = 'top';
270+
ctx.fillText(
271+
view.labelContent,
272+
view.labelX,
273+
view.labelY
274+
);
275+
}
227276
}
228277
});
229278

230279
function isValid(num) {
231280
return !isNaN(num) && isFinite(num);
232281
}
233282

283+
function calculateLabelPosition(view, width, height) {
284+
var ret = {
285+
x: ((view.x1 + view.x2 - width) / 2),
286+
y: ((view.y1 + view.y2 - height) / 2)
287+
};
288+
switch (view.labelPosition) {
289+
case "top":
290+
ret.y = view.y1 > view.y2 ? view.y2 : view.y1;
291+
break;
292+
case "left":
293+
ret.x = view.x1 > view.x2 ? view.x1 : view.x2;
294+
break;
295+
case "bottom":
296+
ret.y = view.y1 > view.y2 ? view.y1 : view.y2;
297+
break;
298+
case "right":
299+
ret.x = view.x1 > view.x2 ? view.x2 : view.x1;
300+
break;
301+
}
302+
ret.x += view.labelXAdjust;
303+
ret.y += view.labelYAdjust;
304+
return ret;
305+
}
306+
234307
function lineUpdate(obj, options, chartInstance) {
235-
var model = obj._model = obj._model || {};
308+
var model = obj._model = helpers.clone(obj._model) || {};
236309

237310
var scale = chartInstance.scales[options.scaleID];
238311
var pixel = scale ? scale.getPixelForValue(options.value) : NaN;
239312
var endPixel = scale && isValid(options.endValue) ? scale.getPixelForValue(options.endValue) : NaN;
240313
if (isNaN(endPixel))
241314
endPixel = pixel;
242315
var chartArea = chartInstance.chartArea;
316+
var ctx = chartInstance.chart.ctx;
243317

244318
if (!isNaN(pixel)) {
245319
if (options.mode == horizontalKeyword) {
@@ -255,6 +329,37 @@ module.exports = function(Chart) {
255329
}
256330
}
257331

332+
// Figure out the label:
333+
model.labelBackgroundColor = options.label.backgroundColor;
334+
model.labelFontFamily = options.label.fontFamily;
335+
model.labelFontSize = options.label.fontSize;
336+
model.labelFontStyle = options.label.fontStyle;
337+
model.labelFontColor = options.label.fontColor;
338+
model.labelXPadding = options.label.xPadding;
339+
model.labelYPadding = options.label.yPadding;
340+
model.labelCornerRadius = options.label.cornerRadius;
341+
model.labelPosition = options.label.position;
342+
model.labelXAdjust = options.label.xAdjust;
343+
model.labelYAdjust = options.label.yAdjust;
344+
model.labelEnabled = options.label.enabled;
345+
model.labelContent = options.label.content;
346+
347+
ctx.font = helpers.fontString(
348+
model.labelFontSize,
349+
model.labelFontStyle,
350+
model.labelFontFamily
351+
);
352+
var text = ctx.measureText(model.labelContent);
353+
var position = calculateLabelPosition(
354+
model,
355+
text.width,
356+
model.labelFontSize
357+
);
358+
model.labelX = position.x;
359+
model.labelY = position.y;
360+
model.labelWidth = text.width + (2 * model.labelXPadding);
361+
model.labelHeight = model.labelFontSize + (2 * model.labelYPadding)
362+
258363
model.borderColor = options.borderColor;
259364
model.borderWidth = options.borderWidth;
260365
model.borderDash = options.borderDash || [];
@@ -268,4 +373,4 @@ module.exports = function(Chart) {
268373
};
269374
};
270375

271-
},{}]},{},[3]);
376+
},{"chart.js":1}]},{},[3]);

chartjs-plugin-annotation.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)