Chartjs How to render a custom horizon line under X-Axis - chart.js

I am working ChartJS component using angular2. I would like to know whether there is any way to render as this image or not.
Basically, The Bar Chart rendered on the grid. When I click on the column bar, for example, June the horizontal line should be displayed with the up arrow at the exact month under the column bar. Do you have any suggestions? Thanks in advance.

You can capture the onclick event of the canvas and check which bar has been clicked with the getElementAtEvent method of chartjs. getElementAtEvent gives you all the relevant information you need (chart-width, x-coordinate of the bar, label etc.) to draw a custom line below the chart.
canvas.onclick = function (evt) {
var activePoints = myBarChart.getElementAtEvent(evt);
if (activePoints[0]) {
//draw your custom line
}
};
The snippet below has two canvas. One for chart.js to draw the actual chart and the second below to draw a line with the text of the clicked label.
var canvas = document.getElementById('myChart');
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
backgroundColor: "rgba(255,99,132,0.2)",
borderColor: "rgba(255,99,132,1)",
borderWidth: 2,
hoverBackgroundColor: "rgba(255,99,132,0.4)",
hoverBorderColor: "rgba(255,99,132,1)",
data: [65, 59, 20, 81, 56, 55, 40],
}]
};
var option = {
scales: {
yAxes: [{
stacked: true,
gridLines: {
display: true,
color: "rgba(255,99,132,0.2)"
}
}],
xAxes: [{
gridLines: {
display: false
}
}]
}
};
var myBarChart = Chart.Bar(canvas, {
data: data,
options: option
});
canvas.onclick = function (evt) {
var activePoints = myBarChart.getElementAtEvent(evt);
if (activePoints[0]) {
var chart = activePoints[0]._chart;
var canvasX = document.getElementById('xAxis2');
// set the width of the second canvas to the chart width
canvasX.width = chart.width;
var canvas2D = canvasX.getContext('2d');
// draw the line
canvas2D.moveTo(0, 20);
canvas2D.lineTo(activePoints[0]._view.x - 10, 20);
canvas2D.lineTo(activePoints[0]._view.x, 0);
canvas2D.lineTo(activePoints[0]._view.x + 10, 20);
canvas2D.lineTo(canvasX.width, 20);
canvas2D.stroke();
// add the label text
canvas2D.font = '12px serif';
canvas2D.fillText('for ' + activePoints[0]._view.label, canvasX.width - 100, 15);
}
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.min.js"></script>
<canvas id="myChart" width="400" height="250"></canvas>
<canvas id="xAxis2" height="20"></canvas>

Related

How to draw border all the way around bar element

I would like to use chart.js to draw a bar in a horizontal bar chart that has a border all the way around.
As can be seen on the image I'm successful in applying a border but I can't figure out how to get a border on the left side; which would make it a full square.
Any help would be appreciated.
You can set the borderSkipped option to false, depending on if you do it in the options or on the dataset level it will apply to all bars or only the bars of that specific dataset.
var options = {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 5,
borderColor: 'pink',
borderSkipped: false //Apply setting only to this bar dataset
}]
},
options: {
elements: {
bar: {
borderSkipped: false // Apply setting to all bar datasets
}
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.js"></script>
</body>

Display Chartjs tooltip values outside the canvas - multi line chart

I am trying to replicate the NSE Stock exchange comparison graph as displayed here.
I am using Chartjs 2.0. I have 2 line graphs in the chart.
On hovering on the data points I want to show the tooltip's ylabel in a div which is outside the canvas, (like the changing values are displayed in the top right corner in the chart above)
I found GRUNT's code helpful
Moving vertical line when hovering over the chart using chart.js
You can use Label Callback
document.getElementById('y-label').textContent = tooltipItem.yLabel;
Chart.defaults.LineWithLine = Chart.defaults.line;
Chart.controllers.LineWithLine = Chart.controllers.line.extend({
draw: function(ease) {
Chart.controllers.line.prototype.draw.call(this, ease);
if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
var activePoint = this.chart.tooltip._active[0],
ctx = this.chart.ctx,
x = activePoint.tooltipPosition().x,
topY = this.chart.scales['y-axis-0'].top,
bottomY = this.chart.scales['y-axis-0'].bottom;
// draw line
ctx.save();
ctx.beginPath();
ctx.moveTo(x, topY);
ctx.lineTo(x, bottomY);
ctx.lineWidth = 2;
ctx.strokeStyle = '#07C';
ctx.stroke();
ctx.restore();
}
}
});
var chart = new Chart(ctx, {
type: 'LineWithLine',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'],
datasets: [{
label: 'Statistics',
data: [3, 1, 2, 5, 4, 7, 6],
backgroundColor: 'rgba(0, 119, 204, 0.8)',
borderColor: 'rgba(0, 119, 204, 0.3)',
fill: false
}]
},
options: {
responsive: false,
tooltips: {
intersect: false,
callbacks: {
label: function(tooltipItem, data) {
var label = data.datasets[tooltipItem.datasetIndex].label || '';
if (label) {
label += ': ';
}
label += Math.round(tooltipItem.yLabel * 100) / 100;
document.getElementById('y-label').textContent = tooltipItem.yLabel;
return label;
}
}
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<h4 id="y-label"> </h4>
<canvas id="ctx" height="200"></canvas>

ChartJS with ChartJS DataLabels: Change Color per Dataset for Value Labels

I'm using ChartJS with the plug-in ChartJS DataLabels to show text values right next to the points (who would have thought that a plugin is necessary for this basic task, but I digress).
My issue I need to vary the color of my text labels along with the individual dataset. But so far I haven't found a solution. I'm adding new datasets dynamically, they're not statically pre-loaded. The color should match the color of the dataset.
Suppose I have
var colorpalette = ["red", "blue", "green", "magenta", "yellow", "brown", "purple", "orange", "black", "gray"];
var currseriesnum = 0;
var chart = null;
function setUpChart() {
var ctx = document.getElementById('chartArea').getContext('2d');
chart = new Chart(ctx, {
type: 'line',
data: {
labels: monthnames,
datasets: [] // Initially blank - series added dynamically with chart.update()
},
options: {
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
plugins: { // ChartsJS DataLabels initialized here
datalabels: {
anchor: 'end',
align: 'bottom',
formatter: Math.round,
font: {
weight: 'bold',
size: 16
},
color: colorpalette[currseriesnum] // Pick color dynamically
}
}
}
});
}
Doesn't work. Also tried a function, color: function(context), but unsure how to retrieve the current index of the dataset I'm getting here.
I'm adding series to the chart dynamically (initially empty) as below, and incrementing the global var currseriesnum.
chart.data.datasets.push({
label: keyValueSelection.label,
fill: false,
data: keyValueSelection.value,
borderColor: colorpalette[currseriesnum],
borderWidth: 2
});
chart.update();
currseriesnum++;
They gave me the answer on the ChartJS DataLabels forum:
plugins: {
datalabels: {
color: function(ctx) {
// use the same color as the border
return ctx.dataset.borderColor
}
}
}

Chart JS data labels getting cut

I am using Chart JS with data label plugin and I want to show data labels next to the bar and pie chart but noticed that some of the data labels are getting cut or going out of canvas. Is their any way to fix this?
var chartData3 = {
labels: ["January", "February", "March", "April", "May", "June"],
datasets: [{
backgroundColor: "#79D1CF",
data: [60, 90, 81, 56, 55, 40],
datalabels: {
align: 'end',
anchor: 'end'
}
}]
};
https://plnkr.co/edit/I906pCN8tdrrOX2hgN0W?p=preview
Thanks,
MSK
You need to set padding to display the labels properly. Also, adjust the canvas width and height to account for padding so that your chart doesn't get too small.
options: {
layout: {
padding: {
left: 50,
right: 50,
top: 50,
bottom: 50
}
}
}
Set max tick in chart option, for example:
this.chartOption.scales.yAxes[0].ticks.max = Math.max(...chartData3.datasets[0].data) * 1.2

chartjs: set default min for the line chart

I have a line chart which is drawing at its default min. I have changed the min of the chart on the button click and then update it. Problem is i want to toggle on the button click. Like if i have set the min on the button click. by clicking again it should change again back to the normal min. But in that it did not have a min at all in the default case.
I am setting this like
$('#action').off().on('click', function() {
myLineChart.options.scales.yAxes[0].ticks.min = -50;
myLineChart.update();
})
This is my Jsfiddle
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
backgroundColor: "rgba(255,99,132,0.2)",
borderColor: "rgba(255,99,132,1)",
borderWidth: 2,
hoverBackgroundColor: "rgba(255,99,132,0.4)",
hoverBorderColor: "rgba(255,99,132,1)",
data: [65, 59, 20, 81, 56, 55, 40],
}]
};
var option = {
legend: false,
title: {
display: true,
}
};
var myLineChart = Chart.Line('myChart', {
data: data,
options: option
});
$('#action').off().on('click', function() {
myLineChart.options.scales.yAxes[0].ticks.min = -50;
myLineChart.update();
$("#action2").show();
$("#action").hide();
})
$('#action2').off().on('click', function() {
myLineChart.options.scales.yAxes[0].ticks.min = 0;
myLineChart.update();
$("#action").show();
$("#action2").hide();
})
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
<canvas id="myChart" width="400" height="200"></canvas>
<button id="action" style="display: block;">action</button>
<button id="action2" style="display: none;">action</button>
You can split the task by adding another button.
Please Add one more button on HTML with same name but display none.
<button id="action" style="display: block;">action</button>
<button id="action2" style="display: none;">action</button>
Add one More function
$('#action').off().on('click', function() {
myLineChart.options.scales.yAxes[0].ticks.min = -50;
myLineChart.update();
$("#action2").show();
$("#action").hide();
})
$('#action2').off().on('click', function() {
myLineChart.options.scales.yAxes[0].ticks.min = 0;
myLineChart.update();
$("#action").show();
$("#action2").hide();
})
OnClick you can hide / show (toggle)