Is there a way to get a vertical scrubber line when hovering over a line chart using chart.js v2? Similar to the way a vertical line appears using this rickshaw example: http://code.shutterstock.com/rickshaw/examples/formatter.html
I can use tool tips on the actual points along the line, but it'd like to be able to have a vertical line appear as the user hovers over the chart and scrubs left to right
You can extend Chart.js to do this. Just override the showTooltip method after initializing the chart.
Preview
Script
Chart.types.Line.extend({
name: "LineAlt",
initialize: function () {
Chart.types.Line.prototype.initialize.apply(this, arguments);
var originalShowTooltip = this.showTooltip;
this.showTooltip = function (activePoints) {
if (activePoints.length) {
var ctx = this.chart.ctx;
var scale = this.scale;
ctx.save();
ctx.strokeStyle = '#aaa';
ctx.beginPath();
ctx.moveTo(activePoints[0].x, scale.startPoint);
ctx.lineTo(activePoints[0].x, scale.endPoint);
ctx.stroke();
ctx.restore();
}
return originalShowTooltip.apply(this, arguments);
}
}
});
and then
new Chart(ctx).LineAlt(data);
Fiddle - http://jsfiddle.net/98gz1fhw/
Related
How to add color box on chartjs multiline tooltip?
What I did for multiple line is:
mode: 'single',
callbacks: {
afterBody: function(data) {
var multistringText = ['first string'];
// do some stuff
multistringText.push('another string');
return multistringText;
}
}
}
But I wanted a color box along with the multiple text with different color on them.
The code is from: https://stackoverflow.com/questions/29302392/chartjs-tooltip-line-breaks
I am using chart.js to create a stacked bar chart and while I have succeed to move and rotate the xaxis labels to be shown on the top of the bars, when I use mouse to move over the bars, the whole chart appears distorted.
this is the normal
and this is what i get after mouse over:
here is the code
this is what i use to rotate xaxis labels:
https://jsfiddle.net/staverist/zhocr17t/96/
animation: {
duration: 1,
onComplete: function() {
var chartInstance = this.chart;
var ctx = chartInstance.ctx;
ctx.textAlign = "left";
ctx.font = "bold 10px Arial";
ctx.fillStyle = "black";
Chart.helpers.each(this.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
Chart.helpers.each(meta.data.forEach(function (bar, index) {
ctx.save();
// Translate 0,0 to the point you want the text
ctx.translate(bar._model.x, bar._model.y - 30);
// Rotate context by -90 degrees
ctx.rotate(-0.5 * Math.PI);
// Draw text
//ctx.fillText(value,0,0);
if(bar._datasetIndex==0){
ctx.fillText(bar._model.label, 0, 0);
ctx.restore();
}
}),this)
}),this);
}
This is because you are not restoring the canvas state after rotating it. Instead of restoring it inside the if statement, you should restore it outside, like so :
...
if (bar._datasetIndex == 0) {
ctx.fillText(bar._model.label, 0, 0);
}
ctx.restore(); //<- restore canvas state
...
also, you should better create a plugin (to prevent label flickering), instead of drawing the labels on animation complete.
Here is the working example on JSFiddle
Is there a way to create vertical lines (event lines, phase changes) using Chart.JS 2.0?
I've seen some examples online (see this related question), HOWEVER, when using Moment.js to create the horizontal axis, it is not possible to give LineAtIndex a moment.js date to create a line at that date.
var originalLineDraw = Chart.controllers.line.prototype.draw;
Chart.helpers.extend(Chart.controllers.line.prototype, {
draw: function() {
originalLineDraw.apply(this, arguments);
var chart = this.chart;
var ctx = chart.chart.ctx;
var index = chart.config.data.lineAtIndex;
if (index) {
var xaxis = chart.scales['x-axis-0'];
var yaxis = chart.scales['y-axis-0'];
ctx.save();
ctx.beginPath();
ctx.moveTo(xaxis.getPixelForValue(undefined, index), yaxis.top);
ctx.strokeStyle = '#ff0000';
ctx.lineTo(xaxis.getPixelForValue(undefined, index), yaxis.bottom);
ctx.stroke();
ctx.restore();
}
}
});
Here's a fiddle demonstrating the problem:
https://jsfiddle.net/harblz/0am8vehg/
I believe my issue is that I don't properly understand this bit of code:
var xaxis = chart.scales['x-axis-0'];
var yaxis = chart.scales['y-axis-0'];
If I am able to figure this out, I'll post a working fiddle here for any future users tackling the same project.
Thanks you for your time reading this :)
I tried multiple plugins, but none could handle Charts with cartesian axes of type time. My rather simple solution:
First register the chart plugin globally:
Chart.plugins.register({
drawLine: function (chart, xValue, color = 'rgba(87,86,86,0.2)') {
const canvas = chart.chart
const context = canvas.ctx
context.beginPath()
context.moveTo(xValue, 6) // top
context.lineTo(xValue, canvas.height - 73) // bottom
context.strokeStyle = color
context.stroke()
},
afterDraw: function (chart) {
const xScale = chart.scales['x-axis-0']
if (chart.options.verticalLine) {
chart.options.verticalLine.forEach((line) => {
const xValue = xScale.getPixelForValue(line)
if (xValue) {
this.drawLine(chart, xValue)
}
})
}
}
})
Then add verticalLine Array to your chart definition:
options: {
scales: { xAxes: [{ type: 'time' }] },
verticalLine: ['2019-04-1', '2019-07-01', '2019-10-01'],
}
I am trying to hot swap chart types based on select box changes. If data needs to be updated, it changes.
So for example, on page load I create a chart like this:
var config = {
type: 'line',
data: {
labels: this.labels,
datasets: [{
label: 'Some Label',
data: this.values
}]
},
options: {
responsive: true
}
}
var context = document.getElementById('canvas').getContext('2d');
window.mychart = new Chart(context, config);
But then I change the combo box to a bar chart. I have tested the data with bar chart on page load, and it worked great.
Here's how I am trying to change the chart.
window.mychart.destroy();
// chartType = 'bar'
config.type = chartType;
var context = document.getElementById('canvas').getContext('2d');
window.mychart = new Chart(context, config);
window.mychart.update();
window.mychart.render();
But nothing happens. The line chart remains. How can I dynamically change the chart type? (Even if it means destroying & re-creating the chart canvas).
UPDATE
Note it looks like it is actually destroying the chart, but keeps redrawing a line chart, even though I do console.log(config.type); and it returns bar, not line
The Fix
Destroy the old chart (to remove event listeners and clear the canvas)
Make a deep copy of the config object
Change the type of the copy
Pass the copy instead of the original object.
Here is a working jsfiddle example
Example Overview:
var temp = jQuery.extend(true, {}, config);
temp.type = 'bar'; // The new chart type
myChart = new Chart(ctx, temp);
NOTE: Using version 2.0.1 of Chart.js
Why this works
Chart.js modifies the config object you pass in. Because of that you can not just change 'config.type'. You could go into the modified object and change everything to the type you want, but it is much easier to just save the original config object.
Just to follow up that this is now fixed in v.2.1.3, as followed through by https://stackoverflow.com/users/239375/nathan
document.getElementById('changeToLine').onclick = function() {
myChart.destroy();
myChart = new Chart(ctx, {
type: 'line',
data: chartData
});
};
Confirmed fixed in latest version. Check out http://codepen.io/anon/pen/ezJGPB and press the button under the chart to change it from a bar to a line chart.
No need to destroy and re-create, you just have to change the type from the chart's config variable then update the chart.
var chartCfg = {
type: 'pie',
data: data
};
var myChart = new Chart(ctx, chartCfg );
function changeToBar() {
chartCfg.type = "bar";
myChart.update();
}
In chart.js 3.8.0 you can do it like this:
let chart = new Chart(ctx, {
type: "line",
data: {
// ...
},
options: {
// ...
}
});
chart.config.type = "bar";
chart.update();
you can also change data and options this way
chart.js docs on updating:
https://www.chartjs.org/docs/latest/developers/updates.html
codepen example: https://codepen.io/3zbumban/pen/yLKMMJx
The alternate solution can be as simple as creating both the charts in separate Div elements. Then as per your condition just make one visible and hide other in the javascript. This should serve the purpose you may have for changing the chart type for your requirement.
In ChartJS, the chart type can also be changed easily like chart data. Following example might be helpful
my_chart.type = 'bar';
my_chart.update();
In ChartJS 3, :
var options = // your options.
var data = { ...myChart.data }; // deep copy of the data
var ctx = document.getElementById('myChart_id').getContext('2d');
myChart.destroy()
/// Modify ctx or data if you need to.
myChart = new Chart(ctx, {
type: chart_type,
data: data
});
Chart.options = options;
myChart.update();
I am implementing the line graph using chartjs plugin. My line graph is drawn
from bottom to top when loading. I would like the lines animated from left to right. How can I change?
You can extend the chart and override the starting values for the animation in the initialize override, like so
Chart.types.Line.extend({
name: "LineAlt",
initialize: function(data){
Chart.types.Line.prototype.initialize.apply(this, arguments);
this.eachPoints(function(point, index){
Chart.helpers.extend(point, {
x: this.scale.calculateX(0),
y: this.scale.calculateY(point.value)
});
point.save();
}, this);
}
});
Then just use the extended chart, like so
...
new Chart(ctx).LineAlt(data);
Fiddle - http://jsfiddle.net/kLg5ntou/