Chart.js Box Annotations Fill Entire Chart - chart.js

I am trying to plot a simple chart, but want to colour the upper and lower parts of the chart red to indicate a value out of range, and the center part of the chart green to indicate an acceptable value.
Using chartjs-plugin-annotation.js and three Box Annotations, I am almost there. Unfortunately the three boxes don't seem to want to honour the 'yMax' and 'yMin' coordinates I specify. The boxes expand out to the edges in the Y direction. This is what I want them to do in the X direction. But in the Y direction I'm trying to specify the demarcation between the central, green "ok" area and the upper and lower "danger" zones.
If someone can point me in the direction of a solution, I'd very much appreciate it! Here is my code attempt:
<!DOCTYPE HTML>
<html>
<head>
<title>Test Chart</title>
<script src='./moment.js'></script>
<script src='./Chart.js'></script>
<script src='./chartjs-plugin-annotation.js'></script>
</head>
<body>
<canvas id='TestChart' width='1200' height='300'>
<script>
var user_notes = [ '','','','','Note One','','','','',
'Note Two','','','','','','','','','','' ];
new Chart (
document.getElementById( 'TestChart' ), {
'type' : 'line',
'data' : {
'datasets' : [{
'label' : 'Test Chart',
'fill' : false,
'borderColor' : '#000000',
'colour' : '#c0ffa0',
'lineTension' : 0.4,
'pointHitRadius' : 10,
'pointRotation' : 45,
'pointRadius' : [ 5,5,5,5,9,5,5,5,5,9,5,5,5,5,5,5,5,5,5,5 ],
// 'pointRadius' : (item, data) => { // function better but
// console.log( 'TEST pointRadius' );// can't get it to work
// return 7;
// },
'pointStyle' : [ 'circle','circle','circle','circle','rect',
'circle','circle','circle','circle','rect',
'circle','circle','circle','circle','circle',
'circle','circle','circle','circle','circle' ],
// 'pointStyle' : (item, data) => { // function better but
// console.log( 'TEST pointStyle' ); // can't get it to work
// return 'triangle';
// },
'pointBackgroundColor' : [ '#ffa0c0', '#ffa0c0', '#ffa0c0',
'#c0ffa0', '#c0ffa0', '#c0ffa0',
'#c0ffa0', '#ffa0c0', '#c0ffa0',
'#c0ffa0', '#c0ffa0', '#c0ffa0',
'#c0ffa0', '#c0ffa0', '#c0ffa0',
'#c0ffa0', '#ffa0c0', '#c0ffa0',
'#c0ffa0', '#c0ffa0' ],
// a function call would be better
// but can't get either of the following to work
// // function type one
// 'pointBackgroundColor' : (item, data) => {
// console.log( 'pointBackgroundColor TEST' );
// return '#c0ffa0';
// },
// // function type two
// 'pointBackgroundColor' : function( context ) {
// var v = context.dataset.data[c_index];
// console.log( 'pointBackgroundColor TEST: v = ' + v );
// return
// (v <= 3.9) || (v >= 6)
// ? '#ffa0c0' // draw extreme values in red
// : '#c0ffa0'; // else, values in green
// },
'data' : [
{ x: new Date( '2019-11-03 07:19' ), y: 3.9 },
{ x: new Date( '2019-11-04 07:31' ), y: 3.8 },
{ x: new Date( '2019-11-05 08:15' ), y: 3.6 },
{ x: new Date( '2019-11-06 08:20' ), y: 4.2 },
{ x: new Date( '2019-11-07 08:08' ), y: 4.2 },
{ x: new Date( '2019-11-08 08:00' ), y: 4.2 },
{ x: new Date( '2019-11-09 08:18' ), y: 4.4 },
{ x: new Date( '2019-11-10 07:59' ), y: 3.5 },
{ x: new Date( '2019-11-11 08:02' ), y: 4.8 },
{ x: new Date( '2019-11-12 08:23' ), y: 4.4 },
{ x: new Date( '2019-11-13 07:54' ), y: 4.0 },
{ x: new Date( '2019-11-14 08:00' ), y: 4.3 },
{ x: new Date( '2019-11-15 08:11' ), y: 4.2 },
{ x: new Date( '2019-11-16 08:11' ), y: 4.9 },
{ x: new Date( '2019-11-17 08:10' ), y: 4.9 },
{ x: new Date( '2019-11-18 08:15' ), y: 5.8 },
{ x: new Date( '2019-11-19 07:10' ), y: 6.1 },
{ x: new Date( '2019-11-20 08:03' ), y: 5.1 },
{ x: new Date( '2019-11-21 07:51' ), y: 4.7 },
{ x: new Date( '2019-11-22 07:56' ), y: 4.3 }
]
}]
},
options: {
'point' : {
'borderColor' : '#000000',
},
'tooltips' : {
'mode' : 'index',
'bodyFontSize' : 24,
'footerFontSize' : 18,
'footerFontColor' : '#ffeb6d',
'axix' : 'y',
'callbacks' : {
'title' : (item, data) => {
var when = item[0].xLabel.split( ' ' );
var newT = when[0] + ' ' + when[1] + ' ' + when[3];
return newT.substring(0, newT.length - 3);
},
'label' : (item, data) => {
return item.yLabel.toFixed( 1 ) + ' Units';
},
'footer' : (item, data) => {
return user_notes[ item[0].index ];
},
},
}, // end tooltips
'legend' : {
'onClick' : 'null',
// 'display' : 'false',
'position' : 'top',
},
'scales' : {
'xAxes' : [ {
'type' : 'time',
'ticks' : {
'time' : { 'displayFormats' : { 'day' : 'D MMM' } },
}
} ],
'yAxes' : [ {
'display' : 'true',
'position' : 'right',
'ticks' : {
'suggestedMax' : 9.0,
'suggestedMin' : 3.0,
}
} ],
}, // end scales
'annotation' : {
'drawTime' : 'beforeDatasetsDraw',
'annotations' : [{
'type' : 'box',
'id' : 'top-red',
'xScaleID' : 'xAxes',
'yScaleID' : 'yAxes',
'yMin' : '5.9', //ignored
'borderWidth' : 0,
'borderColor' : 'rgba(255,200,200,0.3)',
'backgroundColor' : 'rgba(255,200,200,0.3)',
},{
'type' : 'box',
'id' : 'middle-green',
'xScaleID' : 'xAxes',
'yScaleID' : 'yAxes',
'yMax' : '5.9', // ignored
'yMin' : '4.0', // ignored
'borderWidth' : 0,
'borderColor' : 'rgba(200,255,200,0.3)',
'backgroundColor' : 'rgba(200,255,200,0.3)',
},{
'type' : 'box',
'id' : 'bottom-red',
'xScaleID' : 'xAxes',
'yScaleID' : 'yAxes',
'yMax' : '4.0', // ignored
'borderWidth' : 0,
'borderColor' : 'rgba(255,200,200,0.3)',
'backgroundColor' : 'rgba(255,200,200,0.3)',
}]
} // end annotation
} // end options
}
);
</script>
</body>
</html>

