      1 /**
      2  * @license
      3  * Copyright 2012 Dan Vanderkam (danvdk@gmail.com)
      4  * MIT-licenced: https://opensource.org/licenses/MIT
      5  */
      6 /*global Dygraph:false */
      7
      8 /*
      9
     10 Current bits of jankiness:
     11 - Direct layout access
     12 - Direct area access
     13
     14 */
     15
     16 "use strict";
     17
     18 /**
     19  * Draws the gridlines, i.e. the gray horizontal & vertical lines running the
     20  * length of the chart.
     21  *
     22  * @constructor
     23  */
     24 var grid = function() {
     25 };
     26
     27 grid.prototype.toString = function() {
     28   return "Gridline Plugin";
     29 };
     30
     31 grid.prototype.activate = function(g) {
     32   return {
     33     willDrawChart: this.willDrawChart
     34   };
     35 };
     36
     37 grid.prototype.willDrawChart = function(e) {
     38   // Draw the new X/Y grid. Lines appear crisper when pixels are rounded to
     39   // half-integers. This prevents them from drawing in two rows/cols.
     40   var g = e.dygraph;
     41   var ctx = e.drawingContext;
     42   var layout = g.layout_;
     43   var area = e.dygraph.plotter_.area;
     44
     45   function halfUp(x)  { return Math.round(x) + 0.5; }
     46   function halfDown(y){ return Math.round(y) - 0.5; }
     47
     48   var x, y, i, ticks;
     49   if (g.getOptionForAxis('drawGrid', 'y')) {
     50     var axes = ["y", "y2"];
     51     var strokeStyles = [], lineWidths = [], drawGrid = [], stroking = [], strokePattern = [];
     52     for (var i = 0; i < axes.length; i++) {
     53       drawGrid[i] = g.getOptionForAxis('drawGrid', axes[i]);
     54       if (drawGrid[i]) {
     55         strokeStyles[i] = g.getOptionForAxis('gridLineColor', axes[i]);
     56         lineWidths[i] = g.getOptionForAxis('gridLineWidth', axes[i]);
     57         strokePattern[i] = g.getOptionForAxis('gridLinePattern', axes[i]);
     58         stroking[i] = strokePattern[i] && (strokePattern[i].length >= 2);
     59       }
     60     }
     61     ticks = layout.yticks;
     62     ctx.save();
     63     // draw grids for the different y axes
     64     ticks.forEach(tick => {
     65       if (!tick.has_tick) return;
     66       var axis = tick.axis;
     67       if (drawGrid[axis]) {
     68         ctx.save();
     69         if (stroking[axis]) {
     70           if (ctx.setLineDash) ctx.setLineDash(strokePattern[axis]);
     71         }
     72         ctx.strokeStyle = strokeStyles[axis];
     73         ctx.lineWidth = lineWidths[axis];
     74
     75         x = halfUp(area.x);
     76         y = halfDown(area.y + tick.pos * area.h);
     77         ctx.beginPath();
     78         ctx.moveTo(x, y);
     79         ctx.lineTo(x + area.w, y);
     80         ctx.stroke();
     81
     82         ctx.restore();
     83       }
     84     });
     85     ctx.restore();
     86   }
     87
     88   // draw grid for x axis
     89   if (g.getOptionForAxis('drawGrid', 'x')) {
     90     ticks = layout.xticks;
     91     ctx.save();
     92     var strokePattern = g.getOptionForAxis('gridLinePattern', 'x');
     93     var stroking = strokePattern && (strokePattern.length >= 2);
     94     if (stroking) {
     95       if (ctx.setLineDash) ctx.setLineDash(strokePattern);
     96     }
     97     ctx.strokeStyle = g.getOptionForAxis('gridLineColor', 'x');
     98     ctx.lineWidth = g.getOptionForAxis('gridLineWidth', 'x');
     99     ticks.forEach(tick => {
    100       if (!tick.has_tick) return;
    101       x = halfUp(area.x + tick.pos * area.w);
    102       y = halfDown(area.y + area.h);
    103       ctx.beginPath();
    104       ctx.moveTo(x, y);
    105       ctx.lineTo(x, area.y);
    106       ctx.stroke();
    107     });
    108     if (stroking) {
    109       if (ctx.setLineDash) ctx.setLineDash([]);
    110     }
    111     ctx.restore();
    112   }
    113 };
    114
    115 grid.prototype.destroy = function() {
    116 };
    117
    118 export default grid;
    119