Chart js always show labels on a doughnut chart - javascript

So I have a doughnut chart, and I'm trying to keep the labels always on, and in my research I've found this but it doesn't seem to work, here's my code
function showPieChart(){
var config = {
type: 'doughnut',
data: {
datasets: [{
data: [50,25,15,10],
backgroundColor: ['#585ba7','#999acb','#8ac0e9','#363e96'],
label: 'Dataset 1'
}],
labels: ['Token Sale','Foundation','Early Contributors','Team & Advisors']
},
options: {
tooltipTemplate: "<%= value %>",
showTooltips: true,
onAnimationComplete: function() {
this.showTooltip(this.datasets[0].points, true);
},
tooltipEvents: [],
cutoutPercentage: 90,
layout: {
padding: {
left: 0,
right: 0,
top: 0,
bottom: 0
}
},
responsive: true,
legend: {
display: false,
},
title: {
display: false,
},
animation: {
animateRotate: true,
duration: 1000,
animateScale: true,
animationSteps: 15
}
}
};
var ctx = $("#pie-chart").get(0).getContext("2d");
Chart.defaults.global.maintainAspectRatio = false;
window.myDoughnut = new Chart(ctx, config);
}
I've added toolTipTemplate, showToolTips, onAnimationComplete, and toolTipEvents the same way than on the answer I found, but it doesn't seem to work, and chartjs documentations doesn't have anything on these. Therefore, I'm looking for the reason why this is not working, and how I could get it to work in a non hacky way.

Using the plugin from this github issue seems to work, assuming you are on the latest version of chartjs (2.7.1 at the time of this answer)
here is a fiddle with working plugin: https://jsfiddle.net/Lngyxg3r/
here is the code from that fiddle:
html:
<canvas id="pie-chart"></canvas>
js:
Chart.pluginService.register({
beforeRender: function (chart) {
if (chart.config.options.showAllTooltips) {
// create an array of tooltips
// we can't use the chart tooltip because there is only one tooltip per chart
chart.pluginTooltips = [];
chart.config.data.datasets.forEach(function (dataset, i) {
chart.getDatasetMeta(i).data.forEach(function (sector, j) {
chart.pluginTooltips.push(new Chart.Tooltip({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart));
});
});
// turn off normal tooltips
chart.options.tooltips.enabled = false;
}
},
afterDraw: function (chart, easing) {
if (chart.config.options.showAllTooltips) {
// we don't want the permanent tooltips to animate, so don't do anything till the animation runs atleast once
if (!chart.allTooltipsOnce) {
if (easing !== 1)
return;
chart.allTooltipsOnce = true;
}
// turn on tooltips
chart.options.tooltips.enabled = true;
Chart.helpers.each(chart.pluginTooltips, function (tooltip) {
tooltip.initialize();
tooltip.update();
// we don't actually need this since we are not animating tooltips
tooltip.pivot();
tooltip.transition(easing).draw();
});
chart.options.tooltips.enabled = false;
}
}
});
function showPieChart(){
var config = {
type: 'doughnut',
data: {
datasets: [{
data: [50,25,15,10],
backgroundColor: ['#585ba7','#999acb','#8ac0e9','#363e96'],
label: 'Dataset 1'
}],
labels: ['Token Sale','Foundation','Early Contributors','Team & Advisors']
},
options: {
tooltipTemplate: "<%= value %>",
showTooltips: true,
showAllTooltips: true,
onAnimationComplete: function() {
this.showTooltip(this.datasets[0].points, true);
},
tooltipEvents: [],
cutoutPercentage: 90,
layout: {
padding: {
left: 0,
right: 0,
top: 0,
bottom: 0
}
},
responsive: true,
legend: {
display: false,
},
title: {
display: false,
},
animation: {
animateRotate: true,
duration: 1000,
animateScale: true,
animationSteps: 15
}
}
};
var ctx = $("#pie-chart").get(0).getContext("2d");
Chart.defaults.global.maintainAspectRatio = false;
window.myDoughnut = new Chart(ctx, config);
}
showPieChart();

Related

Apex Charts JS fill to size

So I've got a pretty small div, in which I gotta get a small timeline chart shoved in. The current problem is, that due to the chart being perfectly centered, I have a lot of whitespace I could really use, to make the actual data and chart much larger.:
I think showing the parent div shouldn't matter(because changing around these sizes doesn't really affect the chart itself). It feels like there's some option in the configuration that I'm missing. I've tried setting offsetY and even offsetX to negative values, because I was desperate, but to no avail.
<html>
<div id="chartTarget" style="height: 100; width: 100%;">
<canvas id="chartCanvas" height="100"></canvas>
<div style="opacity:0;" class="chartTooltip center">
</div>
</div>
</html>
Relevant code is pretty much straight up copied from the example, but since I'm bound to get questions about it, here goes:
var options = {
series: [
{
name: 'Pending',
data: [
{
x: 'Trip',
y: [
new Date('2021-04-21T03:24:00').getTime(),
new Date('2021-04-21T04:24:00').getTime()
]
}
]
},
{
name: 'Active',
data: [
{
x: 'Trip',
y: [
new Date('2021-04-21T05:24:00').getTime(),
new Date('2021-04-21T08:24:00').getTime()
]
}
]
},
{
name: 'Deleted',
data: [
{
x: 'Trip',
y: [
new Date('2021-04-21T11:24:00').getTime(),
new Date('2021-04-21T12:24:00').getTime()
]
}
]
}
],
chart: {
height: 75,
width: 250,
type: 'rangeBar',
offsetY: -25,
toolbar: {
show: false,
tools: {
download: false,
selection: false,
zoom: false,
zoomin: false,
zoomout: false,
pan: true,
reset: true
}
},
events: {
dataPointMouseEnter: function (event, chartContext, config) {
config.w.config.chart.toolbar.show = false;
},
dataPointMouseLeave: function (event, chartContext, config) {
config.w.config.chart.toolbar.show = false;
}
}
},
plotOptions: {
bar: {
horizontal: true,
barHeight: '50%',
rangeBarGroupRows: true
}
},
colors: [
"#008FFB", "#00E396", "#FEB019", "#FF4560", "#775DD0",
"#3F51B5", "#546E7A", "#D4526E", "#8D5B4C", "#F86624",
"#D7263D", "#1B998B", "#2E294E", "#F46036", "#E2C044"
],
fill: {
type: 'solid'
},
xaxis: {
type: 'datetime',
labels: {
maxHeight: 25,
style: {
fontSize: '9px'
},
offsetY: -8
},
tooltip: {
enabled: false
}
},
yaxis: {
show: false,
lines: {
show: true
}
},
legend: {
show: false,
position: 'top'
}
};
var chart = new ApexCharts(document.querySelector("#chartTarget"), options);
chart.render();
I need the label, so things like sparkline aren't useful.
A negative offset at the chart level seems to have fixed for my needs.
chart.offsetY: -25
I assume everyone else can play with negative offset values, where available for more fine tuning.

