https://github.com/Wikunia/Chart.js/tree/Double-Y-Axis was forked from the early (2 years ago) version of Chart.js
currentChart.addData is not a function
This plug does not have this feature. That is why you get this error.
By the way, you can take a look at the latest version of Chart.js. There is an alpha version issue - https://github.com/nnnick/Chart.js/issues/17
This says: is it possible to add the second Y axis differently?
With the current version? Yes, if you are willing to compromise on several parameters. I believe you could get around these tradeoffs, but the added complexity is too much :-)
High level steps
- One of the data sets controls the scale β select another data set, determine the scale based on it, and then normalize the values ββbased on that scale and the actual scale.
- You do not want the tooltips to display a normalized value, so you need to change the tooltip function to denormalize the values
- Mark labels for secondary y axis
The first 2 can be performed in redefinition of initialization and in the last 1 in redefinition of a draw.
Declaration and Initialization
Of course, we need to expand the chart first. And let's start the scale from 0 and turn off the grid lines to reduce complexity.
So,
Chart.types.Line.extend({ name: "Line2Y",
and
var ctx = document.getElementById("chart").getContext("2d"); var myLine1 = new Chart(ctx).Line2Y(lineChartData1, { scaleBeginAtZero: true, scaleShowGridLines: false });
Normalizing factor calculation
initialize: function (data) { // figure out which dataset has the max value - that is the one that drives the scale var max = 0; var datasetToNotScale = 0; var datasetToScale = 1; data.datasets.forEach(function (dataset, i) { dataset.data.forEach(function (e) { if (e > max) { max = e; datasetToNotScale = i; datasetToScale = (i == 0 ? 1 : 0); } }) }) var datasetToScaleLabel = data.datasets[datasetToScale].label; var startPoint = this.options.scaleFontSize; var endPoint = this.chart.height - (this.options.scaleFontSize * 1.5) - 5; // use the helper function to get the scale for both datasets var notScaleRange = Chart.helpers.calculateScaleRange( data.datasets[datasetToNotScale].data, endPoint - startPoint, this.options.scaleFontSize, this.options.scaleBeginAtZero, this.options.scaleIntegersOnly ) this.scaleRange = Chart.helpers.calculateScaleRange( data.datasets[datasetToScale].data, endPoint - startPoint, this.options.scaleFontSize, this.options.scaleBeginAtZero, this.options.scaleIntegersOnly )
Once we have a scale for both datasets, calculate the normalizing coefficient (the ratio of the maximum value of both scales, since we set the scale of the scale starting at 0)
var normalizingFactor = notScaleRange.max / this.scaleRange.max;
Normalization (for plotting) and Denormalization (for tooltips)
Use this to update a dataset that does not control scale.
// update one of our datasets! data.datasets[datasetToScale].data.forEach(function (e, i) { data.datasets[datasetToScale].data[i] = e * normalizingFactor; })
And of course, counteract this by denormalizing in the tooltip function (pay attention to Math.round - which takes care of a slight loss in the accuracy of the conversion back and forth)
this.options.multiTooltipTemplate = function (d) { if (d.datasetLabel == datasetToScaleLabel) return Math.round(d.value / normalizingFactor, 6); else return d.value; }
Secondary axis label display
First, make sure you have enough space on the right side.
draw: function () { this.scale.xScalePaddingRight = this.scale.xScalePaddingLeft;
Then, as soon as the actual chart is drawn, draw our marks on the secondary axis
this.chart.ctx.font = Chart.helpers.fontString(self.fontSize, self.fontStyle, self.fontFamily) this.chart.ctx.textAlign = 'left'; this.chart.ctx.textBaseline = "middle"; this.chart.ctx.fillStyle = "#666"; var label = this.scaleRange.min; var yStep = (this.scale.endPoint - this.scale.startPoint) / this.scaleRange.steps for (var i = 0, y = this.scale.endPoint; i <= this.scaleRange.steps; i++) { this.chart.ctx.fillText(label, this.chart.width - this.scale.xScalePaddingRight + 10, y); y -= yStep; label += this.scaleRange.stepValue }
and we are done!
Fiddle - http://jsfiddle.net/u2Lru6vv/
Note. Overlapping two charts with the y-axis (as we did above) is another (slightly less invasive) parameter, but the problem is that you are losing tooltips for the base chart.