This behavior comes from the fact that you did not provide the correct y-axis id and x-axis id in the boxes definition.
I see that you did not put any id for x-axis and y-axis in your chart's xAxes and yAxes definition, so their default ids are 'x-axis-0' and 'y-axis-0'.
For each of your boxes definition, try changing
'xScaleID' : 'xAxes',
'yScaleID' : 'yAxes'
into
'xScaleID' : 'x-axis-0',
'yScaleID' : 'y-axis-0'

Related

Class does not have id chartjs

I need a help!
const annotationLinePlugin = {
renderAnnotationLine: function(chartInstance, line) {
let datasetMeta = chartInstance.getDatasetMeta(line.datasetIndex);
let context = chartInstance.chart.ctx;
let datasetModel = datasetMeta.data[line.dataIndex]._model;
const xBarCenter = datasetModel.x
const barWidth = datasetModel.width;
const xStart = xBarCenter - (barWidth / 2) - 4;
const xEnd = xBarCenter + (barWidth / 2) + 4;
const yAxisID = datasetMeta.yAxisID;
const yCoordinate = chartInstance.scales[yAxisID].getPixelForValue(line.yCoordinate);
context.beginPath();
context.strokeStyle = line.color;
context.lineWidth = line.width;
context.moveTo(xStart, yCoordinate);
context.lineTo(xEnd, yCoordinate);
context.stroke();
if (typeof line.label !== typeof undefined) {
context.textAlign = 'center';
context.fillStyle = line.color;
context.fillText(line.label, yCoordinate, xEnd + 7);
}
},
afterDatasetsDraw: function(chart, easing) {
if (chart.data.datasets.length < 1) {
return;
}
if (chart.config.lines) {
chart.config.lines.map(line => {
this.renderAnnotationLine(chart, line);
});
}
}
};
Chart.register(annotationLinePlugin);
I get a error in browser : Uncaught Error : class does not have id
picture with errors
I had chartjs2, i had to migrate to chartjs3.In chartjs2, there were red lines on every chart object, after switching to chaartjs3, these lines were gone, in the record of cases that Chart.plugins.register was replaced by chart.register, I replaced it, but still nothing worked.
There were the lines :
lines
index.html :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Chart.js 2 to 3</title>
</head>
<body>
<div>
<canvas id="сhart"></canvas>
</div>
</body>
<script src="./chartjs3/chart.js"></script>
<script src="./chartjs3/chart.min.js"></script>
<script src="./chartjs3/chartjs-plugin-annotation.js"></script>
<script src="./chartjs3/chartjs-plugin-annotation.min.js"></script>
<script src="./chartjs3/chartjs-plugin-annotationLine.js"></script>
<script src="./chartjs3/chartjs-plugin-datalabels.js"></script>
<script src="./chartjs3/chartjs-plugin-datalabels.min.js"></script>
<script src="./chartjs3/hammer.min.js"></script>
<script>
const ctx = document.getElementById("сhart").getContext("2d");
const options = {
type: "bar",
responsive: true,
maintainAspectRatio: false,
title: { display: false },
tooltips: {
mode: "index",
intersect: true,
filter: (tooltipItem, chartData) => {
return (
!chartData.datasets[tooltipItem.datasetIndex].hideFromTooltip &&
(chartData.datasets[tooltipItem.datasetIndex].yAxisID == "R" ||
tooltipItem.yLabel > 0)
);
},
callbacks: {
label: function (tooltipItem, chartData) {
return (
chartData.datasets[tooltipItem.datasetIndex].label +
": " +
tooltipItem.yLabel.round(0)
);
},
},
},
animation: {
duration: 500,
easing: "linear",
},
plugins: {
datalabels: {
display: function (context) {
const axisMax = context.chart.scales["L"]
? context.chart.scales["L"].max
: 0;
const datasetLabelsSettings =
context.chart.data.datasets[context.datasetIndex].datalabels;
const isLabelOutside =
datasetLabelsSettings &&
datasetLabelsSettings.anchor === "end" &&
datasetLabelsSettings.align === "end";
return (
context.chart.isDatasetVisible(context.datasetIndex) &&
report.chartSettings.showDataLabels &&
((isLabelOutside &&
context.dataset.data[context.dataIndex] > 0) ||
context.dataset.data[context.dataIndex] >
axisMax * HIDE_DATALABELS_Y_LEVEL) &&
context.dataset.type !== "line"
);
},
formatter: (x) => {
return (x || 0).round(0);
},
},
},
legend: {
display: true,
onClick: function (event, legendItem) {
var index = legendItem.datasetIndex,
meta = null;
var tag = chart.data.datasets[index].tag;
var meta = chart.getDatasetMeta(index);
if (tag || isNumeric(tag)) {
chart.data.datasets
.filter((x) => x.tag == tag)
.forEach((item) => {
item.hidden = item.forcedHidden || !item.hidden;
});
} else {
meta.hidden = meta.hidden === null ? !meta.hidden : null;
}
chart.update();
},
position: "top",
labels: {
usePointStyle: true,
filter: function (legendItem, chartData) {
return (
chartData.datasets[legendItem.datasetIndex].displayInLegend ||
chartData.datasets[legendItem.datasetIndex].displayInLegend ==
undefined
);
return false;
},
},
},
cales: {
xAxes: [
{
stacked: true,
scaleLabel: {
display: true,
labelString: "Период",
},
},
],
yAxes: [
{
id: "L",
type: "linear",
position: "left",
stacked: true,
scaleLabel: {
display: true,
labelString: "Трудозатраты, чел-мес",
},
},
],
},
lines: [
5553, 5454, 5399, 5290, 5260, 4927, 4565, 4649, 5324, 5624, 5710, 5766,
5827, 5829, 5831, 5832, 5833, 5835, 5835, 5836, 5836, 5836, 5837, 583,
].map((x, i) => {
return {
datasetIndex: 0,
dataIndex: i,
yCoordinate: x,
color: "salmon",
width: 3,
};
}),
data: {
labels: [
"2022-01",
"2022-02",
"2022-03",
"2022-04",
"2022-05",
"2022-06",
"2022-07",
"2022-08",
"2022-09",
"2022-10",
"2022-11",
"2022-12",
"2023-01",
"2023-02",
"2023-03",
"2023-04",
"2024-05",
"2023-06",
"2023-07",
"2023-08",
"2023-09",
"2023-10",
"2023-11",
"2023-12",
],
datasets: [
{
label: "ОПИ (ресурсный профиль)",
findId: "ОПИ",
tag: "ОПИ",
type: "bar",
borderWidth: 1,
stack: "cnt",
groupType: "cnt",
backgroundColor: "#2196f3",
fill: false,
pointStyle: "rect",
detailMode: "point",
data: [
5356, 5802, 6105, 6258, 6524, 6690, 6697, 7348, 6578, 5742, 4626,
3678, 4809, 6038, 5891, 4526, 3637, 3601, 3471, 3618, 3548, 3428,
3330, 3448, 5031,
],
displayInLegend: false,
datalabels: {
anchor: "end",
align: "end",
offset: 0,
color: function (context) {
return "#2196f3";
},
},
},
],
},
};
const сhart = new Chart(ctx, options);
</script>
</html>
The plugin needs to have an unique id.
You could add an id (see following example):
const annotationLinePlugin = {
id: 'annotationLine',
....
}
Be also aware the afterDatasetsDraw hook has got a different signature (arguments).
https://www.chartjs.org/docs/latest/api/interfaces/Plugin.html#afterdatasetsdraw

