how to put "%" in chart pie (chartjs) - javascript

I need to put % after the number in the chart:
Like: 100%
This is the code that i'm using to make the chart, using chart js:
new Chart(document.getElementById("pie-chart-one"), {
type: 'doughnut',
data: {
labels: ['Transmitidas', 'Não Transmitidas'],
datasets: [{
data: [#Model.PorcentQtdDeclaracoesStatusTransmitida, #Model.PorcentQtdDeclaracoesStatusNaoTransmitida],
backgroundColor: backgroudColor,
borderWidth: 1,
}]
},
options: {
legend: {
display: true,
position: 'bottom',
fontSize: 10
},
responsive:false,
fontsize: 11,
layout: {
padding: {
left: 0,
right: 0,
top: 30,
bottom: 30
}
}
}
});

in options definitions...
options: {
tooltips: {
enabled: true,
mode: 'single',
callbacks: {
label: function(tooltipItems, data) {
return tooltipItems.yLabel + ' %';
}
}
},
}

I solve the problem using a callback and a title inside the tooltip:
options: {
tooltips: {
callbacks: {
label: function (tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var total = dataset.data.reduce(function (previousValue, currentValue, currentIndex, array) {
return previousValue + currentValue;
});
var currentValue = dataset.data[tooltipItem.index];
var percentage = Math.floor(((currentValue / total) * 100) + 0.5);
return percentage + "%";
},
title: function (tooltipItem, data) {
return data.labels[tooltipItem[0].index];
}
}
}

Related

Small value in doughnut chart is not visible - Chartjs

Small data isn't visible for doughnut chart type. Can i resize it without change label value?
My chart options:
options: {
cutoutPercentage: 65,
maintainAspectRatio: false,
legend: {
display: false
},
plugins: {
datalabels: {
display: false
}
},
tooltips: {
enabled: true,
mode: 'nearest'
},
scales: {
yAxes: [{
ticks: {
max: 5,
min: 0,
stepSize: 0.5
}
}]
}
}
Example:
http://jsfiddle.net/Lkya2tqb/
I converted the dataset to percent and round a small value to 1.
var seriesData = [1,210,215];
var total = seriesData.reduce((a,v) => a + v);
var inPercent = seriesData.map(v => Math.max(v / total * 100, 1));
Create callback for tooltip.
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var value = seriesData[tooltipItem.index];
var label = data.labels[tooltipItem.index];
return `${label}: ${value}`;
}
}
var seriesData = [1, 210, 215];
var total = seriesData.reduce((a, v) => a + v);
var inPercent = seriesData.map(v => Math.max(v / total * 100, 1));
var labelsData = ["one", "two", "second"];
var backgroundColors = ["#FBC02D", "#E64A19", "#388E3C"]
var t = new Chart(document.getElementById('broadcast').getContext('2d'), {
type: "doughnut",
data: {
datasets: [{
data: inPercent,
backgroundColor: backgroundColors,
hoverBorderColor: "#fff"
}],
labels: labelsData,
},
options: {
cutoutPercentage: 65,
maintainAspectRatio: false,
legend: {
display: false
},
plugins: {
datalabels: {
display: false
}
},
tooltips: {
enabled: true,
mode: 'nearest',
callbacks: {
label: function(tooltipItem, data) {
var value = seriesData[tooltipItem.index];
var label = labelsData[tooltipItem.index];
return `${label}: ${value}`;
}
}
}
}
});
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<canvas id="broadcast" width="350" height="250" style="width: 350px; height: 250px;"></canvas>

How can I hide tooltip in Chart.js on a specific data label?

