}
this.yticks = new Array();
- for (var i = 0; i < 1; i++ ) {
+ for (var i = 0; i < this.options.yAxes.length; i++ ) {
var axis = this.options.yAxes[i];
for (var j = 0; j < axis.ticks.length; j++) {
var tick = axis.ticks[j];
var label = tick.label;
var pos = 1.0 - (axis.yscale * (tick.v - axis.minyval));
if ((pos >= 0.0) && (pos <= 1.0)) {
- this.yticks.push([pos, label]);
+ this.yticks.push([i, pos, label]);
}
}
}
// TODO(danvk): consider all axes in this computation.
this.area = {
+ // TODO(danvk): per-axis setting.
x: this.options.yAxisLabelWidth + 2 * this.options.axisTickSize,
y: 0
};
* Draw an X/Y grid on top of the existing plot
*/
DygraphCanvasRenderer.prototype.render = function() {
+ // Shrink the drawing area to accomodate additional y-axes.
+ if (this.layout.options.yAxes.length == 2) {
+ // TODO(danvk): per-axis setting.
+ this.area.w -= (this.options.yAxisLabelWidth + 2 * this.options.axisTickSize);
+ } else if (this.layout.options.yAxes.length > 2) {
+ this.dygraph_.error("Only two y-axes are supported at this time. (Trying " +
+ "to use " + this.layout.yAxes.length + ")");
+ }
+
// Draw the new X/Y grid
var ctx = this.element.getContext("2d");
ctx.strokeStyle = this.options.gridLineColor;
ctx.lineWidth = this.options.axisLineWidth;
for (var i = 0; i < ticks.length; i++) {
+ if (ticks[i][0] != 0) continue; // TODO(danvk): per-axis property
var x = this.area.x;
- var y = this.area.y + ticks[i][0] * this.area.h;
+ var y = this.area.y + ticks[i][1] * this.area.h;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x + this.area.w, y);
ctx.strokeStyle = this.options.gridLineColor;
ctx.lineWidth = this.options.axisLineWidth;
for (var i=0; i<ticks.length; i++) {
- var x = this.area.x + ticks[i][0] * this.area.w;
+ var x = this.area.x + ticks[i][1] * this.area.w;
var y = this.area.y + this.area.h;
ctx.beginPath();
ctx.moveTo(x, y);
var tick = this.layout.yticks[i];
if (typeof(tick) == "function") return;
var x = this.area.x;
- var y = this.area.y + tick[0] * this.area.h;
+ if (tick[0] == 1) {
+ x = this.area.x + this.area.w - labelStyle.width;
+ }
+ var y = this.area.y + tick[1] * this.area.h;
context.beginPath();
context.moveTo(x, y);
context.lineTo(x - this.options.axisTickSize, y);
context.closePath();
context.stroke();
- var label = makeDiv(tick[1]);
+ var label = makeDiv(tick[2]);
var top = (y - this.options.axisLabelFontSize / 2);
if (top < 0) top = 0;
} else {
label.style.top = top + "px";
}
- label.style.left = "0px";
- label.style.textAlign = "right";
+ if (tick[0] == 0) {
+ label.style.left = "0px";
+ label.style.textAlign = "right";
+ } else if (tick[0] == 1) {
+ label.style.left = (this.area.x + this.area.w +
+ this.options.axisTickSize) + "px";
+ label.style.textAlign = "left";
+ }
label.style.width = this.options.yAxisLabelWidth + "px";
this.container.appendChild(label);
this.ylabels.push(label);
var axes = out[0];
var seriesToAxisMap = out[1];
this.displayedYRange_ = axes[0].valueRange;
- // TODO(danvk): remove yAxis, yTicks
- this.layout_.updateOptions( { yAxis: axes[0].valueRange,
- yTicks: axes[0].ticks,
- yAxes: axes,
+ this.layout_.updateOptions( { yAxes: axes,
seriesToAxisMap: seriesToAxisMap
- } );
+ } );
this.addXTicks_();
/**
* Determine all y-axes.
- * Inputs: mapping from seriesName -> [low, high] for that series,
- * (implicit) per-series axis attributes.
* Returns [ axes, seriesToAxisMap ]
- * axes = [ { valueRange: [low, high], otherOptions: ..., ticks: [...] } ]
+ * axes = [ { options } ]
* seriesToAxisMap = { seriesName: 0, seriesName2: 1, ... }
* indices are into the axes array.
*/
Dygraph.update(this.renderOptions_, attrs);
this.labelsFromCSV_ = (this.attr_("labels") == null);
+ this.computeYaxes_();
// TODO(danvk): this doesn't match the constructor logic
this.layout_.updateOptions({ 'errorBars': this.attr_("errorBars") });