From 3ca46cc49eba509392e5d1f170dd68528567c9d1 Mon Sep 17 00:00:00 2001 From: Ahmed Ali Date: Thu, 26 Jul 2018 10:16:22 +0200 Subject: [PATCH] Allow tooltip on label, hide labels for small slices, innerlabels for big slices --- src/classes.js | 8 +++++--- src/plugin.js | 43 ++++++++++++++++++++++++++++++++++++++++++- src/positioners.js | 4 ++-- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/classes.js b/src/classes.js index 0122910..68782b4 100644 --- a/src/classes.js +++ b/src/classes.js @@ -94,14 +94,15 @@ export default { this.predictedOffset = this.offset; var angle = -((el._model.startAngle + el._model.endAngle) / 2) / (Math.PI); + let innerLabel = el._model.circumference > 0.5; var val = Math.abs(angle - Math.trunc(angle)); if (val > 0.45 && val < 0.55) { this.predictedOffset.x = 0; } else if (angle <= 0.45 && angle >= -0.45) { - this.predictedOffset.x = this.size.width / 2; + this.predictedOffset.x = this.size.width / (innerLabel ? -2 : 2); } else if (angle >= -1.45 && angle <= -0.55) { - this.predictedOffset.x = -this.size.width / 2; + this.predictedOffset.x = -this.size.width / (innerLabel ? -2 : 2); } }; @@ -255,7 +256,8 @@ export default { this.update = function(view, elements, max) { - this.center = positioners.center(view, this.stretch); + let innerLabel = el._model.circumference > 0.5; + this.center = positioners.center(view, this.stretch, innerLabel); this.moveLabelToOffset(); this.center.x += this.offset.x; diff --git a/src/plugin.js b/src/plugin.js index fa3a16a..546933d 100644 --- a/src/plugin.js +++ b/src/plugin.js @@ -13,6 +13,7 @@ outlabeledCharts.init(); Chart.defaults.global.plugins.outlabels = defaults; var LABEL_KEY = defaults.LABEL_KEY; +let activeTooltip = null; function configure(dataset, options) { var override = dataset.outlabels; @@ -35,6 +36,46 @@ Chart.plugins.register({ chart.sizeChanged = true; }, + beforeEvent: function(chart, event, options) { + const { + x, + y + } = event; + + const { + tooltipToggle, + toggleOffDistance + } = options; + + const elems = chart.getDatasetMeta(0).data; + let center, data; + + if (activeTooltip && (Math.abs(activeTooltip.x - x) > toggleOffDistance || Math.abs(activeTooltip.y - y) > toggleOffDistance)) { + tooltipToggle(null, null); + activeTooltip = null; + } + for (let i = 0; i < elems.length; i++) { + if (!elems[i].$outlabels) { + continue; + } + const within = elems[i].$outlabels.containsPoint({ + x: event.x, + y: event.y, + }); + if (within) { + center = elems[i].$outlabels.center; + const index = elems[i]._index; + data = chart.data.labels[index]; + tooltipToggle(center, data); + activeTooltip = center; + return; + } + } + + return; + }, + + afterDatasetUpdate: function(chart, args, options) { var labels = chart.config.data.labels; var dataset = chart.data.datasets[args.index]; @@ -52,7 +93,7 @@ Chart.plugins.register({ percent = dataset.data[i] / args.meta.total; newLabel = null; - if (display && el && !el.hidden) { + if (display && el && !el.hidden && el._model.circumference > options.tooltipCutoff) { try { context = { chart: chart, diff --git a/src/positioners.js b/src/positioners.js index b1d3dbd..8c917aa 100644 --- a/src/positioners.js +++ b/src/positioners.js @@ -1,13 +1,13 @@ 'use strict'; export default { - center: function(arc, stretch) { + center: function(arc, stretch, invert) { var angle = (arc.startAngle + arc.endAngle) / 2; var cosA = Math.cos(angle); var sinA = Math.sin(angle); var d = arc.outerRadius; - var stretchedD = d + stretch; + var stretchedD = invert ? d - stretch : d + stretch; return { x: arc.x + cosA * stretchedD, y: arc.y + sinA * stretchedD,