+ this._renderAxis();
+ this._renderAnnotations();
+};
+
+
+DygraphCanvasRenderer.prototype._renderAxis = function() {
+ if (!this.options.drawXAxis && !this.options.drawYAxis)
+ return;
+
+ // Round pixels to half-integer boundaries for crisper drawing.
+ function halfUp(x){return Math.round(x)+0.5};
+ function halfDown(y){return Math.round(y)-0.5};
+
+ var context = this.element.getContext("2d");
+
+ var labelStyle = {
+ "position": "absolute",
+ "fontSize": this.options.axisLabelFontSize + "px",
+ "zIndex": 10,
+ "color": this.options.axisLabelColor,
+ "width": this.options.axisLabelWidth + "px",
+ "overflow": "hidden"
+ };
+ var makeDiv = function(txt) {
+ var div = document.createElement("div");
+ for (var name in labelStyle) {
+ if (labelStyle.hasOwnProperty(name)) {
+ div.style[name] = labelStyle[name];
+ }
+ }
+ div.appendChild(document.createTextNode(txt));
+ return div;
+ };
+
+ // axis lines
+ context.save();
+ context.strokeStyle = this.options.axisLineColor;
+ context.lineWidth = this.options.axisLineWidth;
+
+ if (this.options.drawYAxis) {
+ if (this.layout.yticks && this.layout.yticks.length > 0) {
+ for (var i = 0; i < this.layout.yticks.length; i++) {
+ var tick = this.layout.yticks[i];
+ if (typeof(tick) == "function") return;
+ var x = this.area.x;
+ var sgn = 1;
+ if (tick[0] == 1) { // right-side y-axis
+ x = this.area.x + this.area.w;
+ sgn = -1;
+ }
+ var y = this.area.y + tick[1] * this.area.h;
+ context.beginPath();
+ context.moveTo(halfUp(x), halfDown(y));
+ context.lineTo(halfUp(x - sgn * this.options.axisTickSize), halfDown(y));
+ context.closePath();
+ context.stroke();
+
+ var label = makeDiv(tick[2]);
+ var top = (y - this.options.axisLabelFontSize / 2);
+ if (top < 0) top = 0;
+
+ if (top + this.options.axisLabelFontSize + 3 > this.height) {
+ label.style.bottom = "0px";
+ } else {
+ label.style.top = top + "px";
+ }
+ 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);
+ }
+
+ // The lowest tick on the y-axis often overlaps with the leftmost
+ // tick on the x-axis. Shift the bottom tick up a little bit to
+ // compensate if necessary.
+ var bottomTick = this.ylabels[0];
+ var fontSize = this.options.axisLabelFontSize;
+ var bottom = parseInt(bottomTick.style.top) + fontSize;
+ if (bottom > this.height - fontSize) {
+ bottomTick.style.top = (parseInt(bottomTick.style.top) -
+ fontSize / 2) + "px";
+ }
+ }
+
+ // draw a vertical line on the left to separate the chart from the labels.
+ context.beginPath();
+ context.moveTo(halfUp(this.area.x), halfDown(this.area.y));
+ context.lineTo(halfUp(this.area.x), halfDown(this.area.y + this.area.h));
+ context.closePath();
+ context.stroke();
+
+ // if there's a secondary y-axis, draw a vertical line for that, too.
+ if (this.dygraph_.numAxes() == 2) {
+ context.beginPath();
+ context.moveTo(halfDown(this.area.x + this.area.w), halfDown(this.area.y));
+ context.lineTo(halfDown(this.area.x + this.area.w), halfDown(this.area.y + this.area.h));
+ context.closePath();
+ context.stroke();
+ }
+ }
+
+ if (this.options.drawXAxis) {
+ if (this.layout.xticks) {
+ for (var i = 0; i < this.layout.xticks.length; i++) {
+ var tick = this.layout.xticks[i];
+ if (typeof(dataset) == "function") return;
+
+ var x = this.area.x + tick[0] * this.area.w;
+ var y = this.area.y + this.area.h;
+ context.beginPath();
+ context.moveTo(halfUp(x), halfDown(y));
+ context.lineTo(halfUp(x), halfDown(y + this.options.axisTickSize));
+ context.closePath();
+ context.stroke();
+
+ var label = makeDiv(tick[1]);
+ label.style.textAlign = "center";
+ label.style.bottom = "0px";
+
+ var left = (x - this.options.axisLabelWidth/2);
+ if (left + this.options.axisLabelWidth > this.width) {
+ left = this.width - this.options.xAxisLabelWidth;
+ label.style.textAlign = "right";
+ }
+ if (left < 0) {
+ left = 0;
+ label.style.textAlign = "left";
+ }
+
+ label.style.left = left + "px";
+ label.style.width = this.options.xAxisLabelWidth + "px";
+ this.container.appendChild(label);
+ this.xlabels.push(label);
+ }
+ }
+
+ context.beginPath();
+ context.moveTo(halfUp(this.area.x), halfDown(this.area.y + this.area.h));
+ context.lineTo(halfUp(this.area.x + this.area.w), halfDown(this.area.y + this.area.h));
+ context.closePath();
+ context.stroke();
+ }
+
+ context.restore();