chart.js-plugin-labels-dv
Advanced tools
| export * from './src/chart-label'; | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../../index.js"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"} |
| import { fontString } from 'chart.js/helpers'; | ||
| var LabelPosition; | ||
| (function (LabelPosition) { | ||
| LabelPosition["OUTSIDE"] = "outside"; | ||
| LabelPosition["BORDER"] = "border"; | ||
| LabelPosition["DEFAULT"] = "default"; | ||
| })(LabelPosition || (LabelPosition = {})); | ||
| var EMPTY_LINE_SEPARATOR = '\n'; | ||
| var SUPPORTED_TYPES = ['pie', 'doughnut', 'polarArea', 'bar']; | ||
| var SUPPORTED_TYPES_MAP = SUPPORTED_TYPES.reduce(function (acc, id) { | ||
| acc[id] = true; | ||
| return acc; | ||
| }, {}); | ||
| var isAllowedType = function (type) { return SUPPORTED_TYPES_MAP[type]; }; | ||
| var isPluginsLabelsDefined = function (options) { | ||
| var _a, _b, _c, _d, _e; | ||
| var chartConfig = (_c = (_b = (_a = options === null || options === void 0 ? void 0 : options._context) === null || _a === void 0 ? void 0 : _a.chart) === null || _b === void 0 ? void 0 : _b.config) === null || _c === void 0 ? void 0 : _c._config; | ||
| return !!((_e = (_d = chartConfig === null || chartConfig === void 0 ? void 0 : chartConfig.options) === null || _d === void 0 ? void 0 : _d.plugins) === null || _e === void 0 ? void 0 : _e.labels); | ||
| }; | ||
| export var PLUGIN_ID = 'labels'; | ||
| export var getChartLabelPlugin = function () { return ({ | ||
| id: PLUGIN_ID, | ||
| beforeDatasetsUpdate: function (chart, args, options) { | ||
| if (!isAllowedType(chart.config.type) || !isPluginsLabelsDefined(options)) { | ||
| return; | ||
| } | ||
| if (!options.length) { | ||
| options = [options]; | ||
| } | ||
| var count = options.length; | ||
| if (!chart._labels || count !== chart._labels.length) { | ||
| chart._labels = options.map(function () { | ||
| return new ChartLabel(); | ||
| }); | ||
| } | ||
| var someOutside = false; | ||
| var maxPadding = 0; | ||
| for (var i = 0; i < count; ++i) { | ||
| var label = chart._labels[i]; | ||
| label.setup(chart, options[i]); | ||
| if (label.options.position === LabelPosition.OUTSIDE) { | ||
| someOutside = true; | ||
| var padding = label.options.fontSize * 1.5 + label.options.outsidePadding; | ||
| if (padding > maxPadding) { | ||
| maxPadding = padding; | ||
| } | ||
| } | ||
| } | ||
| if (someOutside) { | ||
| chart.chartArea.top += maxPadding; | ||
| chart.chartArea.bottom -= maxPadding; | ||
| } | ||
| }, | ||
| afterDatasetUpdate: function (chart, args, options) { | ||
| var _a; | ||
| if (!isAllowedType(chart.config.type) || !isPluginsLabelsDefined(options)) { | ||
| return; | ||
| } | ||
| (_a = chart._labels) === null || _a === void 0 ? void 0 : _a.forEach(function (label) { | ||
| label.args[args.index] = args; | ||
| }); | ||
| }, | ||
| beforeDraw: function (chart, args, options) { | ||
| var _a; | ||
| if (!isAllowedType(chart.config.type) || !isPluginsLabelsDefined(options)) { | ||
| return; | ||
| } | ||
| (_a = chart._labels) === null || _a === void 0 ? void 0 : _a.forEach(function (label) { | ||
| label.barTotalPercentage = {}; | ||
| }); | ||
| }, | ||
| afterDatasetsDraw: function (chart, args, options) { | ||
| var _a; | ||
| if (!isAllowedType(chart.config.type) || !isPluginsLabelsDefined(options)) { | ||
| return; | ||
| } | ||
| (_a = chart._labels) === null || _a === void 0 ? void 0 : _a.forEach(function (label) { | ||
| label.render(); | ||
| }); | ||
| } | ||
| }); }; | ||
| var ChartLabel = (function () { | ||
| function ChartLabel() { | ||
| } | ||
| ChartLabel.prototype.setup = function (chart, options) { | ||
| this.chart = chart; | ||
| this.ctx = chart.ctx; | ||
| this.args = {}; | ||
| this.barTotal = {}; | ||
| var chartOptions = chart.config.options; | ||
| this.options = Object.assign({ | ||
| position: LabelPosition.DEFAULT, | ||
| precision: 0, | ||
| fontSize: chartOptions.font ? chartOptions.font.size : 12, | ||
| fontColor: chartOptions.color || '#333333', | ||
| fontStyle: chartOptions.font ? chartOptions.font.style : 'normal', | ||
| fontFamily: chartOptions.font | ||
| ? chartOptions.font.family | ||
| : '\'Helvetica Neue\', \'Helvetica\', \'Arial\', sans-serif', | ||
| shadowOffsetX: 3, | ||
| shadowOffsetY: 3, | ||
| shadowColor: 'rgba(0,0,0,0.3)', | ||
| shadowBlur: 6, | ||
| images: [], | ||
| outsidePadding: 2, | ||
| textMargin: 2, | ||
| overlap: true | ||
| }, options); | ||
| var config = chart === null || chart === void 0 ? void 0 : chart.config; | ||
| if (config.type === 'bar') { | ||
| this.options.position = LabelPosition.DEFAULT; | ||
| this.options.arc = false; | ||
| this.options.overlap = true; | ||
| } | ||
| }; | ||
| ChartLabel.prototype.render = function () { | ||
| var _this = this; | ||
| this.labelBounds = []; | ||
| this.chart.data.datasets.forEach(function (d, i) { | ||
| return _this.renderToDataset.bind(_this)(d, i); | ||
| }); | ||
| }; | ||
| ChartLabel.prototype.renderToDataset = function (dataset, index) { | ||
| var _this = this; | ||
| this.totalPercentage = 0; | ||
| this.total = null; | ||
| var arg = this.args[index]; | ||
| arg.meta.data.forEach(function (element, index) { | ||
| return _this.renderToElement.bind(_this)(dataset, arg, element, index); | ||
| }); | ||
| }; | ||
| ChartLabel.prototype.renderToElement = function (dataset, arg, element, index) { | ||
| if (!this.shouldRenderToElement(arg.meta, element)) { | ||
| return; | ||
| } | ||
| this.percentage = null; | ||
| var label = this.getLabel(dataset, element, index); | ||
| if (!label) { | ||
| return; | ||
| } | ||
| var ctx = this.ctx; | ||
| ctx.save(); | ||
| var font = fontString(this.options.fontSize, this.options.fontStyle, this.options.fontFamily); | ||
| if (font) { | ||
| ctx.font = font; | ||
| } | ||
| var renderInfo = this.getRenderInfo(element, label); | ||
| if (!this.drawable(element, label, renderInfo)) { | ||
| ctx.restore(); | ||
| return; | ||
| } | ||
| ctx.beginPath(); | ||
| ctx.fillStyle = this.getFontColor(dataset, element, index); | ||
| this.renderLabel(label, renderInfo); | ||
| ctx.restore(); | ||
| }; | ||
| ChartLabel.prototype.renderLabel = function (label, renderInfo) { | ||
| return this.options.arc | ||
| ? this.renderArcLabel(label, renderInfo) | ||
| : this.renderBaseLabel(label, renderInfo); | ||
| }; | ||
| ChartLabel.prototype.renderBaseLabel = function (label, position) { | ||
| var ctx = this.ctx; | ||
| if (typeof label === 'object') { | ||
| ctx.drawImage(label, position.x - label.width / 2, position.y - label.height / 2, label.width, label.height); | ||
| return; | ||
| } | ||
| ctx.save(); | ||
| ctx.textBaseline = 'top'; | ||
| ctx.textAlign = 'center'; | ||
| if (this.options.textShadow) { | ||
| ctx.shadowOffsetX = this.options.shadowOffsetX; | ||
| ctx.shadowOffsetY = this.options.shadowOffsetY; | ||
| ctx.shadowColor = this.options.shadowColor; | ||
| ctx.shadowBlur = this.options.shadowBlur; | ||
| } | ||
| var lines = label.split(EMPTY_LINE_SEPARATOR); | ||
| for (var i = 0; i < lines.length; i++) { | ||
| var y = position.y - | ||
| (this.options.fontSize / 2) * lines.length + | ||
| this.options.fontSize * i; | ||
| ctx.fillText(lines[i], position.x, y); | ||
| } | ||
| ctx.restore(); | ||
| }; | ||
| ChartLabel.prototype.renderArcLabel = function (label, renderInfo) { | ||
| var ctx = this.ctx; | ||
| var radius = renderInfo.radius; | ||
| var view = renderInfo.view; | ||
| ctx.save(); | ||
| ctx.translate(view.x, view.y); | ||
| if (typeof label === 'string') { | ||
| ctx.rotate(renderInfo.startAngle); | ||
| ctx.textBaseline = 'middle'; | ||
| ctx.textAlign = 'left'; | ||
| var max = 0; | ||
| var lines = label.split(EMPTY_LINE_SEPARATOR); | ||
| var widths = []; | ||
| var offset = this.options.position === LabelPosition.BORDER | ||
| ? ((lines.length - 1) * this.options.fontSize) / 2 | ||
| : 0; | ||
| for (var j = 0; j < lines.length; ++j) { | ||
| var metrics = this.ctx.measureText(lines[j]); | ||
| if (metrics.width > max) { | ||
| max = metrics.width; | ||
| } | ||
| widths.push(metrics.width); | ||
| } | ||
| for (var j = 0; j < lines.length; ++j) { | ||
| var line = lines[j]; | ||
| var y = (lines.length - 1 - j) * -this.options.fontSize + offset; | ||
| ctx.save(); | ||
| var padding = (max - widths[j]) / 2; | ||
| ctx.rotate(padding / radius); | ||
| for (var i = 0; i < line.length; i++) { | ||
| var char = line.charAt(i); | ||
| var metrics = this.ctx.measureText(char); | ||
| ctx.save(); | ||
| ctx.translate(0, -1 * radius); | ||
| ctx.fillText(char, 0, y); | ||
| ctx.restore(); | ||
| ctx.rotate(metrics.width / radius); | ||
| } | ||
| ctx.restore(); | ||
| } | ||
| } | ||
| else { | ||
| ctx.rotate((view.startAngle + Math.PI / 2 + renderInfo.endAngle) / 2); | ||
| ctx.translate(0, -1 * radius); | ||
| this.renderLabel(label, { x: 0, y: 0 }); | ||
| } | ||
| ctx.restore(); | ||
| }; | ||
| ChartLabel.prototype.shouldRenderToElement = function (meta, element) { | ||
| return (!meta.hidden && | ||
| (this.options.showZero || this.isChartType(this.chart, 'polarArea') | ||
| ? element.outerRadius !== 0 | ||
| : element.circumference !== 0)); | ||
| }; | ||
| ChartLabel.prototype.getLabel = function (dataset, element, index) { | ||
| var label; | ||
| if (typeof this.options.render === 'function') { | ||
| label = this.options.render({ | ||
| label: this.chart.config.data.labels[index], | ||
| value: dataset.data[index], | ||
| percentage: this.getPercentage(dataset, element, index), | ||
| dataset: dataset, | ||
| index: index | ||
| }); | ||
| } | ||
| else { | ||
| switch (this.options.render) { | ||
| case 'value': | ||
| label = dataset.data[index]; | ||
| break; | ||
| case 'label': | ||
| label = this.chart.config.data.labels[index]; | ||
| break; | ||
| case 'image': | ||
| label = this.options.images[index] | ||
| ? this.loadImage(this.options.images[index]) | ||
| : ''; | ||
| break; | ||
| case 'percentage': | ||
| default: | ||
| label = this.getPercentage(dataset, element, index) + '%'; | ||
| break; | ||
| } | ||
| } | ||
| if (typeof label === 'object') { | ||
| label = this.loadImage(label); | ||
| } | ||
| else if (label) { | ||
| label = label.toString(); | ||
| } | ||
| return label; | ||
| }; | ||
| ChartLabel.prototype.getFontColor = function (dataset, element, index) { | ||
| var fontColor = this.options.fontColor; | ||
| if (typeof fontColor === 'function') { | ||
| fontColor = fontColor({ | ||
| label: this.chart.config.data.labels[index], | ||
| value: dataset.data[index], | ||
| percentage: this.getPercentage(dataset, element, index), | ||
| backgroundColor: dataset.backgroundColor[index], | ||
| dataset: dataset, | ||
| index: index | ||
| }); | ||
| } | ||
| else if (typeof fontColor !== 'string') { | ||
| fontColor = fontColor[index] || this.chart.config.options.color; | ||
| } | ||
| return fontColor; | ||
| }; | ||
| ChartLabel.prototype.getPercentage = function (dataset, element, index) { | ||
| if (this.percentage) { | ||
| return this.percentage; | ||
| } | ||
| var percentage; | ||
| if (this.isChartType(this.chart, 'polarArea') || | ||
| this.isChartType(this.chart, 'doughnut') || | ||
| this.isChartType(this.chart, 'pie')) { | ||
| if (!this.total) { | ||
| this.total = 0; | ||
| for (var i = 0; i < dataset.data.length; ++i) { | ||
| this.total += dataset.data[i]; | ||
| } | ||
| } | ||
| percentage = (dataset.data[index] / this.total) * 100; | ||
| } | ||
| else if (this.isChartType(this.chart, 'bar')) { | ||
| if (!this.barTotal[index]) { | ||
| this.barTotal[index] = 0; | ||
| for (var i = 0; i < this.chart.data.datasets.length; ++i) { | ||
| this.barTotal[index] += this.chart.data.datasets[i].data[index]; | ||
| } | ||
| } | ||
| percentage = (dataset.data[index] / this.barTotal[index]) * 100; | ||
| } | ||
| else { | ||
| var circumference = this.chart.config.options.circumference; | ||
| percentage = (element.circumference / circumference) * 100; | ||
| } | ||
| percentage = parseFloat(percentage.toFixed(this.options.precision)); | ||
| if (!this.options.showActualPercentages) { | ||
| if (this.isChartType(this.chart, 'bar')) { | ||
| this.totalPercentage = this.barTotalPercentage[index] || 0; | ||
| } | ||
| this.totalPercentage += percentage; | ||
| if (this.totalPercentage > 100) { | ||
| percentage -= this.totalPercentage - 100; | ||
| percentage = parseFloat(percentage.toFixed(this.options.precision)); | ||
| } | ||
| if (this.isChartType(this.chart, 'bar')) { | ||
| this.barTotalPercentage[index] = this.totalPercentage; | ||
| } | ||
| } | ||
| this.percentage = percentage; | ||
| return percentage; | ||
| }; | ||
| ChartLabel.prototype.getRenderInfo = function (element, label) { | ||
| if (this.isChartType(this.chart, 'bar')) { | ||
| return this.getBarRenderInfo(element, label); | ||
| } | ||
| else { | ||
| return this.options.arc | ||
| ? this.getArcRenderInfo(element, label) | ||
| : this.getBaseRenderInfo(element, label); | ||
| } | ||
| }; | ||
| ChartLabel.prototype.getBaseRenderInfo = function (element, label) { | ||
| if (this.options.position === LabelPosition.OUTSIDE || | ||
| this.options.position === LabelPosition.BORDER) { | ||
| var rangeFromCentre = void 0; | ||
| var view = element; | ||
| var centreAngle = view.startAngle + (view.endAngle - view.startAngle) / 2; | ||
| var innerRadius = view.outerRadius / 2; | ||
| if (this.options.position === LabelPosition.BORDER) { | ||
| rangeFromCentre = (view.outerRadius - innerRadius) / 2 + innerRadius; | ||
| } | ||
| else if (this.options.position === LabelPosition.OUTSIDE) { | ||
| rangeFromCentre = | ||
| view.outerRadius - | ||
| innerRadius + | ||
| innerRadius + | ||
| this.options.textMargin; | ||
| } | ||
| var renderInfo = { | ||
| x: view.x + Math.cos(centreAngle) * rangeFromCentre, | ||
| y: view.y + Math.sin(centreAngle) * rangeFromCentre | ||
| }; | ||
| if (this.options.position === LabelPosition.OUTSIDE) { | ||
| var offset = this.options.textMargin + this.measureLabel(label).width / 2; | ||
| renderInfo.x += renderInfo.x < view.x ? -offset : offset; | ||
| } | ||
| return renderInfo; | ||
| } | ||
| else { | ||
| return element.tooltipPosition(); | ||
| } | ||
| }; | ||
| ChartLabel.prototype.getArcRenderInfo = function (element, label) { | ||
| var radius; | ||
| var view = element; | ||
| if (this.options.position === LabelPosition.OUTSIDE) { | ||
| radius = | ||
| view.outerRadius + this.options.fontSize + this.options.textMargin; | ||
| } | ||
| else if (this.options.position === LabelPosition.BORDER) { | ||
| radius = (view.outerRadius / 2 + view.outerRadius) / 2; | ||
| } | ||
| else { | ||
| radius = (view.innerRadius + view.outerRadius) / 2; | ||
| } | ||
| var startAngle = view.startAngle, endAngle = view.endAngle; | ||
| var totalAngle = endAngle - startAngle; | ||
| startAngle += Math.PI / 2; | ||
| endAngle += Math.PI / 2; | ||
| var metrics = this.measureLabel(label); | ||
| startAngle += (endAngle - (metrics.width / radius + startAngle)) / 2; | ||
| return { radius: radius, startAngle: startAngle, endAngle: endAngle, totalAngle: totalAngle, view: view }; | ||
| }; | ||
| ChartLabel.prototype.getBarRenderInfo = function (element, label) { | ||
| var renderInfo = element.tooltipPosition(); | ||
| renderInfo.y -= | ||
| this.measureLabel(label).height / 2 + this.options.textMargin; | ||
| return renderInfo; | ||
| }; | ||
| ChartLabel.prototype.outsideInRange = function (left, right, top, bottom) { | ||
| var labelBounds = this.labelBounds; | ||
| for (var i = 0; i < labelBounds.length; ++i) { | ||
| var bound = labelBounds[i]; | ||
| var potins = [ | ||
| [left, top], | ||
| [left, bottom], | ||
| [right, top], | ||
| [right, bottom], | ||
| ]; | ||
| for (var j = 0; j < potins.length; ++j) { | ||
| var x = potins[j][0]; | ||
| var y = potins[j][1]; | ||
| if (x >= bound.left && | ||
| x <= bound.right && | ||
| y >= bound.top && | ||
| y <= bound.bottom) { | ||
| return false; | ||
| } | ||
| } | ||
| potins = [ | ||
| [bound.left, bound.top], | ||
| [bound.left, bound.bottom], | ||
| [bound.right, bound.top], | ||
| [bound.right, bound.bottom], | ||
| ]; | ||
| for (var j = 0; j < potins.length; ++j) { | ||
| var x = potins[j][0]; | ||
| var y = potins[j][1]; | ||
| if (x >= left && x <= right && y >= top && y <= bottom) { | ||
| return false; | ||
| } | ||
| } | ||
| } | ||
| labelBounds.push({ left: left, right: right, top: top, bottom: bottom }); | ||
| return true; | ||
| }; | ||
| ChartLabel.prototype.drawable = function (element, label, renderInfo) { | ||
| if (this.options.overlap) { | ||
| return true; | ||
| } | ||
| if (this.options.arc) { | ||
| return (renderInfo.endAngle - renderInfo.startAngle <= renderInfo.totalAngle); | ||
| } | ||
| var metrics = this.measureLabel(label); | ||
| var left = renderInfo.x - metrics.width / 2; | ||
| var right = renderInfo.x + metrics.width / 2; | ||
| var top = renderInfo.y - metrics.height / 2; | ||
| var bottom = renderInfo.y + metrics.height / 2; | ||
| if (this.options.position === LabelPosition.OUTSIDE) { | ||
| return this.outsideInRange(left, right, top, bottom); | ||
| } | ||
| return (element.inRange(left, top) && | ||
| element.inRange(left, bottom) && | ||
| element.inRange(right, top) && | ||
| element.inRange(right, bottom)); | ||
| }; | ||
| ChartLabel.prototype.measureLabel = function (label) { | ||
| var _this = this; | ||
| if (typeof label === 'object') { | ||
| return { width: label.width, height: label.height }; | ||
| } | ||
| var lines = label.split(EMPTY_LINE_SEPARATOR); | ||
| var width = lines.reduce(function (acc, item) { | ||
| var result = _this.ctx.measureText(item); | ||
| return result.width > acc ? result.width : acc; | ||
| }, 0); | ||
| var height = this.options.fontSize * lines.length; | ||
| return { width: width, height: height }; | ||
| }; | ||
| ChartLabel.prototype.loadImage = function (imgObject) { | ||
| var image = new Image(); | ||
| image.src = imgObject.src; | ||
| image.width = imgObject.width; | ||
| image.height = imgObject.height; | ||
| return image; | ||
| }; | ||
| ChartLabel.prototype.isChartType = function (chart, type) { | ||
| var config = chart === null || chart === void 0 ? void 0 : chart.config; | ||
| return (config === null || config === void 0 ? void 0 : config.type) === type; | ||
| }; | ||
| return ChartLabel; | ||
| }()); | ||
| export { ChartLabel }; | ||
| //# sourceMappingURL=chart-label.js.map |
| {"version":3,"file":"chart-label.js","sourceRoot":"","sources":["../../../src/chart-label.ts"],"names":[],"mappings":"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"} |
| (function () { | ||
| 'use strict'; | ||
| if (typeof Chart === 'undefined') { | ||
| console.error('Cannot find Chart object.'); | ||
| return; | ||
| } | ||
| var helpers = Chart.helpers; | ||
| if (typeof Object.assign !== 'function') { | ||
| Object.assign = function (target) { | ||
| if (!target) { | ||
| throw new TypeError('Cannot convert undefined or null to object'); | ||
| } | ||
| var to = Object(target); | ||
| for (var index = 1; index < arguments.length; index++) { | ||
| var nextSource = arguments[index]; | ||
| if (nextSource) { | ||
| for (var nextKey in nextSource) { | ||
| if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { | ||
| to[nextKey] = nextSource[nextKey]; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return to; | ||
| }; | ||
| } | ||
| var SUPPORTED_TYPES = {}; | ||
| ['pie', 'doughnut', 'polarArea', 'bar'].forEach(function (t) { | ||
| SUPPORTED_TYPES[t] = true; | ||
| }); | ||
| function Label() { | ||
| this.renderToDataset = this.renderToDataset.bind(this); | ||
| } | ||
| Label.prototype.setup = function (chart, options) { | ||
| this.chart = chart; | ||
| this.ctx = chart.ctx; | ||
| this.args = {}; | ||
| this.barTotal = {}; | ||
| var chartOptions = chart.config.options; | ||
| this.options = Object.assign({ | ||
| position: 'default', | ||
| precision: 0, | ||
| fontSize: chartOptions.font ? chartOptions.font.size : 12, | ||
| fontColor: chartOptions.color || '#333333', | ||
| fontStyle: chartOptions.font ? chartOptions.font.style : 'normal', | ||
| fontFamily: chartOptions.font ? chartOptions.font.family : '\'Helvetica Neue\', \'Helvetica\', \'Arial\', sans-serif', | ||
| shadowOffsetX: 3, | ||
| shadowOffsetY: 3, | ||
| shadowColor: 'rgba(0,0,0,0.3)', | ||
| shadowBlur: 6, | ||
| images: [], | ||
| outsidePadding: 2, | ||
| textMargin: 2, | ||
| overlap: true | ||
| }, options); | ||
| if (chart.config.type === 'bar') { | ||
| this.options.position = 'default'; | ||
| this.options.arc = false; | ||
| this.options.overlap = true; | ||
| } | ||
| }; | ||
| Label.prototype.render = function () { | ||
| this.labelBounds = []; | ||
| this.chart.data.datasets.forEach(this.renderToDataset); | ||
| }; | ||
| Label.prototype.renderToDataset = function (dataset, index) { | ||
| this.totalPercentage = 0; | ||
| this.total = null; | ||
| var arg = this.args[index]; | ||
| arg.meta.data.forEach(function (element, index) { | ||
| this.renderToElement(dataset, arg, element, index); | ||
| }.bind(this)); | ||
| }; | ||
| Label.prototype.renderToElement = function (dataset, arg, element, index) { | ||
| if (!this.shouldRenderToElement(arg.meta, element)) { | ||
| return; | ||
| } | ||
| this.percentage = null; | ||
| var label = this.getLabel(dataset, element, index); | ||
| if (!label) { | ||
| return; | ||
| } | ||
| var ctx = this.ctx; | ||
| ctx.save(); | ||
| ctx.font = helpers.fontString(this.options.fontSize, this.options.fontStyle, this.options.fontFamily); | ||
| var renderInfo = this.getRenderInfo(element, label); | ||
| if (!this.drawable(element, label, renderInfo)) { | ||
| ctx.restore(); | ||
| return; | ||
| } | ||
| ctx.beginPath(); | ||
| ctx.fillStyle = this.getFontColor(dataset, element, index); | ||
| this.renderLabel(label, renderInfo); | ||
| ctx.restore(); | ||
| }; | ||
| Label.prototype.renderLabel = function (label, renderInfo) { | ||
| return this.options.arc ? this.renderArcLabel(label, renderInfo) : this.renderBaseLabel(label, renderInfo); | ||
| }; | ||
| Label.prototype.renderBaseLabel = function (label, position) { | ||
| var ctx = this.ctx; | ||
| if (typeof label === 'object') { | ||
| ctx.drawImage(label, position.x - label.width / 2, position.y - label.height / 2, label.width, label.height); | ||
| } | ||
| else { | ||
| ctx.save(); | ||
| ctx.textBaseline = 'top'; | ||
| ctx.textAlign = 'center'; | ||
| if (this.options.textShadow) { | ||
| ctx.shadowOffsetX = this.options.shadowOffsetX; | ||
| ctx.shadowOffsetY = this.options.shadowOffsetY; | ||
| ctx.shadowColor = this.options.shadowColor; | ||
| ctx.shadowBlur = this.options.shadowBlur; | ||
| } | ||
| var lines = label.split('\n'); | ||
| for (var i = 0; i < lines.length; i++) { | ||
| var y = position.y - this.options.fontSize / 2 * lines.length + this.options.fontSize * i; | ||
| ctx.fillText(lines[i], position.x, y); | ||
| } | ||
| ctx.restore(); | ||
| } | ||
| }; | ||
| Label.prototype.renderArcLabel = function (label, renderInfo) { | ||
| var ctx = this.ctx, radius = renderInfo.radius, view = renderInfo.view; | ||
| ctx.save(); | ||
| ctx.translate(view.x, view.y); | ||
| if (typeof label === 'string') { | ||
| ctx.rotate(renderInfo.startAngle); | ||
| ctx.textBaseline = 'middle'; | ||
| ctx.textAlign = 'left'; | ||
| var lines = label.split('\n'); | ||
| var max = 0; | ||
| var widths = []; | ||
| var offset = 0; | ||
| if (this.options.position === 'border') { | ||
| offset = (lines.length - 1) * this.options.fontSize / 2; | ||
| } | ||
| var mertrics = void 0; | ||
| for (var j = 0; j < lines.length; ++j) { | ||
| mertrics = ctx.measureText(lines[j]); | ||
| if (mertrics.width > max) { | ||
| max = mertrics.width; | ||
| } | ||
| widths.push(mertrics.width); | ||
| } | ||
| for (var j = 0; j < lines.length; ++j) { | ||
| var line = lines[j]; | ||
| var y = (lines.length - 1 - j) * -this.options.fontSize + offset; | ||
| ctx.save(); | ||
| var padding = (max - widths[j]) / 2; | ||
| ctx.rotate(padding / radius); | ||
| for (var i = 0; i < line.length; i++) { | ||
| var char = line.charAt(i); | ||
| mertrics = ctx.measureText(char); | ||
| ctx.save(); | ||
| ctx.translate(0, -1 * radius); | ||
| ctx.fillText(char, 0, y); | ||
| ctx.restore(); | ||
| ctx.rotate(mertrics.width / radius); | ||
| } | ||
| ctx.restore(); | ||
| } | ||
| } | ||
| else { | ||
| ctx.rotate((view.startAngle + Math.PI / 2 + renderInfo.endAngle) / 2); | ||
| ctx.translate(0, -1 * radius); | ||
| this.renderLabel(label, { x: 0, y: 0 }); | ||
| } | ||
| ctx.restore(); | ||
| }; | ||
| Label.prototype.shouldRenderToElement = function (meta, element) { | ||
| return !meta.hidden && (this.options.showZero || | ||
| this.chart.config.type === 'polarArea' ? element.outerRadius !== 0 : element.circumference !== 0); | ||
| }; | ||
| Label.prototype.getLabel = function (dataset, element, index) { | ||
| var label; | ||
| if (typeof this.options.render === 'function') { | ||
| label = this.options.render({ | ||
| label: this.chart.config.data.labels[index], | ||
| value: dataset.data[index], | ||
| percentage: this.getPercentage(dataset, element, index), | ||
| dataset: dataset, | ||
| index: index | ||
| }); | ||
| } | ||
| else { | ||
| switch (this.options.render) { | ||
| case 'value': | ||
| label = dataset.data[index]; | ||
| break; | ||
| case 'label': | ||
| label = this.chart.config.data.labels[index]; | ||
| break; | ||
| case 'image': | ||
| label = this.options.images[index] ? this.loadImage(this.options.images[index]) : ''; | ||
| break; | ||
| case 'percentage': | ||
| default: | ||
| label = this.getPercentage(dataset, element, index) + '%'; | ||
| break; | ||
| } | ||
| } | ||
| if (typeof label === 'object') { | ||
| label = this.loadImage(label); | ||
| } | ||
| else if (label) { | ||
| label = label.toString(); | ||
| } | ||
| return label; | ||
| }; | ||
| Label.prototype.getFontColor = function (dataset, element, index) { | ||
| var fontColor = this.options.fontColor; | ||
| if (typeof fontColor === 'function') { | ||
| fontColor = fontColor({ | ||
| label: this.chart.config.data.labels[index], | ||
| value: dataset.data[index], | ||
| percentage: this.getPercentage(dataset, element, index), | ||
| backgroundColor: dataset.backgroundColor[index], | ||
| dataset: dataset, | ||
| index: index | ||
| }); | ||
| } | ||
| else if (typeof fontColor !== 'string') { | ||
| fontColor = fontColor[index] || this.chart.config.options.color; | ||
| } | ||
| return fontColor; | ||
| }; | ||
| Label.prototype.getPercentage = function (dataset, element, index) { | ||
| if (this.percentage) { | ||
| return this.percentage; | ||
| } | ||
| var percentage; | ||
| if (this.chart.config.type === 'polarArea' || this.chart.config.type === 'doughnut' || this.chart.config.type === 'pie') { | ||
| if (!this.total) { | ||
| this.total = 0; | ||
| for (var i = 0; i < dataset.data.length; ++i) { | ||
| this.total += dataset.data[i]; | ||
| } | ||
| } | ||
| percentage = dataset.data[index] / this.total * 100; | ||
| } | ||
| else if (this.chart.config.type === 'bar') { | ||
| if (!this.barTotal[index]) { | ||
| this.barTotal[index] = 0; | ||
| for (var i = 0; i < this.chart.data.datasets.length; ++i) { | ||
| this.barTotal[index] += this.chart.data.datasets[i].data[index]; | ||
| } | ||
| } | ||
| percentage = dataset.data[index] / this.barTotal[index] * 100; | ||
| } | ||
| else { | ||
| percentage = element.circumference / this.chart.config.options.circumference * 100; | ||
| } | ||
| percentage = parseFloat(percentage.toFixed(this.options.precision)); | ||
| if (!this.options.showActualPercentages) { | ||
| if (this.chart.config.type === 'bar') { | ||
| this.totalPercentage = this.barTotalPercentage[index] || 0; | ||
| } | ||
| this.totalPercentage += percentage; | ||
| if (this.totalPercentage > 100) { | ||
| percentage -= this.totalPercentage - 100; | ||
| percentage = parseFloat(percentage.toFixed(this.options.precision)); | ||
| } | ||
| if (this.chart.config.type === 'bar') { | ||
| this.barTotalPercentage[index] = this.totalPercentage; | ||
| } | ||
| } | ||
| this.percentage = percentage; | ||
| return percentage; | ||
| }; | ||
| Label.prototype.getRenderInfo = function (element, label) { | ||
| if (this.chart.config.type === 'bar') { | ||
| return this.getBarRenderInfo(element, label); | ||
| } | ||
| else { | ||
| return this.options.arc ? this.getArcRenderInfo(element, label) : this.getBaseRenderInfo(element, label); | ||
| } | ||
| }; | ||
| Label.prototype.getBaseRenderInfo = function (element, label) { | ||
| if (this.options.position === 'outside' || this.options.position === 'border') { | ||
| var renderInfo = {}; | ||
| var rangeFromCentre = void 0; | ||
| var view = element; | ||
| var centreAngle = view.startAngle + (view.endAngle - view.startAngle) / 2; | ||
| var innerRadius = view.outerRadius / 2; | ||
| if (this.options.position === 'border') { | ||
| rangeFromCentre = (view.outerRadius - innerRadius) / 2 + innerRadius; | ||
| } | ||
| else if (this.options.position === 'outside') { | ||
| rangeFromCentre = (view.outerRadius - innerRadius) + innerRadius + this.options.textMargin; | ||
| } | ||
| renderInfo = { | ||
| x: view.x + (Math.cos(centreAngle) * rangeFromCentre), | ||
| y: view.y + (Math.sin(centreAngle) * rangeFromCentre) | ||
| }; | ||
| if (this.options.position === 'outside') { | ||
| var offset = this.options.textMargin + this.measureLabel(label).width / 2; | ||
| renderInfo.x += renderInfo.x < view.x ? -offset : offset; | ||
| } | ||
| return renderInfo; | ||
| } | ||
| else { | ||
| return element.tooltipPosition(); | ||
| } | ||
| }; | ||
| Label.prototype.getArcRenderInfo = function (element, label) { | ||
| var radius; | ||
| var view = element; | ||
| if (this.options.position === 'outside') { | ||
| radius = view.outerRadius + this.options.fontSize + this.options.textMargin; | ||
| } | ||
| else if (this.options.position === 'border') { | ||
| radius = (view.outerRadius / 2 + view.outerRadius) / 2; | ||
| } | ||
| else { | ||
| radius = (view.innerRadius + view.outerRadius) / 2; | ||
| } | ||
| var startAngle = view.startAngle, endAngle = view.endAngle; | ||
| var totalAngle = endAngle - startAngle; | ||
| startAngle += Math.PI / 2; | ||
| endAngle += Math.PI / 2; | ||
| var mertrics = this.measureLabel(label); | ||
| startAngle += (endAngle - (mertrics.width / radius + startAngle)) / 2; | ||
| return { radius: radius, startAngle: startAngle, endAngle: endAngle, totalAngle: totalAngle, view: view }; | ||
| }; | ||
| Label.prototype.getBarRenderInfo = function (element, label) { | ||
| var renderInfo = element.tooltipPosition(); | ||
| renderInfo.y -= this.measureLabel(label).height / 2 + this.options.textMargin; | ||
| return renderInfo; | ||
| }; | ||
| Label.prototype.drawable = function (element, label, renderInfo) { | ||
| if (this.options.overlap) { | ||
| return true; | ||
| } | ||
| else if (this.options.arc) { | ||
| return renderInfo.endAngle - renderInfo.startAngle <= renderInfo.totalAngle; | ||
| } | ||
| else { | ||
| var mertrics = this.measureLabel(label), left = renderInfo.x - mertrics.width / 2, right = renderInfo.x + mertrics.width / 2, top_1 = renderInfo.y - mertrics.height / 2, bottom = renderInfo.y + mertrics.height / 2; | ||
| if (this.options.position === 'outside') { | ||
| return this.outsideInRange(left, right, top_1, bottom); | ||
| } | ||
| else { | ||
| return element.inRange(left, top_1) && element.inRange(left, bottom) && | ||
| element.inRange(right, top_1) && element.inRange(right, bottom); | ||
| } | ||
| } | ||
| }; | ||
| Label.prototype.outsideInRange = function (left, right, top, bottom) { | ||
| var labelBounds = this.labelBounds; | ||
| for (var i = 0; i < labelBounds.length; ++i) { | ||
| var bound = labelBounds[i]; | ||
| var potins = [ | ||
| [left, top], | ||
| [left, bottom], | ||
| [right, top], | ||
| [right, bottom] | ||
| ]; | ||
| for (var j = 0; j < potins.length; ++j) { | ||
| var x = potins[j][0]; | ||
| var y = potins[j][1]; | ||
| if (x >= bound.left && x <= bound.right && y >= bound.top && y <= bound.bottom) { | ||
| return false; | ||
| } | ||
| } | ||
| potins = [ | ||
| [bound.left, bound.top], | ||
| [bound.left, bound.bottom], | ||
| [bound.right, bound.top], | ||
| [bound.right, bound.bottom] | ||
| ]; | ||
| for (var j = 0; j < potins.length; ++j) { | ||
| var x = potins[j][0]; | ||
| var y = potins[j][1]; | ||
| if (x >= left && x <= right && y >= top && y <= bottom) { | ||
| return false; | ||
| } | ||
| } | ||
| } | ||
| labelBounds.push({ left: left, right: right, top: top, bottom: bottom }); | ||
| return true; | ||
| }; | ||
| Label.prototype.measureLabel = function (label) { | ||
| if (typeof label === 'object') { | ||
| return { width: label.width, height: label.height }; | ||
| } | ||
| else { | ||
| var width = 0; | ||
| var lines = label.split('\n'); | ||
| for (var i = 0; i < lines.length; ++i) { | ||
| var result = this.ctx.measureText(lines[i]); | ||
| if (result.width > width) { | ||
| width = result.width; | ||
| } | ||
| } | ||
| var height = this.options.fontSize * lines.length; | ||
| return { width: width, height: height }; | ||
| } | ||
| }; | ||
| Label.prototype.loadImage = function (obj) { | ||
| var image = new Image(); | ||
| image.src = obj.src; | ||
| image.width = obj.width; | ||
| image.height = obj.height; | ||
| return image; | ||
| }; | ||
| function isPluginsLabelsDefined(options) { | ||
| var chartConfig = options._context.chart.config._config; | ||
| if (chartConfig.options && chartConfig.options.plugins) | ||
| return !!chartConfig.options.plugins.labels; | ||
| return false; | ||
| } | ||
| Chart.register({ | ||
| id: 'labels', | ||
| beforeDatasetsUpdate: function (chart, args, options) { | ||
| if (!SUPPORTED_TYPES[chart.config.type] || !isPluginsLabelsDefined(options)) { | ||
| return; | ||
| } | ||
| if (!options.length) { | ||
| options = [options]; | ||
| } | ||
| var count = options.length; | ||
| if (!chart._labels || count !== chart._labels.length) { | ||
| chart._labels = options.map(function () { | ||
| return new Label(); | ||
| }); | ||
| } | ||
| var someOutside = false, maxPadding = 0; | ||
| for (var i = 0; i < count; ++i) { | ||
| var label = chart._labels[i]; | ||
| label.setup(chart, options[i]); | ||
| if (label.options.position === 'outside') { | ||
| someOutside = true; | ||
| var padding = label.options.fontSize * 1.5 + label.options.outsidePadding; | ||
| if (padding > maxPadding) { | ||
| maxPadding = padding; | ||
| } | ||
| } | ||
| } | ||
| if (someOutside) { | ||
| chart.chartArea.top += maxPadding; | ||
| chart.chartArea.bottom -= maxPadding; | ||
| } | ||
| }, | ||
| afterDatasetUpdate: function (chart, args, options) { | ||
| var _a; | ||
| if (!SUPPORTED_TYPES[chart.config.type] || !isPluginsLabelsDefined(options)) { | ||
| return; | ||
| } | ||
| (_a = chart._labels) === null || _a === void 0 ? void 0 : _a.forEach(function (label) { | ||
| label.args[args.index] = args; | ||
| }); | ||
| }, | ||
| beforeDraw: function (chart, args, options) { | ||
| var _a; | ||
| if (!SUPPORTED_TYPES[chart.config.type] || !isPluginsLabelsDefined(options)) { | ||
| return; | ||
| } | ||
| (_a = chart._labels) === null || _a === void 0 ? void 0 : _a.forEach(function (label) { | ||
| label.barTotalPercentage = {}; | ||
| }); | ||
| }, | ||
| afterDatasetsDraw: function (chart, args, options) { | ||
| var _a; | ||
| if (!SUPPORTED_TYPES[chart.config.type] || !isPluginsLabelsDefined(options)) { | ||
| return; | ||
| } | ||
| (_a = chart._labels) === null || _a === void 0 ? void 0 : _a.forEach(function (label) { | ||
| label.render(); | ||
| }); | ||
| } | ||
| }); | ||
| })(); | ||
| //# sourceMappingURL=chartjs-plugin-labels.js.map |
| {"version":3,"file":"chartjs-plugin-labels.js","sourceRoot":"","sources":["../../../src/chartjs-plugin-labels.js"],"names":[],"mappings":"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"} |
| export * from "./src/chart-label"; |
| import Chart, { ChartComponentLike } from 'chart.js/auto'; | ||
| export declare const PLUGIN_ID = "labels"; | ||
| export declare const getChartLabelPlugin: () => ChartComponentLike; | ||
| export declare class ChartLabel { | ||
| chart: Chart; | ||
| ctx: any; | ||
| args: any; | ||
| percentage: any; | ||
| totalPercentage: any; | ||
| barTotalPercentage: any; | ||
| total: any; | ||
| barTotal: any; | ||
| options: any; | ||
| labelBounds: any; | ||
| setup(chart: Chart, options: any): void; | ||
| private render; | ||
| private renderToDataset; | ||
| private renderToElement; | ||
| private renderLabel; | ||
| private renderBaseLabel; | ||
| private renderArcLabel; | ||
| private shouldRenderToElement; | ||
| private getLabel; | ||
| private getFontColor; | ||
| private getPercentage; | ||
| private getRenderInfo; | ||
| private getBaseRenderInfo; | ||
| private getArcRenderInfo; | ||
| private getBarRenderInfo; | ||
| private outsideInRange; | ||
| private drawable; | ||
| private measureLabel; | ||
| private loadImage; | ||
| private isChartType; | ||
| } |
+1
| export * from './src/chart-label'; |
| import { fontString } from 'chart.js/helpers'; | ||
| import Chart, { | ||
| ChartComponentLike, | ||
| ChartConfiguration, | ||
| ChartType, | ||
| } from 'chart.js/auto'; | ||
| /** | ||
| * The label seems to be a string most of the time. | ||
| * However, sometimes we have an extra check for width and height. | ||
| * TODO: Investigate the `label: string | LabelMetrics` | ||
| * remove LabelMetrics if not needed. | ||
| * */ | ||
| interface LabelMetrics { | ||
| width: number; | ||
| height: number; | ||
| } | ||
| interface RenderInfo { | ||
| x: number; | ||
| y: number; | ||
| } | ||
| enum LabelPosition { | ||
| OUTSIDE = 'outside', | ||
| BORDER = 'border', | ||
| DEFAULT = 'default', | ||
| } | ||
| type BooleanMap = { [id: string]: boolean }; | ||
| type ChartWithCircumference = 'pie' | 'doughnut'; | ||
| const EMPTY_LINE_SEPARATOR = '\n'; | ||
| const SUPPORTED_TYPES: ChartType[] = ['pie', 'doughnut', 'polarArea', 'bar']; | ||
| const SUPPORTED_TYPES_MAP: BooleanMap = SUPPORTED_TYPES.reduce( | ||
| (acc: BooleanMap, id: ChartType) => { | ||
| acc[id] = true; | ||
| return acc; | ||
| }, | ||
| {}, | ||
| ); | ||
| const isAllowedType = (type: string): boolean => SUPPORTED_TYPES_MAP[type]; | ||
| const isPluginsLabelsDefined = (options: any): boolean => { | ||
| const chartConfig: any = options?._context?.chart?.config?._config; | ||
| return !!chartConfig?.options?.plugins?.labels; | ||
| }; | ||
| export const PLUGIN_ID = 'labels'; | ||
| export const getChartLabelPlugin = (): ChartComponentLike => ({ | ||
| id: PLUGIN_ID, | ||
| beforeDatasetsUpdate: function (chart: any, args: any, options: any): void { | ||
| if (!isAllowedType(chart.config.type) || !isPluginsLabelsDefined(options)) { | ||
| return; | ||
| } | ||
| if (!options.length) { | ||
| options = [options]; | ||
| } | ||
| const count = options.length; | ||
| if (!chart._labels || count !== chart._labels.length) { | ||
| chart._labels = options.map(function () { | ||
| return new ChartLabel(); | ||
| }); | ||
| } | ||
| let someOutside = false; | ||
| let maxPadding = 0; | ||
| for (let i = 0; i < count; ++i) { | ||
| const label: ChartLabel = chart._labels[i]; | ||
| label.setup(chart, options[i]); | ||
| if (label.options.position === LabelPosition.OUTSIDE) { | ||
| someOutside = true; | ||
| const padding = | ||
| label.options.fontSize * 1.5 + label.options.outsidePadding; | ||
| if (padding > maxPadding) { | ||
| maxPadding = padding; | ||
| } | ||
| } | ||
| } | ||
| if (someOutside) { | ||
| chart.chartArea.top += maxPadding; | ||
| chart.chartArea.bottom -= maxPadding; | ||
| } | ||
| }, | ||
| afterDatasetUpdate: function (chart: any, args: any, options: any): void { | ||
| if (!isAllowedType(chart.config.type) || !isPluginsLabelsDefined(options)) { | ||
| return; | ||
| } | ||
| chart._labels?.forEach(function (label: any): void { | ||
| label.args[args.index] = args; | ||
| }); | ||
| }, | ||
| beforeDraw: function (chart: any, args: any, options: any): void { | ||
| if (!isAllowedType(chart.config.type) || !isPluginsLabelsDefined(options)) { | ||
| return; | ||
| } | ||
| chart._labels?.forEach(function (label: any): void { | ||
| label.barTotalPercentage = {}; | ||
| }); | ||
| }, | ||
| afterDatasetsDraw: function (chart: any, args: any, options: any): void { | ||
| if (!isAllowedType(chart.config.type) || !isPluginsLabelsDefined(options)) { | ||
| return; | ||
| } | ||
| chart._labels?.forEach(function (label: any): void { | ||
| label.render(); | ||
| }); | ||
| }, | ||
| }); | ||
| export class ChartLabel { | ||
| chart: Chart; | ||
| ctx: any; | ||
| args: any; | ||
| percentage: any; | ||
| totalPercentage: any; | ||
| barTotalPercentage: any; | ||
| total: any; | ||
| barTotal: any; | ||
| options: any; | ||
| labelBounds: any; | ||
| public setup(chart: Chart, options: any): void { | ||
| this.chart = chart; | ||
| this.ctx = chart.ctx; | ||
| this.args = {}; | ||
| this.barTotal = {}; | ||
| const chartOptions = chart.config.options; | ||
| this.options = Object.assign( | ||
| { | ||
| position: LabelPosition.DEFAULT, | ||
| precision: 0, | ||
| fontSize: chartOptions.font ? chartOptions.font.size : 12, | ||
| fontColor: chartOptions.color || '#333333', | ||
| fontStyle: chartOptions.font ? chartOptions.font.style : 'normal', | ||
| fontFamily: chartOptions.font | ||
| ? chartOptions.font.family | ||
| : '\'Helvetica Neue\', \'Helvetica\', \'Arial\', sans-serif', | ||
| shadowOffsetX: 3, | ||
| shadowOffsetY: 3, | ||
| shadowColor: 'rgba(0,0,0,0.3)', | ||
| shadowBlur: 6, | ||
| images: [], | ||
| outsidePadding: 2, | ||
| textMargin: 2, | ||
| overlap: true, | ||
| }, | ||
| options, | ||
| ); | ||
| const config: ChartConfiguration = chart?.config as ChartConfiguration; | ||
| if (config.type === 'bar') { | ||
| this.options.position = LabelPosition.DEFAULT; | ||
| this.options.arc = false; | ||
| this.options.overlap = true; | ||
| } | ||
| } | ||
| private render(): void { | ||
| this.labelBounds = []; | ||
| this.chart.data.datasets.forEach((d: any, i: number) => | ||
| this.renderToDataset.bind(this)(d, i), | ||
| ); | ||
| } | ||
| private renderToDataset(dataset: any, index: number): void { | ||
| this.totalPercentage = 0; | ||
| this.total = null; | ||
| const arg = this.args[index]; | ||
| arg.meta.data.forEach((element: any, index: number) => | ||
| this.renderToElement.bind(this)(dataset, arg, element, index), | ||
| ); | ||
| } | ||
| private renderToElement( | ||
| dataset: any, | ||
| arg: any, | ||
| element: any, | ||
| index: number, | ||
| ): void { | ||
| if (!this.shouldRenderToElement(arg.meta, element)) { | ||
| return; | ||
| } | ||
| this.percentage = null; | ||
| const label = this.getLabel(dataset, element, index); | ||
| if (!label) { | ||
| return; | ||
| } | ||
| const ctx = this.ctx; | ||
| ctx.save(); | ||
| const font: string = fontString( | ||
| this.options.fontSize, | ||
| this.options.fontStyle, | ||
| this.options.fontFamily, | ||
| ); | ||
| if (font) { | ||
| ctx.font = font; | ||
| } | ||
| const renderInfo = this.getRenderInfo(element, label); | ||
| if (!this.drawable(element, label, renderInfo)) { | ||
| ctx.restore(); | ||
| return; | ||
| } | ||
| ctx.beginPath(); | ||
| ctx.fillStyle = this.getFontColor(dataset, element, index); | ||
| this.renderLabel(label, renderInfo); | ||
| ctx.restore(); | ||
| } | ||
| private renderLabel(label: string | LabelMetrics, renderInfo: any): void { | ||
| return this.options.arc | ||
| ? this.renderArcLabel(label, renderInfo) | ||
| : this.renderBaseLabel(label, renderInfo); | ||
| } | ||
| private renderBaseLabel(label: string | LabelMetrics, position: any): void { | ||
| const ctx = this.ctx; | ||
| if (typeof label === 'object') { | ||
| ctx.drawImage( | ||
| label, | ||
| position.x - label.width / 2, | ||
| position.y - label.height / 2, | ||
| label.width, | ||
| label.height, | ||
| ); | ||
| return; | ||
| } | ||
| ctx.save(); | ||
| ctx.textBaseline = 'top'; | ||
| ctx.textAlign = 'center'; | ||
| if (this.options.textShadow) { | ||
| ctx.shadowOffsetX = this.options.shadowOffsetX; | ||
| ctx.shadowOffsetY = this.options.shadowOffsetY; | ||
| ctx.shadowColor = this.options.shadowColor; | ||
| ctx.shadowBlur = this.options.shadowBlur; | ||
| } | ||
| const lines = label.split(EMPTY_LINE_SEPARATOR); | ||
| for (let i = 0; i < lines.length; i++) { | ||
| const y: number = | ||
| position.y - | ||
| (this.options.fontSize / 2) * lines.length + | ||
| this.options.fontSize * i; | ||
| ctx.fillText(lines[i], position.x, y); | ||
| } | ||
| ctx.restore(); | ||
| } | ||
| private renderArcLabel(label: string | LabelMetrics, renderInfo: any): void { | ||
| const ctx = this.ctx; | ||
| const radius = renderInfo.radius; | ||
| const view = renderInfo.view; | ||
| ctx.save(); | ||
| ctx.translate(view.x, view.y); | ||
| if (typeof label === 'string') { | ||
| ctx.rotate(renderInfo.startAngle); | ||
| ctx.textBaseline = 'middle'; | ||
| ctx.textAlign = 'left'; | ||
| let max = 0; | ||
| const lines: string[] = label.split(EMPTY_LINE_SEPARATOR); | ||
| const widths: number[] = []; | ||
| const offset: number = | ||
| this.options.position === LabelPosition.BORDER | ||
| ? ((lines.length - 1) * this.options.fontSize) / 2 | ||
| : 0; | ||
| for (let j = 0; j < lines.length; ++j) { | ||
| const metrics: TextMetrics = this.ctx.measureText(lines[j]); | ||
| if (metrics.width > max) { | ||
| max = metrics.width; | ||
| } | ||
| widths.push(metrics.width); | ||
| } | ||
| for (let j = 0; j < lines.length; ++j) { | ||
| const line = lines[j]; | ||
| const y = (lines.length - 1 - j) * -this.options.fontSize + offset; | ||
| ctx.save(); | ||
| const padding = (max - widths[j]) / 2; | ||
| ctx.rotate(padding / radius); | ||
| for (let i = 0; i < line.length; i++) { | ||
| const char = line.charAt(i); | ||
| const metrics: TextMetrics = this.ctx.measureText(char); | ||
| ctx.save(); | ||
| ctx.translate(0, -1 * radius); | ||
| ctx.fillText(char, 0, y); | ||
| ctx.restore(); | ||
| ctx.rotate(metrics.width / radius); | ||
| } | ||
| ctx.restore(); | ||
| } | ||
| } else { | ||
| ctx.rotate((view.startAngle + Math.PI / 2 + renderInfo.endAngle) / 2); | ||
| ctx.translate(0, -1 * radius); | ||
| this.renderLabel(label, { x: 0, y: 0 }); | ||
| } | ||
| ctx.restore(); | ||
| } | ||
| private shouldRenderToElement(meta: any, element: any): boolean { | ||
| return ( | ||
| !meta.hidden && | ||
| (this.options.showZero || this.isChartType(this.chart, 'polarArea') | ||
| ? element.outerRadius !== 0 | ||
| : element.circumference !== 0) | ||
| ); | ||
| } | ||
| /** | ||
| * TODO: Investigate what the label type might be. | ||
| * It might not be LabelMetrics, but often times it is a string. | ||
| * */ | ||
| private getLabel( | ||
| dataset: any, | ||
| element: any, | ||
| index: any, | ||
| ): string | LabelMetrics { | ||
| let label; | ||
| if (typeof this.options.render === 'function') { | ||
| label = this.options.render({ | ||
| label: this.chart.config.data.labels[index], | ||
| value: dataset.data[index], | ||
| percentage: this.getPercentage(dataset, element, index), | ||
| dataset, | ||
| index, | ||
| }); | ||
| } else { | ||
| switch (this.options.render) { | ||
| case 'value': | ||
| label = dataset.data[index]; | ||
| break; | ||
| case 'label': | ||
| label = this.chart.config.data.labels[index]; | ||
| break; | ||
| case 'image': | ||
| label = this.options.images[index] | ||
| ? this.loadImage(this.options.images[index]) | ||
| : ''; | ||
| break; | ||
| case 'percentage': | ||
| default: | ||
| label = this.getPercentage(dataset, element, index) + '%'; | ||
| break; | ||
| } | ||
| } | ||
| if (typeof label === 'object') { | ||
| label = this.loadImage(label); | ||
| } else if (label) { | ||
| label = label.toString(); | ||
| } | ||
| return label; | ||
| } | ||
| private getFontColor(dataset: any, element: any, index: number): any { | ||
| let fontColor = this.options.fontColor; | ||
| if (typeof fontColor === 'function') { | ||
| fontColor = fontColor({ | ||
| label: this.chart.config.data.labels[index], | ||
| value: dataset.data[index], | ||
| percentage: this.getPercentage(dataset, element, index), | ||
| backgroundColor: dataset.backgroundColor[index], | ||
| dataset, | ||
| index, | ||
| }); | ||
| } else if (typeof fontColor !== 'string') { | ||
| fontColor = fontColor[index] || this.chart.config.options.color; | ||
| } | ||
| return fontColor; | ||
| } | ||
| private getPercentage(dataset: any, element: any, index: number): number { | ||
| if (this.percentage) { | ||
| return this.percentage; | ||
| } | ||
| let percentage: number; | ||
| if ( | ||
| this.isChartType(this.chart, 'polarArea') || | ||
| this.isChartType(this.chart, 'doughnut') || | ||
| this.isChartType(this.chart, 'pie') | ||
| ) { | ||
| if (!this.total) { | ||
| this.total = 0; | ||
| for (let i = 0; i < dataset.data.length; ++i) { | ||
| this.total += dataset.data[i]; | ||
| } | ||
| } | ||
| percentage = (dataset.data[index] / this.total) * 100; | ||
| } else if (this.isChartType(this.chart, 'bar')) { | ||
| if (!this.barTotal[index]) { | ||
| this.barTotal[index] = 0; | ||
| for (let i = 0; i < this.chart.data.datasets.length; ++i) { | ||
| this.barTotal[index] += this.chart.data.datasets[i].data[index]; | ||
| } | ||
| } | ||
| percentage = (dataset.data[index] / this.barTotal[index]) * 100; | ||
| } else { | ||
| const circumference: number = ( | ||
| this.chart.config as ChartConfiguration<ChartWithCircumference> | ||
| ).options.circumference; | ||
| percentage = (element.circumference / circumference) * 100; | ||
| } | ||
| percentage = parseFloat(percentage.toFixed(this.options.precision)); | ||
| if (!this.options.showActualPercentages) { | ||
| if (this.isChartType(this.chart, 'bar')) { | ||
| this.totalPercentage = this.barTotalPercentage[index] || 0; | ||
| } | ||
| this.totalPercentage += percentage; | ||
| if (this.totalPercentage > 100) { | ||
| percentage -= this.totalPercentage - 100; | ||
| percentage = parseFloat(percentage.toFixed(this.options.precision)); | ||
| } | ||
| if (this.isChartType(this.chart, 'bar')) { | ||
| this.barTotalPercentage[index] = this.totalPercentage; | ||
| } | ||
| } | ||
| this.percentage = percentage; | ||
| return percentage; | ||
| } | ||
| private getRenderInfo(element: any, label: any): any { | ||
| if (this.isChartType(this.chart, 'bar')) { | ||
| return this.getBarRenderInfo(element, label); | ||
| } else { | ||
| return this.options.arc | ||
| ? this.getArcRenderInfo(element, label) | ||
| : this.getBaseRenderInfo(element, label); | ||
| } | ||
| } | ||
| private getBaseRenderInfo(element: any, label: any): any { | ||
| if ( | ||
| this.options.position === LabelPosition.OUTSIDE || | ||
| this.options.position === LabelPosition.BORDER | ||
| ) { | ||
| let rangeFromCentre: number; | ||
| const view = element; | ||
| const centreAngle = | ||
| view.startAngle + (view.endAngle - view.startAngle) / 2; | ||
| const innerRadius = view.outerRadius / 2; | ||
| if (this.options.position === LabelPosition.BORDER) { | ||
| rangeFromCentre = (view.outerRadius - innerRadius) / 2 + innerRadius; | ||
| } else if (this.options.position === LabelPosition.OUTSIDE) { | ||
| rangeFromCentre = | ||
| view.outerRadius - | ||
| innerRadius + | ||
| innerRadius + | ||
| this.options.textMargin; | ||
| } | ||
| const renderInfo: RenderInfo = { | ||
| x: view.x + Math.cos(centreAngle) * rangeFromCentre, | ||
| y: view.y + Math.sin(centreAngle) * rangeFromCentre, | ||
| }; | ||
| if (this.options.position === LabelPosition.OUTSIDE) { | ||
| const offset: number = | ||
| this.options.textMargin + this.measureLabel(label).width / 2; | ||
| renderInfo.x += renderInfo.x < view.x ? -offset : offset; | ||
| } | ||
| return renderInfo; | ||
| } else { | ||
| return element.tooltipPosition(); | ||
| } | ||
| } | ||
| private getArcRenderInfo(element: any, label: any): any { | ||
| let radius; | ||
| const view = element; | ||
| if (this.options.position === LabelPosition.OUTSIDE) { | ||
| radius = | ||
| view.outerRadius + this.options.fontSize + this.options.textMargin; | ||
| } else if (this.options.position === LabelPosition.BORDER) { | ||
| radius = (view.outerRadius / 2 + view.outerRadius) / 2; | ||
| } else { | ||
| radius = (view.innerRadius + view.outerRadius) / 2; | ||
| } | ||
| let startAngle = view.startAngle, | ||
| endAngle = view.endAngle; | ||
| const totalAngle = endAngle - startAngle; | ||
| startAngle += Math.PI / 2; | ||
| endAngle += Math.PI / 2; | ||
| const metrics: LabelMetrics = this.measureLabel(label); | ||
| startAngle += (endAngle - (metrics.width / radius + startAngle)) / 2; | ||
| return { radius, startAngle, endAngle, totalAngle, view }; | ||
| } | ||
| private getBarRenderInfo(element: any, label: any): any { | ||
| const renderInfo = element.tooltipPosition(); | ||
| renderInfo.y -= | ||
| this.measureLabel(label).height / 2 + this.options.textMargin; | ||
| return renderInfo; | ||
| } | ||
| private outsideInRange( | ||
| left: any, | ||
| right: any, | ||
| top: any, | ||
| bottom: any, | ||
| ): boolean { | ||
| const labelBounds = this.labelBounds; | ||
| for (let i = 0; i < labelBounds.length; ++i) { | ||
| const bound = labelBounds[i]; | ||
| let potins = [ | ||
| [left, top], | ||
| [left, bottom], | ||
| [right, top], | ||
| [right, bottom], | ||
| ]; | ||
| for (let j = 0; j < potins.length; ++j) { | ||
| const x = potins[j][0]; | ||
| const y = potins[j][1]; | ||
| if ( | ||
| x >= bound.left && | ||
| x <= bound.right && | ||
| y >= bound.top && | ||
| y <= bound.bottom | ||
| ) { | ||
| return false; | ||
| } | ||
| } | ||
| potins = [ | ||
| [bound.left, bound.top], | ||
| [bound.left, bound.bottom], | ||
| [bound.right, bound.top], | ||
| [bound.right, bound.bottom], | ||
| ]; | ||
| for (let j = 0; j < potins.length; ++j) { | ||
| const x = potins[j][0]; | ||
| const y = potins[j][1]; | ||
| if (x >= left && x <= right && y >= top && y <= bottom) { | ||
| return false; | ||
| } | ||
| } | ||
| } | ||
| labelBounds.push({ left, right, top, bottom }); | ||
| return true; | ||
| } | ||
| private drawable( | ||
| element: any, | ||
| label: LabelMetrics | string, | ||
| renderInfo: any, | ||
| ): boolean { | ||
| if (this.options.overlap) { | ||
| return true; | ||
| } | ||
| if (this.options.arc) { | ||
| return ( | ||
| renderInfo.endAngle - renderInfo.startAngle <= renderInfo.totalAngle | ||
| ); | ||
| } | ||
| const metrics: LabelMetrics = this.measureLabel(label); | ||
| const left: number = renderInfo.x - metrics.width / 2; | ||
| const right: number = renderInfo.x + metrics.width / 2; | ||
| const top: number = renderInfo.y - metrics.height / 2; | ||
| const bottom: number = renderInfo.y + metrics.height / 2; | ||
| if (this.options.position === LabelPosition.OUTSIDE) { | ||
| return this.outsideInRange(left, right, top, bottom); | ||
| } | ||
| return ( | ||
| element.inRange(left, top) && | ||
| element.inRange(left, bottom) && | ||
| element.inRange(right, top) && | ||
| element.inRange(right, bottom) | ||
| ); | ||
| } | ||
| private measureLabel(label: string | LabelMetrics): LabelMetrics { | ||
| if (typeof label === 'object') { | ||
| return { width: label.width, height: label.height }; | ||
| } | ||
| const lines: string[] = label.split(EMPTY_LINE_SEPARATOR); | ||
| const width: number = lines.reduce((acc: number, item: string): number => { | ||
| const result: TextMetrics = this.ctx.measureText(item); | ||
| return result.width > acc ? result.width : acc; | ||
| }, 0); | ||
| const height: number = this.options.fontSize * lines.length; | ||
| return { width, height }; | ||
| } | ||
| private loadImage(imgObject: HTMLImageElement): HTMLImageElement { | ||
| const image: HTMLImageElement = new Image(); | ||
| image.src = imgObject.src; | ||
| image.width = imgObject.width; | ||
| image.height = imgObject.height; | ||
| return image; | ||
| } | ||
| private isChartType(chart: Chart, type: ChartType): boolean { | ||
| const config: ChartConfiguration = chart?.config as ChartConfiguration; | ||
| return config?.type === type; | ||
| } | ||
| } |
| { | ||
| "compilerOptions": { | ||
| "module": "ES2022", | ||
| "noImplicitAny": true, | ||
| "removeComments": true, | ||
| "preserveConstEnums": true, | ||
| "sourceMap": true, | ||
| "allowJs": true, | ||
| "outDir": "dist/esm", | ||
| "moduleResolution": "Node", | ||
| "declaration": true, | ||
| "declarationDir": "dist/types" | ||
| }, | ||
| "include": ["src/**/*", "index.js"], | ||
| "exclude": ["node_modules", "**/*.test.js"] | ||
| } |
+6
-1
@@ -6,3 +6,8 @@ { | ||
| }, | ||
| "extends": "eslint:recommended", | ||
| "extends": [ | ||
| "eslint:recommended", "plugin:@typescript-eslint/recommended" | ||
| ], | ||
| "parser": "@typescript-eslint/parser", | ||
| "plugins": ["@typescript-eslint"], | ||
| "root": true, | ||
| "parserOptions": { | ||
@@ -9,0 +14,0 @@ "ecmaVersion": 12, |
+11
-0
| # Change Log | ||
| ## v5.0.0-beta / 2023-07-03 | ||
| ### Added | ||
| - Angular support with usage example | ||
| ### Changed | ||
| - Add support for Chart.js v4.3 !BREAKING | ||
| - TypeScript refactoring of the initial plugin source | ||
| - TypeScript eslint support | ||
| - Extracted `ChartLabel` – this holds a large chunk of the initial logic | ||
| - Extracted `getChartLabelPlugin()` method – which can be used to register chart plugin | ||
| ## v3.0.0 / 2021-05-26 | ||
@@ -4,0 +15,0 @@ ### Added |
+10
-5
| { | ||
| "name": "chart.js-plugin-labels-dv", | ||
| "version": "4.0.0", | ||
| "version": "5.0.0-beta", | ||
| "description": "Chart.js plugin to display labels on pie, doughnut and polar area chart.", | ||
| "main": "src/chartjs-plugin-labels.js", | ||
| "main": "dist/esm/chart-label.js", | ||
| "scripts": { | ||
| "build": "rollup -c", | ||
| "build:ts": "tsc", | ||
| "lint": "eslint ./" | ||
| }, | ||
| "peerDependencies": { | ||
| "chart.js": "^4.2.1" | ||
| "chart.js": "^4.3.0" | ||
| }, | ||
| "types": "./dist/types/index.d.ts", | ||
| "repository": { | ||
@@ -30,6 +32,9 @@ "type": "git", | ||
| "devDependencies": { | ||
| "eslint": "^8.36.0", | ||
| "@typescript-eslint/eslint-plugin": "^5.60.1", | ||
| "@typescript-eslint/parser": "^5.60.1", | ||
| "eslint": "^8.44.0", | ||
| "rollup": "^2.79.1", | ||
| "rollup-plugin-terser": "^7.0.2" | ||
| "rollup-plugin-terser": "^7.0.2", | ||
| "typescript": "^4.6.4" | ||
| } | ||
| } |
+81
-28
@@ -1,4 +0,8 @@ | ||
| # Chart.js Plugin Labels for Chart.js v3+ | ||
| [Chart.js](https://www.chartjs.org/) plugin to display labels on pie, doughnut and polar area chart. Forked from emn178/chartjs-plugin-labels. | ||
| [](https://codeclimate.com/github/DavideViolante/chart.js-plugin-labels-dv/maintainability)  [](https://www.paypal.me/dviolante) | ||
| [](https://nodei.co/npm/chart.js-plugin-labels-dv/) | ||
| # Chart.js Plugin Labels for Chart.js v4+ | ||
| [Chart.js](https://www.chartjs.org/) plugin to display labels on pie, doughnut and polar area chart. Forked from [emn178/chartjs-plugin-labels](https://github.com/emn178/chartjs-plugin-labels). | ||
| ## Demo | ||
@@ -16,3 +20,3 @@ - [Demo](http://emn178.github.io/chartjs-plugin-labels/samples/demo/) from the original repo using Chart.js v2.x, but it's almost the same. | ||
| ## Installation | ||
| ## Install from NPM | ||
| - `npm i chart.js-plugin-labels-dv` | ||
@@ -22,3 +26,3 @@ | ||
| JavaScript | ||
| ```JavaScript | ||
| ```js | ||
| new Chart(ctx, { | ||
@@ -32,40 +36,27 @@ type: type, | ||
| render: 'value', | ||
| // precision for percentage, default is 0 | ||
| precision: 0, | ||
| // identifies whether or not labels of value 0 are displayed, default is false | ||
| showZero: true, | ||
| // font size, default is defaultFontSize | ||
| fontSize: 12, | ||
| // font color, can be color array for each data or function for dynamic color, default is defaultFontColor | ||
| fontColor: '#fff', | ||
| // font style, default is defaultFontStyle | ||
| fontStyle: 'normal', | ||
| // font family, default is defaultFontFamily | ||
| fontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", | ||
| // draw text shadows under labels, default is false | ||
| textShadow: true, | ||
| // text shadow intensity, default is 6 | ||
| shadowBlur: 10, | ||
| // text shadow X offset, default is 3 | ||
| shadowOffsetX: -5, | ||
| // text shadow Y offset, default is 3 | ||
| shadowOffsetY: 5, | ||
| // text shadow color, default is 'rgba(0,0,0,0.3)' | ||
| shadowColor: 'rgba(255,0,0,0.75)', | ||
| // draw label in arc, default is false | ||
| // bar chart ignores this | ||
| arc: true, | ||
| // position to draw label, available value is 'default', 'border' and 'outside' | ||
@@ -75,10 +66,7 @@ // bar chart ignores this | ||
| position: 'default', | ||
| // draw label even it's overlap, default is true | ||
| // bar chart ignores this | ||
| overlap: true, | ||
| // show the real calculated percentages from the values and don't apply the additional logic to fit the percentages to 100 in total, default is false | ||
| showActualPercentages: true, | ||
| // set images when `render` is 'image' | ||
@@ -92,7 +80,5 @@ images: [ | ||
| ], | ||
| // add padding when position is `outside` | ||
| // default is 2 | ||
| outsidePadding: 4, | ||
| // add margin of text when position is `outside` or `border` | ||
@@ -112,3 +98,2 @@ // default is 2 | ||
| return '$' + args.value; | ||
| // return object if it is image | ||
@@ -131,3 +116,3 @@ // return { src: 'image.png', width: 16, height: 16 }; | ||
| ```JavaScript | ||
| ```js | ||
| labels: [ | ||
@@ -146,3 +131,3 @@ { | ||
| ```JavaScript | ||
| ```js | ||
| Chart.defaults.plugins.labels = { | ||
@@ -170,6 +155,74 @@ // ... | ||
| ### Angular / Vue | ||
| We need your contribution! If you know how to make it work with these frameworks please open a PR editing this readme. | ||
| ### Vue | ||
| From https://github.com/DavideViolante/chartjs-plugin-labels/issues/2#issuecomment-1483948596 | ||
| ```ts | ||
| import Chart from "chart.js/auto"; | ||
| import * as helpers from "chart.js/helpers"; | ||
| ``` | ||
| Then inside the `created()` hook: | ||
| ```ts | ||
| async created() { | ||
| window.Chart = Chart; | ||
| Chart.helpers = helpers; | ||
| awaitimport("chart.js-plugin-labels-dv"); | ||
| } | ||
| ``` | ||
| ### Angular | ||
| You would need to create your own chart component. | ||
| ```html | ||
| <div class="chart"> | ||
| <canvas [id]="name"></canvas> | ||
| </div> | ||
| ``` | ||
| Importing should be straightforward | ||
| ```ts | ||
| import Chart from 'chart.js/auto'; | ||
| import { getChartLabelPlugin, PLUGIN_ID } from 'chart.js-plugin-labels-dv'; | ||
| ``` | ||
| ```ts | ||
| @Input() chartConfig: any; | ||
| @Output() chartCreated: EventEmitter<Chart> = new EventEmitter<Chart>(); | ||
| public readonly name: string = `chart-${ChartComponent.instanceCount++}`; | ||
| private chart: Chart; | ||
| ngAfterViewInit(): void { | ||
| this.createChart(); | ||
| } | ||
| private createChart(): void { | ||
| if (!this.hasRegisteredPlugin()) { | ||
| Chart.register(getChartLabelPlugin()); | ||
| } | ||
| this.chart = new Chart(this.name, this.chartConfig); | ||
| this.chartCreated.emit(this.chart); | ||
| } | ||
| private hasRegisteredPlugin(): boolean { | ||
| return !!Chart.registry?.plugins.get(PLUGIN_ID); | ||
| } | ||
| ``` | ||
| For fixing the module failed compilation error I have updated tsconfig as follows: | ||
| ``` | ||
| Error: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js): | ||
| Error: /node_modules/chart.js-plugin-labels-dv/src/chart-label.ts is missing from the TypeScript compilation. | ||
| Please make sure it is in your tsconfig via the 'files' or 'include' property. | ||
| ``` | ||
| tsconfig.json | ||
| ```json | ||
| "files": [ | ||
| ... | ||
| "node_modules/chart.js-plugin-labels-ed/src/chart-label.ts" | ||
| ], | ||
| ``` | ||
| Test it out with data from the official Chart.js website: https://www.chartjs.org/docs/latest/charts/doughnut.html#pie | ||
| ## License | ||
@@ -180,2 +233,2 @@ [MIT license](http://www.opensource.org/licenses/MIT). | ||
| The project's website is located at https://github.com/emn178/chartjs-plugin-labels | ||
| Authors: Chen, Yi-Cyuan (emn178@gmail.com), Davide Violante | ||
| Authors: Chen, Yi-Cyuan (emn178@gmail.com), Davide Violante, eduard-landclan |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
156500
181.61%26
85.71%2174
266.61%225
30.81%6
100%2
100%1
Infinity%