Reputation: 13213
I'm using: http://www.chartjs.org/docs/#chart-configuration-mixed-chart-types + AngularJS wrapper: http://jtblin.github.io/angular-chart.js/
When creating a chart, you have the option to overlay different chart types on top of each other as separate datasets.
To do this, you must set a type for each dataset individually. You can create mixed chart types with bar and line chart types.
When creating the chart you must set the overall type as bar.
There is a slight difference how lines are presented - if I display bar
and line
on the same graph, the line does not go to an end.
It doesn't really matter that much, unless I have single element only...
ChartJS displays line charts with single element as a dot - Chartjs linechart with only one point - how to center (and they suggest added some null
elements, I'm not sure if I want to follow that route)
Here some example how to draw vertical line on canvas: http://jsfiddle.net/zk9oc4c9/ (feels like too much effort calculating everything manually)
Maybe there is a better way?
Upvotes: 5
Views: 6323
Reputation: 13213
This helped me a lot: How to draw Horizontal line on Bar Chart Chartjs
Here is the working demo: http://codepen.io/stefek99/pen/ZeXzBr?editors=1010
Chart.pluginService.register({
afterDraw: function(chart) {
if (typeof chart.config.options.lineAt != 'undefined') {
var lineAt = chart.config.options.lineAt;
var ctxPlugin = chart.chart.ctx;
var xAxe = chart.scales[chart.config.options.scales.xAxes[0].id];
var yAxe = chart.scales[chart.config.options.scales.yAxes[0].id];
var position = yAxe.getPixelForValue(lineAt)
ctxPlugin.strokeStyle = "red";
ctxPlugin.beginPath();
ctxPlugin.moveTo(xAxe.left, position);
ctxPlugin.lineTo(xAxe.right, position);
ctxPlugin.stroke();
}
}
});
var _drawLineOnTopOfADot = function(chartData) {
if (chartData.labels.length !== 1) return; // only handling graphs that have single item
if (chartData.dataSetOverride.length < 2) return; // only when we have at least two types of graph
var indexOfLineGraph = -1;
for (var i=0; i<chartData.dataSetOverride.length; i++) {
if (chartData.dataSetOverride[i].type === "line") {
indexOfLineGraph = i;
break;
}
}
if (indexOfLineGraph === -1) return; // no line chart, no worries
chartData.options = chartData.options || {};
chartData.options.lineAt = chartData.data[indexOfLineGraph][0];
}
I've spent way too much time on that.
Upvotes: 3
Reputation: 10705
In addition to the options that you found, you could use the chart.js annotation plugin to easily draw your line without having to mess with rendering pixels in your canvas manually. Note, the plugin is created/supported by the same team as chart.js and is mentioned in the chart.js docs.
Here is an example codepen demonstrating your scenario.
Once you add the plugin, you simply just set additional properties in your chart config.
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["January"],
datasets: [{
label: 'Dataset 1',
borderColor: window.chartColors.blue,
borderWidth: 2,
fill: false,
data: [5]
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Chart.js Stacked Bar and Unstacked Line Combo Chart'
},
tooltips: {
mode: 'index',
intersect: true
},
annotation: {
annotations: [{
type: 'line',
mode: 'horizontal',
scaleID: 'y-axis-0',
value: 5,
borderColor: 'rgb(75, 192, 192)',
borderWidth: 4,
label: {
enabled: false,
content: 'Test label'
}
}]
}
}
});
This is still a little cumbersome because you have you define the location of the line separate from your data point value, but its certainly easier then the other approach.
I'm not sure if there is an existing angular extension of the plugin, but I assume you can create one easy enough if need be.
Upvotes: 1