How can i combine ApexCharts Candlestick chart with multiple lines in the same chart

I want to add multiple lines to ApexCharts candlestick chart. The lines have different lengths. How can i do this? (I develop in another language than java (LiveCode) but want to use ApexCharts for showing stock charts with resistance and trend lines in the Browser Widget).
Tried to copy line chart script in the candle chart but i could not get the lines to show in the candlestick chart. Below the original candlestick chart script is shown that occupies the html page (basic.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>CandleStick Chart</title>
<link href="../../assets/styles.css" rel="stylesheet" />
<style>
#chart {
max-width: 650px;
margin: 35px auto;
}
</style>
</head>
<body>
<div id="chart">
</div>
<script src="https://cdn.jsdelivr.net/npm/apexcharts#latest"></script>
<script src="../../assets/ohlc.js"></script>
<script>
var options = {
chart: {
height: 350,
type: 'candlestick',
},
series: [{
data: [{
x: new Date(1538778600000),
y: [6629.81, 6650.5, 6623.04, 6633.33]
},
{
x: new Date(1538780400000),
y: [6632.01, 6643.59, 6620, 6630.11]
},
{
x: new Date(1538782200000),
y: [6630.71, 6648.95, 6623.34, 6635.65]
},
{
x: new Date(1538784000000),
y: [6635.65, 6651, 6629.67, 6638.24]
},
{
x: new Date(1538785800000),
y: [6638.24, 6640, 6620, 6624.47]
},
{
x: new Date(1538787600000),
y: [6624.53, 6636.03, 6621.68, 6624.31]
},
{
x: new Date(1538789400000),
y: [6624.61, 6632.2, 6617, 6626.02]
},
{
x: new Date(1538791200000),
y: [6627, 6627.62, 6584.22, 6603.02]
},
{
x: new Date(1538793000000),
y: [6605, 6608.03, 6598.95, 6604.01]
},
{
x: new Date(1538794800000),
y: [6604.5, 6614.4, 6602.26, 6608.02]
},
{
x: new Date(1538796600000),
y: [6608.02, 6610.68, 6601.99, 6608.91]
},
{
x: new Date(1538798400000),
y: [6608.91, 6618.99, 6608.01, 6612]
},
{
x: new Date(1538800200000),
y: [6612, 6615.13, 6605.09, 6612]
},
{
x: new Date(1538802000000),
y: [6612, 6624.12, 6608.43, 6622.95]
},
{
x: new Date(1538803800000),
y: [6623.91, 6623.91, 6615, 6615.67]
},
{
x: new Date(1538805600000),
y: [6618.69, 6618.74, 6610, 6610.4]
},
{
x: new Date(1538807400000),
y: [6611, 6622.78, 6610.4, 6614.9]
},
{
x: new Date(1538809200000),
y: [6614.9, 6626.2, 6613.33, 6623.45]
},
{
x: new Date(1538811000000),
y: [6623.48, 6627, 6618.38, 6620.35]
},
{
x: new Date(1538812800000),
y: [6619.43, 6620.35, 6610.05, 6615.53]
},
{
x: new Date(1538814600000),
y: [6615.53, 6617.93, 6610, 6615.19]
},
{
x: new Date(1538816400000),
y: [6615.19, 6621.6, 6608.2, 6620]
},
{
x: new Date(1538818200000),
y: [6619.54, 6625.17, 6614.15, 6620]
},
{
x: new Date(1538820000000),
y: [6620.33, 6634.15, 6617.24, 6624.61]
},
{
x: new Date(1538821800000),
y: [6625.95, 6626, 6611.66, 6617.58]
},
{
x: new Date(1538823600000),
y: [6619, 6625.97, 6595.27, 6598.86]
},
{
x: new Date(1538825400000),
y: [6598.86, 6598.88, 6570, 6587.16]
},
{
x: new Date(1538827200000),
y: [6588.86, 6600, 6580, 6593.4]
},
{
x: new Date(1538829000000),
y: [6593.99, 6598.89, 6585, 6587.81]
},
{
x: new Date(1538830800000),
y: [6587.81, 6592.73, 6567.14, 6578]
},
{
x: new Date(1538832600000),
y: [6578.35, 6581.72, 6567.39, 6579]
},
{
x: new Date(1538834400000),
y: [6579.38, 6580.92, 6566.77, 6575.96]
},
{
x: new Date(1538836200000),
y: [6575.96, 6589, 6571.77, 6588.92]
},
{
x: new Date(1538838000000),
y: [6588.92, 6594, 6577.55, 6589.22]
},
{
x: new Date(1538839800000),
y: [6589.3, 6598.89, 6589.1, 6596.08]
},
{
x: new Date(1538841600000),
y: [6597.5, 6600, 6588.39, 6596.25]
},
{
x: new Date(1538843400000),
y: [6598.03, 6600, 6588.73, 6595.97]
},
{
x: new Date(1538845200000),
y: [6595.97, 6602.01, 6588.17, 6602]
},
{
x: new Date(1538847000000),
y: [6602, 6607, 6596.51, 6599.95]
},
{
x: new Date(1538848800000),
y: [6600.63, 6601.21, 6590.39, 6591.02]
},
{
x: new Date(1538850600000),
y: [6591.02, 6603.08, 6591, 6591]
},
{
x: new Date(1538852400000),
y: [6591, 6601.32, 6585, 6592]
},
{
x: new Date(1538854200000),
y: [6593.13, 6596.01, 6590, 6593.34]
},
{
x: new Date(1538856000000),
y: [6593.34, 6604.76, 6582.63, 6593.86]
},
{
x: new Date(1538857800000),
y: [6593.86, 6604.28, 6586.57, 6600.01]
},
{
x: new Date(1538859600000),
y: [6601.81, 6603.21, 6592.78, 6596.25]
},
{
x: new Date(1538861400000),
y: [6596.25, 6604.2, 6590, 6602.99]
},
{
x: new Date(1538863200000),
y: [6602.99, 6606, 6584.99, 6587.81]
},
{
x: new Date(1538865000000),
y: [6587.81, 6595, 6583.27, 6591.96]
},
{
x: new Date(1538866800000),
y: [6591.97, 6596.07, 6585, 6588.39]
},
{
x: new Date(1538868600000),
y: [6587.6, 6598.21, 6587.6, 6594.27]
},
{
x: new Date(1538870400000),
y: [6596.44, 6601, 6590, 6596.55]
},
{
x: new Date(1538872200000),
y: [6598.91, 6605, 6596.61, 6600.02]
},
{
x: new Date(1538874000000),
y: [6600.55, 6605, 6589.14, 6593.01]
},
{
x: new Date(1538875800000),
y: [6593.15, 6605, 6592, 6603.06]
},
{
x: new Date(1538877600000),
y: [6603.07, 6604.5, 6599.09, 6603.89]
},
{
x: new Date(1538879400000),
y: [6604.44, 6604.44, 6600, 6603.5]
},
{
x: new Date(1538881200000),
y: [6603.5, 6603.99, 6597.5, 6603.86]
},
{
x: new Date(1538883000000),
y: [6603.85, 6605, 6600, 6604.07]
},
{
x: new Date(1538884800000),
y: [6604.98, 6606, 6604.07, 6606]
},
]
}],
title: {
text: 'CandleStick Chart',
align: 'left'
},
xaxis: {
type: 'datetime'
},
yaxis: {
tooltip: {
enabled: true
}
}
}
// -------------------------
var chart = new ApexCharts(
document.querySelector("#chart"),
options
);
chart.render();
//--------------------------
</script>
</body>
</html>
n.a.
With apexcharts v3.20.1 and above, you can render a Candlestick chart together with line charts.
You will need to declare a data series with two data sets:
const lineData = [
{
x: new Date(1538778600000),
y: 6604,
}, {
x: new Date(1538782200000),
y: 6602,
},
];
const ohlcData = [
{
x: new Date(1538778600000),
y: [6629.81, 6650.5, 6623.04, 6633.33],
},
{
x: new Date(1538780400000),
y: [6632.01, 6643.59, 6620, 6630.11],
},
];
const series: ApexAxisChartSeries = [{
name: 'line',
type: 'line',
data: lineData,
}, {
name: 'candle',
type: 'candlestick',
data: ohlcData,
}];
Later on, you can then use it on your Chart component:
import Chart from 'react-apexcharts';
Chart options={chartOptions} series={series} type='candlestick' height={320} />
As of v3.8.6, this is not possible, but it is in the development roadmap.
Already suggested in this GitHub issue