I am trying to hide a tooltip in Chart.js whenever the name of a clicked object is "Something". I have already tried this:
this.doughnutChart = new Chart(this.doughnutCanvas.nativeElement, {
type: 'doughnut',
data: {
datasets: [{
label: _.map(this.dataService.AmTimeSlots, 'ProjectName'),
data: _.map(this.dataService.AmTimeSlots, 'Duration'),
backgroundColor: _.map(this.dataService.AmTimeSlots, 'Color'),
hoverBackgroundColor: _.map(this.dataService.AmTimeSlots, 'HoverColor'),
borderColor: _.map(this.dataService.AmTimeSlots, 'BorderColor'),
borderWidth: 1.5
},
{
label: _.map(this.dataService.PmTimeSlots, 'ProjectName'),
data: _.map(this.dataService.PmTimeSlots, 'Duration'),
backgroundColor: _.map(this.dataService.PmTimeSlots, 'Color'),
hoverBackgroundColor: _.map(this.dataService.PmTimeSlots, 'HoverColor'),
borderColor: _.map(this.dataService.PmTimeSlots, 'BorderColor'),
borderWidth: 1.5
}],
},
options: {
elements: {
arc: {
roundedCornersFor: 0
}
},
segmentShowStroke: false,
responsive: true,
maintainAspectRatio: true,
legend: {
display: false
},
onClick: this.chartClick.bind(this),
cutoutPercentage: 65,
tooltips: {
filter: function (tooltipItem) {
if (tooltipItem.xLabel == "Free Slot") {
return false;
} else {
return true;
}
},
callbacks: {
label: function (tooltipItems, data) {
return data.datasets[tooltipItems.datasetIndex].label[tooltipItems.index];
},
afterLabel: function (tooltipItems, data) {
return Math.floor(data.datasets[tooltipItems.datasetIndex].data[tooltipItems.index] / 6) + 'h ' + data.datasets[tooltipItems.datasetIndex].data[tooltipItems.index] * 10 % 60 + 'm';
}
}
}
},
config: {
data: this.dataService,
settings: this.settingsService
}
});
And this code above is working fine. It’s successfully hiding the text of tooltip, but the problem is that the black label/border still remains. How can I hide it?
You can simply filter tooltips:
options: {
tooltips: {
filter: function (tooltipItem, data) {
var label = data.labels[tooltipItem.index];
if (label == "Red") {
return false;
} else {
return true;
}
}
}
}
See this jsfiddle: https://jsfiddle.net/beaver71/ndc2uao2/
Update for Chart.js 3:
options: {
plugins: {
tooltip: {
filter: function (tooltipItem, data) {
return tooltipItem.label === "Red";
}
}
}
}

To print arrays value using "/" in bar chart

I had to print the values of Active_Employees & Employees_Plan in bar chart like in this
Image
Means to make a bar representing the comparison in the last bar. It would be more suitable if concise code is provided.
function BarChart()
{
var emp = 0;
myData = "{ 'date':'" + startdate + "', 'Level1':'0','Level2':'0','Level3':'0','Level4':'0','Level5':'0','Level6':'0', 'EmployeeId':'" + emp + "'}";
$.ajax({
type: "POST",
url: "NewDashboard.asmx/BarChart",
contentType: "application/json; charset=utf-8",
data:myData,
success: OnSuccessBarChart,
// function (result) {
// alert(result.d);
//},
error: onError,
cache: false
});
}
function OnSuccessBarChart(data,status)
{
var bar_array = [];
if (data.d != null) {
var bar_data = jsonParse(data.d);
$.each(bar_data, function (i, option) {
//OSA.push(
// {
// name: option[i].Active_Employees,
// data: parseFloat(option[i].Employees_Plan)
// })
bar_array.push(
parseFloat([option.Employees_Plan]),
parseFloat([option.Active_Employees]),
parseFloat([option.Employees_Plan] + "/" + [option.Active_Employees])
);
});
}
chart = new Highcharts.Chart({
chart: {
renderTo: 'BarCharts',
type: 'bar',
height: 300
},
title: {
text: 'Month Planned by Employees '
},
colors: [
'#604228'
],
credits: { enabled: false },
tooltip: {
backgroundColor: 'rgba(0, 0, 0, 0.85)',
style: {
color: '#F0F0F0'
},
formatter: function () {
return this.x + ':' + this.y;
}
},
plotOptions: {
series: {
shadow: false,
borderWidth: 1,
dataLabels: {
enabled: true,
}
}
},
xAxis: {
categories: ['Plan of Current Month', 'Total Active Employee', 'Plans Made by Active Employees'],
labels: {
style: {
fontWeight: 'bold'
}
}
},
yAxis: {
title: {
text: 'Plans of Active Employees',
align: 'high'
},
labels: {
overflow: 'justify'
}
},
series: [{
showInLegend: false,
data: bar_array
}]
});
}
I would try something like this:
$.each(bar_data, function (i, option) {
var emp_plan = option.Employees_Plan;
var active_emp = option.Active_Employees;
var plan_ratio = emp_plan / active_emp;
bar_array.push(
parseFloat([option.Employees_Plan]),
parseFloat([option.Active_Employees]),
parseFloat(plan_ratio).toFixed(2)
);
});

Hide/Show yaxis on series hide/show event

