https://github.com/Wikunia/Chart.js/tree/Double-Y-Axis was forked from an early (2 years back) version of Chart.js
currentChart.addData is not a function
The fork does not have this function. That's why you are getting this error.
You might want to take a look at the latest version of Chart.js by the way. There is a related issue that's available in the alpha version - https://github.com/nnnick/Chart.js/issues/17
This said: Is it possible to add a second Y-axis in another way?
With the current version? Yes, if you are willing to compromise on a couple of options. I believe you could workaround these compromises too, but the added complexity is a bit too much :-)
High Level Steps
- One of the datasets drives the scale - pick the other dataset, figure out the scale based on it alone and then normalize the values based on this scale and the actual scale
- You don't want the tooltips to show the normalized value, so you need to modify the tooltip function to denormalize the values
- Render the labels for the secondary y axis
The first 2 can be done in the initialize override and the last 1 in the draw override.
Declaration and Initialization
Of course, we need to extend the chart first. And let's begin the scale at 0 and turn off the grid lines to reduce the 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
});
Calculating the Normalizing Factor
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 the scale for both datasets, calculate the normalizing factor (ratio of max value of both scales, since we set the chart scale to begin at 0)
var normalizingFactor = notScaleRange.max / this.scaleRange.max;
Normalizing (for plotting) and Denormalizing (for the Tooltips)
Use this to update the dataset that does not drive the 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 (notice the Math.round - that takes care of a slight loss of precision converting back and forth)
this.options.multiTooltipTemplate = function (d) {
if (d.datasetLabel == datasetToScaleLabel)
return Math.round(d.value / normalizingFactor, 6);
else
return d.value;
}
Rendering the Secondary Axis Labels
First make sure you have enough space on the right hand side
draw: function () {
this.scale.xScalePaddingRight = this.scale.xScalePaddingLeft;
Then, once the actual chart is drawn, draw our secondary axis labels
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 - overlaying 2 charts with a mirrored y axis (like we did above) is another (slightly less invasive) option, but the problem is you lose tooltips for the underlying chart.