File: candlestickgroup.js

package info (click to toggle)
r-cran-dygraphs 1.1.1.6%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 1,232 kB
  • sloc: javascript: 10,787; sh: 19; makefile: 15
file content (105 lines) | stat: -rw-r--r-- 3,121 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
 * The Candle chart plotter is adapted from code written by
 * Zhenlei Cai (jpenguin@gmail.com)
 * https://github.com/danvk/dygraphs/pull/141/files
 * 
 * Adapted for use by dyGroup in the dygraphs R package
 * 
 */
  function candlestickgroupPlotter(e) {
    // BEGIN HEADER BLOCK
    // This first block can be copied to other plotters to capture the group 
    var g = e.dygraph;
    
    var group;
    var groupIdx = [];
    var sets = [];
    var allSets = e.allSeriesPoints;
    var minIdx = Infinity;
    var setName = e.setName;
    var setNames = g.getLabels().slice(1);
    
    var currGroup = g.attr_("group", setName);
    
    for (var setIdx = 0; setIdx < allSets.length; setIdx++) {
      // get the name and group of the current setIdx
      setName = setNames[setIdx];
      group = g.attr_("group", setName);
  
      if (group === currGroup) {
        //save the indv index and the points
        groupIdx.push(setIdx);
        sets.push(allSets[setIdx]);
        
        // capturing the min indx helps to ensure we don't render the plotter
        // multiple times
        if (setIdx < minIdx) minIdx = setIdx;
      }
    }
    
    // We'll employ the plotter only on the first of the group
    if (e.seriesIndex !== minIdx) return;
    // END HEADER BLOCK
   
    // If the group doesn't have four series then revert to prior 
    if (groupIdx.length < 4) return;
  
    function getPrices(sets) {
      var prices = [];
      var price;
      for (var p = 0 ; p < sets[0].length; p++) {
        price = {
          open : sets[0][p].yval,
          high : sets[1][p].yval,
          low : sets[2][p].yval,
          close : sets[3][p].yval,
          openY : sets[0][p].y,
          highY : sets[1][p].y,
          lowY : sets[2][p].y,
          closeY : sets[3][p].y
        };
        prices.push(price);
      }
      return prices;
    }

    var prices = getPrices(sets);
    var area = e.plotArea;
    var ctx = e.drawingContext;
    ctx.strokeStyle = '#202020';
    ctx.lineWidth = 0.6;

    var minBarWidth = 2;
    var numBars = prices.length + 1; // To compensate the probably removed first "incomplete" bar
    var barWidth = Math.round((area.w / numBars) / 2);
    if (barWidth % 2 !== 0) {
      barWidth++;
    }
    barWidth = Math.max(barWidth, minBarWidth);

    var price;
    for (var p = 0 ; p < prices.length; p++) {
      ctx.beginPath();

      price = prices[p];
      var topY = area.h * price.highY + area.y;
      var bottomY = area.h * price.lowY + area.y;
      var centerX = Math.floor(area.x + sets[0][p].x * area.w) + 0.5; // crisper rendering
      ctx.moveTo(centerX, topY);
      ctx.lineTo(centerX, bottomY);
      ctx.closePath();
      ctx.stroke();
      var bodyY;
      if (price.open > price.close) {
        ctx.fillStyle ='#d9534f';
        bodyY = area.h * price.openY + area.y;
      }
      else {
        ctx.fillStyle ='#5cb85c';
        bodyY = area.h * price.closeY  + area.y;
      }
      var bodyHeight = area.h * Math.abs(price.openY - price.closeY);
      ctx.fillRect(centerX - barWidth / 2, bodyY, barWidth,  bodyHeight);
   }
}