I'm making a multiple panel chart, and I'm trying to hide the y-axis on the hide event of the axis serie.
I tried setting the axis height and redrawing it (didn't work), set extremes, nothing worked. I also tryed this solution but didn't work, I beleave it didn't work beacause I'm using highstock and the "solution" use Highcharts, does that make sense?
I also have to resize the others y-axis when one is hidden, but this is another problem. But if someone has a tip on how to do it automatically would be thankful
Here is my JSFiddle code.
$(function () {
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-ohlcv.json&callback=?', function (data) {
var data1 = [ [100,0], [200,0], [300,1], [400,0], [500,1] ];
var data2 = [ [100,1], [200,0], [300,1], [400,0], [500,0] ];
var data3 = [ [100,1], [200,1], [300,0], [400,0], [500,1] ];
var data4 = [ [100,0], [200,1], [300,1], [400,0], [500,0] ];
// create the chart
var chart = $('#container').highcharts('StockChart', {
title: {
text: 'AAPL Historical'
},
legend: {
enabled: true
},
plotOptions: {
series: {
events: {
hide: function (event) {
console.log(this.yAxis)
//Hide
},
show: function (event) {
console.log(this.yAxis)
//Display
}
}
}
},
tooltip: {
pointFormatter: function() {
var state = (this.y == 1 ? "Active" : "Inactive");
var tooltip = '<span style="color:' + this.color + '">\u25CF</span> ' + this.series.name + ': <b>' + state + '</b><br/>'
return tooltip;
}
},
yAxis: [{
height: '25%',
offset: 0,
lineWidth: 2,
labels: {enabled: false}
}, {
top: '25%',
height: '25%',
offset: 0,
lineWidth: 2,
labels: {enabled: false},
title : {
text: "aaa"
}
}, {
top: '50%',
height: '25%',
offset: 0,
lineWidth: 2,
labels: {enabled: false}
}, {
top: '75%',
height: '25%',
offset: 0,
lineWidth: 2,
labels: {enabled: false}
}],
series: [{
name: 'Data1',
data: data1,
step: true,
yAxis: 0
}, {
name: 'Data2',
data: data2,
step: true,
yAxis: 1
}, {
name: 'Data3',
data: data3,
step: true,
yAxis: 2
}, {
name: 'Data4',
data: data4,
step: true,
yAxis: 3
}]
});
});
});
I worked more on solution and I found A way to hide the y-axis, by changing its height to 0% on the series hide event. I'm also increasing the axis height back to 25% in the series show event.
plotOptions: {
series: {
events: {
hide: function (event) {
this.yAxis.update({
height: '0%'
});
},
show: function (event) {
this.yAxis.update({
height: '25%'
});
}
}
}
},
Full code
Edit:
I found a way to resize the others y-axis when one of them is hidden or one the axis is displayed.
You can check the full code.
$(function () {
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-ohlcv.json&callback=?', function (data) {
var data1 = [ [100,0], [150,1], [150,0], [200,0], [300,1], [400,0], [500,1] ];
var data2 = [ [100,1], [200,0], [300,1], [400,0], [500,0] ];
var data3 = [ [100,1], [200,1], [300,0], [400,0], [500,1] ];
var data4 = [ [100,0], [200,1], [300,1], [400,0], [500,0] ];
// create the chart
var chart = $('#container').highcharts('StockChart', {
title: {
text: 'AAPL Historical'
},
legend: {
enabled: true
},
plotOptions: {
series: {
marker: {
enabled: true,
radius : 2
},
events: {
hide: function (event) {
var serieYAxis = this.yAxis;
serieYAxis.visivel = false;
serieYAxis.update({
height: '0%',
title: {
style: {"display":"none"}
}
});
var axis = this.chart.yAxis.filter(
function (axis) {
return axis.visivel == null || axis.visivel;
}
);
resizeAxis(axis);
},
show: function (event) {
this.yAxis.visivel = true;
this.yAxis.update({
title: {
style: {"display":"initial"}
}
});
var axis = this.chart.yAxis.filter(
function (axis) {
return axis.visivel == null || axis.visivel;
}
);
resizeAxis(axis);
}
}
}
},
tooltip: {
pointFormatter: function() {
var state = (this.y == 1 ? "Active" : "Inactive");
var tooltip = '<span style="color:' + this.color + '">\u25CF</span> ' + this.series.name + ': <b>' + state + '</b><br/>'
return tooltip;
}
},
yAxis: [{
height: '25%',
offset: 0,
lineWidth: 2,
labels: {enabled: false},
title : {
text: "y0"
}
}, {
top: '25%',
height: '25%',
offset: 0,
lineWidth: 2,
labels: {enabled: false},
title : {
text: "y1"
}
}, {
top: '50%',
height: '25%',
offset: 0,
lineWidth: 2,
labels: {enabled: false},
title : {
text: "y2"
}
}, {
top: '75%',
height: '25%',
offset: 0,
lineWidth: 2,
labels: {enabled: false},
title : {
text: "y3"
}
}],
series: [{
name: 'Data1',
data: data1,
step: true,
yAxis: 0
}, {
name: 'Data2',
data: data2,
step: true,
yAxis: 1
}, {
name: 'Data3',
data: data3,
step: true,
yAxis: 2
}, {
name: 'Data4',
data: data4,
step: true,
yAxis: 3
}]
});
});
});