Add value to horizontal bar in chart.js

I have been looking around for a way to add the value inside each bar in a horizontal bar chart, using chart.js but all posts seem to show how to add the label. Tooltip shows both label and value but I wanted to show the value so users can see the result without having to mouse-over the bar.
I put break points in the script to see if there is any property of "model" that contains the value but couldn't find one.
This is how I set up the chart including the animation section that shows the label instead of the value.
Dataset comes from an ajax call and chart is displayed in its onSuccess:
function OnSuccess_(response) {
var jResult = JSON.parse(response.d);
var chartLabels = [];
var chartData = []
$.each(jResult, function (index, val) {
chartLabels.push(val.TIMERANGE);
chartData.push(val.COUNT); // <--- This is what I want to display on each bar
});
var ctx = document.getElementById("rtChart").getContext("2d");
if (chartRespTime)
chartRespTime.destroy();
chartRespTime = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: chartLabels,
datasets: [{
label: "Response Time (ms)",
backgroundColor: ["#3e95cd", "#8e5ea2", "#3cba9f", "#e8c3b9", "#c45850"],
data: chartData
}]
},
options: {
title: {
display: true,
text: 'Database Response Time (milli-seconds)'
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Count'
},
ticks: {
major: {
fontStyle: 'bold',
fontColor: '#FF0000'
}
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Response Time (ms)'
}
}]
},
animation: {
onComplete: function () {
var ctx = this.chart.ctx;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontFamily, 'normal', Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'left';
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function (dataset) {
for (var i = 0; i < dataset.data.length; i++) {
var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model,
left = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._xScale.left;
ctx.fillStyle = '#444'; // label color
var label = model.label; // <--- need value not label
ctx.fillText(label, left + 15, model.y + 8);
}
});
}
},
maintainAspectRatio: false,
responsive: true,
showInlineValues: true,
centeredInllineValues: true,
tooltipCaretSize: 0
}
});
//console.log(ctx);
$('#rtChart').show();
}
There is no build in way to do this, but there is a verry good plugin that achieves what you want: the datalabels plugin https://chartjs-plugin-datalabels.netlify.app/samples/charts/bar.html

Chart.JS value on top disappear when tooltip show up