How to hide Chart.js data labels for small screens

I am trying to hide data labels generated by the data labels plugin for small screens.
I thought that I could use the onResize property of chartjs and set display to false when the width got small. This is much like the hide labels solution found here.
Unfortunately, I've not been able to get this to work. I have the following CodePen that doesn't work.
var moneyFormat = wNumb({
decimals: 0,
thousand: ',',
prefix: '$',
negativeBefore: '-'
});
var percentFormat = wNumb({
decimals: 0,
suffix: '%',
negativeBefore: '-'
});
/*
* Unregister chartjs-plugins-datalabels - not really necessary for this use case
*/
Chart.plugins.unregister(ChartDataLabels);
var doughnutdata = {
labels: ['Housing',
'Food',
'Transportation',
'Clothing',
'Healthcare',
'Childcare',
'Misc'],
datasets: [
{
backgroundColor: [
'#9B2A00',
'#5B5C90',
'#6B8294',
'#1A6300',
'#BE0000',
'#B8A853',
'#64A856'
],
borderColor: [
'#FFFFFF',
'#FFFFFF',
'#FFFFFF',
'#FFFFFF',
'#FFFFFF',
'#FFFFFF',
'#FFFFFF'
],
data: [88480, 57680, 40050, 18430, 23860, 25840, 17490]
}
]
};
var chartOptions = {
responsive: true,
maintainAspectRatio: true,
legend: {
labels: {
boxWidth: 20
}
},
tooltips: {
callbacks: {
label: function (tooltipItem, data) {
var index = tooltipItem.index;
return data.labels[index] + ': ' + moneyFormat.to(data.datasets[0].data[index]) + '';
}
}
},
plugins: {
datalabels: {
anchor: 'end',
backgroundColor: function (context) {
return context.dataset.backgroundColor;
},
borderColor: 'white',
borderRadius: 25,
borderWidth: 1,
color: 'white',
font: {
size: 10
},
formatter: function (value, pieID) {
var sum = 0;
var dataArr = pieID.chart.data.datasets[0].data;
dataArr.map(function (data) {
sum += data;
});
var percentage = percentFormat.to((value * 100 / sum));
return percentage;
}
}
}
};
var doughnutID = document.getElementById('doughnutchart').getContext('2d');
var pieChart = new Chart(doughnutID, {
plugins: [ChartDataLabels],
type: 'doughnut',
data: doughnutdata,
options: chartOptions,
onResize: function(chart, size) {
var showLabels = (size.width < 500) ? false : true;
chart.options = {
plugins: {
datalabels: {
display: showLabels
}
}
};
}
});
Any ideas concerning what I'm doing wrong (and fixes) would be greatly appreciated.
Responsiveness can be implemented using scriptable options and in your case, you would use a function for the display option that returns false if the chart is smaller than a specific size. (Example):
options: {
plugins: {
datalabels: {
display: function(context) {
return context.chart.width > 500;
}
}
}
}
As usual, as soon as I post a question I come up with an answer. One solution using inline plugin definitions is given at the following CodePen. If you put a browser into developer mode and shrink the window to less than 540 px, the data labels will vanish.
The code is shown below:
"use strict";
/* global Chart */
/* global wNumb */
/* global ChartDataLabels */
/*
* Unregister chartjs-plugins-datalabels - not really necessary for this use case
*/
Chart.plugins.unregister(ChartDataLabels);
var moneyFormat = wNumb({
decimals: 0,
thousand: ",",
prefix: "$",
negativeBefore: "-"
});
var percentFormat = wNumb({
decimals: 0,
suffix: "%",
negativeBefore: "-"
});
var doughnutdata = {
labels: [
"Housing",
"Food",
"Transportation",
"Clothing",
"Healthcare",
"Childcare",
"Misc"
],
datasets: [
{
backgroundColor: [
"#9B2A00",
"#5B5C90",
"#6B8294",
"#1A6300",
"#BE0000",
"#B8A853",
"#64A856"
],
borderColor: [
"#FFFFFF",
"#FFFFFF",
"#FFFFFF",
"#FFFFFF",
"#FFFFFF",
"#FFFFFF",
"#FFFFFF"
],
data: [88480, 57680, 40050, 18430, 23860, 25840, 17490]
}
]
};
var chartOptions = {
responsive: true,
maintainAspectRatio: true,
legend: {
labels: {
boxWidth: 20
}
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var index = tooltipItem.index;
return (
data.labels[index] +
": " +
moneyFormat.to(data.datasets[0].data[index]) +
""
);
}
}
},
plugins: {
datalabels: {
anchor: "end",
backgroundColor: function(context) {
return context.dataset.backgroundColor;
},
borderColor: "white",
borderRadius: 25,
borderWidth: 1,
color: "white",
font: {
size: 10
},
formatter: function(value, pieID) {
var sum = 0;
var dataArr = pieID.chart.data.datasets[0].data;
dataArr.map(function(data) {
sum += data;
});
var percentage = percentFormat.to(value * 100 / sum);
return percentage;
}
}
}
};
var doughnutID = document.getElementById("doughnutchart").getContext("2d");
var pieChart = new Chart(doughnutID, {
plugins: [
ChartDataLabels,
{
beforeLayout: function(chart) {
var showLabels = (chart.width) > 500 ? true : false;
chart.options.plugins.datalabels.display = showLabels;
}
},
{
onresize: function(chart) {
var showLabels = (chart.width) > 500 ? true : false;
chart.options.plugins.datalabels.display = showLabels;
}
}
],
type: "doughnut",
data: doughnutdata,
options: chartOptions
});
I hope that this is useful.