Kendo chart second valueAxis issue, not working with axisCrossingValue

I am using Kendo chart with two valueAxes.
One valueAxis is all positive values
other can have negative
Range defined in chart is based on the values. I want both the valueAxis to have value "0" as axisCrossingValue.
I tried this with axisCrossingValue but it is not respecting this value for second valueAxis.
var data1 = [6000, 8000];
var data2 = [0.2, -0.3] ;
$scope.chartOptions = {
transitions: false,
legend: {
visible: false
},
chartArea:
{
margin: {
left: 20,
right: 20
},
background: "transparent"
},
seriesDefaults: {
type: "column"
},
series: [
{
type: "column",
stack: true,
name: "A",
color: "#efefef",
axis: "A",
highlight: {
visible: false
},
data: data1
}, {
type: "line",
name: "B",
color: "#008700",
axis: "B",
style: "smooth",
markers: {
visible: false,
border: {
width: 0
}
},
data: data2
}
],
valueAxes: [
{
name: "A",
labels: {
visible: true,
template: "#= kendo.format('{0:n}', value) #",
color: "#888"
},
axisCrossingValue: 0
}, {
name: "B",
labels: {
visible: true,
justified: true,
template: "#= value #",
color: "#888"
},
axisCrossingValue: 0
}
],
categoryAxis: {
labels: {
visible: false
},
categories: $scope.dates,
axisCrossingValues: [0, $scope.dates.length]
},
tooltip: {
}
};
It looks like the chart does not know how to automatically handle crossing at 0 on both axes. I think your best bet is to calculate/set the min and max values of the 2 axes such that 0 is in the same place on both axes:
valueAxis: [
{
name: "A",
axisCrossingValue: 0,
min: -9000,
max: 9000,
color: "#888",
majorGridLines: {
visible: false,
}
},
{
name: "B",
min: -0.5,
max: 0.5,
justified: true,
color: "#888",
majorGridLines: {
visible: false,
}
}
],
DEMO
To do this dynamically, I had to override the default max/min values for each axis with a rounded value calculated from my data sets.
$scope.getChartMaxMin(values, percentages) {
var minValue = 0;
var maxValue = 0;
var minPercent = 0;
var maxPercent = 0;
angular.forEach(values, function (val) {
if (val < minValue) {
minValue = val;
}
if (val > maxValue) {
maxValue = val;
}
})
angular.forEach(percentages, function (percent) {
percent = percent * 100;
if (percent < minPercent) {
minPercent = percent;
}
if (percent > maxPercent) {
maxPercent = percent;
}
})
minValue = intelliRound(Math.floor(minValue));
maxValue = intelliRound(Math.ceil(maxValue));
minPercent = intelliRound(Math.floor(minPercent));
maxPercent = intelliRound(Math.ceil(maxPercent));
var difference = maxValue / maxPercent;
minPercent = minValue / difference;
return {
minValue: minValue,
maxValue: maxValue,
minPercent: minPercent,
maxPercent: maxPercent
}
}
function intelliRound(num) {
var len = (num + '').length;
var result = 0;
if (num < 0) {
var fac = Math.pow(10, len - 2);
result = Math.floor(num / fac) * fac;
}
else {
var fac = Math.pow(10, len - 1);
result = Math.ceil(num / fac) * fac;
}
return result;
}
var values = [40000, 60000, -30000]
var percentages = [3.65,0.010,1.69]
var maxMin = $scope.getChartMaxMin(values, percentages);
$scope.chartOptions = {
series: [
{
type: "column",
stack: true,
name: "A",
color: "#efefef",
axis: "A",
highlight: {
visible: false
},
data: values
}, {
type: "line",
name: "B",
color: "#008700",
axis: "B",
style: "smooth",
markers: {
visible: false,
border: {
width: 0
}
},
data: percentages
}
],
valueAxes: [
{
name: "A",
labels: {
visible: true,
template: "#= kendo.format('{0:n}', value) #",
color: "#888"
min: maxMin[minValue],
max: maxMin[maxValue]
},
}, {
name: "B",
labels: {
visible: true,
justified: true,
template: "#= value #",
color: "#888"
},
min: maxMin[minPercent],
max: maxMin[maxPercent]
}
],
categoryAxis: {
labels: {
visible: false
},
categories: $scope.dates,
axisCrossingValues: [0, $scope.dates.length]
},
};

Categories