I have chart witch i need show up value on top each bar, and i need show tooltip too, so i try these code
var ctx3 = document.getElementById('canvasppicinh').getContext('2d');
window.myMixedChart = new Chart(ctx3, {
type: 'bar',
data: chartData,
options: {
maintainAspectRatio: false,
title: {
display: true,
text: 'Chart KPI Financial Perfective',
padding: 50
},
legend :{
position : 'bottom'
},
tooltips: {
mode: 'index',
intersect: true,
enabled: true,
callbacks: {
label: function(tooltipItem, data) {
var val = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") +',-';
}
}
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
categoryPercentage: 1.0
},
gridLines: {
display: false
}
}]
},
hover: {
mode: false
},
animation: {
duration : 1,
onProgress: function() {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function(dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function(bar, index) {
var data = dataset.data[index];
ctx.fillText(data, bar._model.x, bar._model.y - 5);
});
});
}
}
}
});
Well is kinda work for me, my chart show value on top each bar but my problem is, everytime i try show tooltip value on top disappear. If tooltip disappear (not hovering) top value appearing. Did i miss something? And I have searching these problem on google, it said i need extend. But i don't have any idea how to use extend with my oldest code. Please help me.
I found the solution you need plugin chartjs-plugin-datalabels, and add inside option chart
plugins: {
datalabels: {
color: 'white',
formatter: function(value, context) {
return Math.round(value) + '%';
}
}
}
And remove animation

Make Chart.js horizontal bar labels multi-line

Just wondering if there is any way to set the horizontal bar labels for y-axis using chart.js. Here is how I set up the chart:
<div class="box-body">
<canvas id="chart" style="position: relative; height: 300px;"></canvas>
</div>
Javascript:
var ctx = document.getElementById('chart').getContext("2d");
var options = {
layout: {
padding: {
top: 5,
}
},
responsive: true,
animation: {
animateScale: true,
animateRotate: true
},
};
var opt = {
type: "horizontalBar",
data: {
labels: label,
datasets: [{
data: price,
}]
},
options: options
};
if (chart) chart.destroy();
chart= new Chart(ctx, opt);
chart.update();
As you all can see, the first and third labels are too long and cut off. Is there a way to make the label multi-line?
If you want to have full control over how long labels are broken down across lines you can specify the breaking point by providing labels in a nested array. For example:
var chart = new Chart(ctx, {
...
data: {
labels: [["Label1 Line1:","Label1 Line2"],["Label2 Line1","Label2 Line2"]],
datasets: [{
...
});
You can use the following chart plugin :
plugins: [{
beforeInit: function(chart) {
chart.data.labels.forEach(function(e, i, a) {
if (/\n/.test(e)) {
a[i] = e.split(/\n/);
}
});
}
}]
add this followed by your chart options
ᴜꜱᴀɢᴇ :
add a new line character (\n) to your label, wherever you wish to add a line break.
ᴅᴇᴍᴏ
var chart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: ['Jan\n2017', 'Feb', 'Mar', 'Apr'],
datasets: [{
label: 'BAR',
data: [1, 2, 3, 4],
backgroundColor: 'rgba(0, 119, 290, 0.7)'
}]
},
options: {
scales: {
xAxes: [{
ticks: {
beginAtZero: true
}
}]
}
},
plugins: [{
beforeInit: function(chart) {
chart.data.labels.forEach(function(e, i, a) {
if (/\n/.test(e)) {
a[i] = e.split(/\n/);
}
});
}
}]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx"></canvas>

Angular chart.js onClick is not working - how to get all elements of a bar when it is clicked on

I am a beginner to Chart.js and I am trying to create click events when a chart is created.
I am trying to access all the elements of a bar when it is clicked on, but right now, the onClick method is not even running properly. The chart is rendering just fine - any html should not be needed as the canvas is created in the code. I would appreciate help in order to solve this problem
controller($state, $scope, $rootScope) {
$scope.myChart;
....
$scope.go = function myFunc() {
document.getElementById("chartContainer").innerHTML = ' ';
document.getElementById("chartContainer").innerHTML = '<canvas style="margin-top: 10px; padding-top: 20px; height:90% ; background-color: ' + vm.options.backgroundColor + '; " id="myChart" click="onClick"></canvas>';
var ctx = document.getElementById("myChart").getContext('2d');
render($scope.myChart, ctx, vm.options.barColor, vm.options.backgroundColor, labelVal, value);
};
$scope.onClick = function (evt) {
console.log("Testing");
};
}
var render = function createChart(myChart, ctx, barColor, backgroundColor, labels, values) {
myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
backgroundColor: barColor,
data: values,
}]
},
options: {
events: ['click'],
chartArea: {
backgroundColor: backgroundColor,
},
global: {
responsive: true,
maintainAspectRatio: false,
},
scaleBeginAtZero: true,
maintainAspectRatio: false,
scales: {
xAxes: [{
ticks: {
autoSkip: false,
}
}],
yAxes: [{
ticks: {
beginAtZero: true,
min: 0
}
}]
}
}
});
}
TRY adding the following on-click event handler in your chart options ...
options: {
onClick: function(e) {
var element = this.getElementAtEvent(e);
if (element.length) {
console.log(element[0])
}
},
...
}
This should work as far as I can tell

Categories