ChartNew.js - Remove/Hide zero label from Pie Chart

I'm trying to remove zero(0) label from pie chart in ChartNew.js.
Can't figure it out.
Below is the example:
var pieData = [
{
value: 0,
color: "sandybrown",
title: "label1",
},
{
value: 10,
color: "gold",
title: "label2",
},
{
value: 46,
color: "darkviolet",
title: "label3",
},
{
value: 0,
color: "green",
title: "label4",
},
{
value: 33,
color: "DeepSkyBlue",
title: "label5",
}
];
var myoptions = {
animateRotate : true,
animateScale : false,
animationByData : false,
animationSteps : 50,
canvasBorders : true,
canvasBordersWidth : 0,
canvasBordersColor : "black",
legend : true,
inGraphDataShow : true,
animationEasing: "linear",
annotateDisplay : true,
spaceBetweenBar : 5,
graphTitleFontSize: 18,
extrapolateMissingData : false
};
var myPie = new Chart(document.getElementById("canvas1").getContext("2d")).Pie(pieData, myoptions);
<SCRIPT src='https://rawgit.com/FVANCOP/ChartNew.js/master/ChartNew.js'></SCRIPT>
<canvas id="canvas1" height="500" width="500"></canvas>
[https://jsfiddle.net/boxxevolution/wb64oL66/2/][1]
Im trying to remove label1 and label4 from the chart.
As suggested by V-Q-A NGUYEN, add the following line in options,
inGraphDataTmpl: "<%=(v6 > 0 ? v6+' %' : ' ')%>",

Format tooltip content of Google column chart generated via Keen

We use Keen on a site to track view data. This works well but I’m having an issue with how some of the data is presented in the graphs (using v3.0.5 of the JS SDK). On the users dashboard we have a graph showing the last 4 months data (timeframe : this_4_months). I have a query though -
When the user hovers over one of the columns you see detail in a tooltip e.g. "April 1, 2015 12:00:00 AM" - is there any way to format this tooltip into something more user-friendly? e.g. "April 2015"
Keen.ready(function() {
var query = new Keen.Query('count', {
'eventCollection' : 'profile_views',
'timeframe' : 'this_4_months',
'interval' : 'monthly',
'groupBy' : 'view.membership_type',
'filters' : [
{
'property_name' : 'view.user_id',
'operator' : 'eq',
'property_value' : String(user_id)
}
]
});
client.draw(query, document.getElementById(element_id), {
chartType: 'columnchart',
width : graph_width,
height : 250,
colors : ['#abdd99', '#8dc7d9', '#eeeeee'],
colorMapping : {
'pro' : '#abdd99',
'basic' : '#8dc7d9'
},
labelMapping: {
"basic": "BASIC",
"pro": "PRO"
},
title : '',
chartOptions: {
width : '100%',
height : '100%',
isStacked: true,
fontName : 'Helvetica',
fontSize : '11px',
chartArea : {
left : '10px',
top : '0',
width : '90%',
height : '90%'
},
axisTitlesPosition : 'in',
vAxis : {
viewWindowMode : 'pretty',
gridlines : { color : '#eeeeee' },
baselineColor : '#eeeeee',
textPosition : 'in'
},
hAxis : {
viewWindowMode : 'pretty',
gridlines : {
color : '#eeeeee'
},
baselineColor : '#eeeeee',
textPosition : 'none'
},
legend : {
position : 'in'
},
titlePosition : 'none'
}
});
});
Here is a screenshot of how the tooltip appears :
Instead of
var chart = keenIoClient.draw(query, document.getElementById("chart2"), options );
Collect all your data to array manually, so you can add more columns there. Here is example with dates and pageviews:
keenIoClient.run(query, function(err, response){
if (err) {
// there was an error!
}
else {
var arrayData = [];
arrayData.push(['Day','Views']);
response.result.forEach(function (element, index, array) {
var date = new Date(element.timeframe.start);
arrayData.push([date.getDate() + '/' + (date.getMonth() + 1) + '/' + date.getFullYear() , element.value]);
});
var data = google.visualization.arrayToDataTable(arrayData);
var chart = new google.visualization.ColumnChart( document.getElementById('chart2'));
chart.draw(data, options);
}
});
The "options" variable stays the same.
P.S. on the way you can set up the format for your dates.
P.P.S. in my case the Query was:
var query = new Keen.Query("count", {
eventCollection: "views",
interval: "daily",
timeframe: "this_7_days",
});