Merge "add filter based on begin&end time of start_date"
[releng.git] / utils / test / reporting / js / gauge.js
1 // ******************************************
2 // Gauge for reporting
3 // Each scenario has a score
4 // We use a gauge to indicate the trust level
5 // ******************************************
6 var gauge = function(container) {
7   var that = {};
8   var config = {
9     size                                                : 150,
10     clipWidth                                   : 250,
11     clipHeight                                  : 100,
12     ringInset                                   : 20,
13     ringWidth                                   : 40,
14
15     pointerWidth                                : 7,
16     pointerTailLength                   : 5,
17     pointerHeadLengthPercent    : 0.8,
18
19     minValue                                    : 0,
20     maxValue                                    : 100,
21
22     minAngle                                    : -90,
23     maxAngle                                    : 90,
24
25     transitionMs                                : 4000,
26
27     majorTicks                                  : 7,
28     labelFormat                                 : d3.format(',g'),
29     labelInset                                  : 10,
30
31     arcColorFn                                  : d3.interpolateHsl(d3.rgb('#ff0000'), d3.rgb('#00ff00'))
32   };
33
34
35 var range = undefined;
36 var r = undefined;
37 var pointerHeadLength = undefined;
38 var value = 0;
39
40 var svg = undefined;
41 var arc = undefined;
42 var scale = undefined;
43 var ticks = undefined;
44 var tickData = undefined;
45 var pointer = undefined;
46
47 var donut = d3.layout.pie();
48
49 function deg2rad(deg) {
50   return deg * Math.PI / 180;
51 }
52
53 function newAngle(d) {
54   var ratio = scale(d);
55   var newAngle = config.minAngle + (ratio * range);
56   return newAngle;
57 }
58
59 function configure() {
60   range = config.maxAngle - config.minAngle;
61   r = config.size / 2;
62   pointerHeadLength = Math.round(r * config.pointerHeadLengthPercent);
63
64   // a linear scale that maps domain values to a percent from 0..1
65   scale = d3.scale.linear()
66     .range([0,1])
67     .domain([config.minValue, config.maxValue]);
68
69   ticks = scale.ticks(config.majorTicks);
70   tickData = d3.range(config.majorTicks).map(function() {return 1/config.majorTicks;});
71
72   arc = d3.svg.arc()
73     .innerRadius(r - config.ringWidth - config.ringInset)
74     .outerRadius(r - config.ringInset)
75     .startAngle(function(d, i) {
76       var ratio = d * i;
77       return deg2rad(config.minAngle + (ratio * range));
78     })
79     .endAngle(function(d, i) {
80       var ratio = d * (i+1);
81       return deg2rad(config.minAngle + (ratio * range));
82     });
83 }
84 that.configure = configure;
85
86 function centerTranslation() {
87   return 'translate('+r +','+ r +')';
88 }
89
90 function isRendered() {
91   return (svg !== undefined);
92 }
93 that.isRendered = isRendered;
94
95 function render(newValue) {
96   svg = d3.select(container)
97     .append('svg:svg')
98       .attr('class', 'gauge')
99       .attr('width', config.clipWidth)
100       .attr('height', config.clipHeight);
101
102   var centerTx = centerTranslation();
103
104   var arcs = svg.append('g')
105       .attr('class', 'arc')
106       .attr('transform', centerTx);
107
108   arcs.selectAll('path')
109       .data(tickData)
110     .enter().append('path')
111       .attr('fill', function(d, i) {
112         return config.arcColorFn(d * i);
113       })
114       .attr('d', arc);
115
116   var lg = svg.append('g')
117       .attr('class', 'label')
118       .attr('transform', centerTx);
119   lg.selectAll('text')
120       .data(ticks)
121     .enter().append('text')
122       .attr('transform', function(d) {
123         var ratio = scale(d);
124         var newAngle = config.minAngle + (ratio * range);
125         return 'rotate(' +newAngle +') translate(0,' +(config.labelInset - r) +')';
126       })
127       .text(config.labelFormat);
128
129   var lineData = [ [config.pointerWidth / 2, 0],
130           [0, -pointerHeadLength],
131           [-(config.pointerWidth / 2), 0],
132           [0, config.pointerTailLength],
133           [config.pointerWidth / 2, 0] ];
134   var pointerLine = d3.svg.line().interpolate('monotone');
135   var pg = svg.append('g').data([lineData])
136       .attr('class', 'pointer')
137       .attr('transform', centerTx);
138
139   pointer = pg.append('path')
140     .attr('d', pointerLine/*function(d) { return pointerLine(d) +'Z';}*/ )
141     .attr('transform', 'rotate(' +config.minAngle +')');
142
143   update(newValue === undefined ? 0 : newValue);
144 }
145 that.render = render;
146
147 function update(newValue, newConfiguration) {
148   if ( newConfiguration  !== undefined) {
149     configure(newConfiguration);
150   }
151   var ratio = scale(newValue);
152   var newAngle = config.minAngle + (ratio * range);
153   pointer.transition()
154     .duration(config.transitionMs)
155     .ease('elastic')
156     .attr('transform', 'rotate(' +newAngle +')');
157 }
158 that.update = update;
159
160 configure();
161
162 render();
163
164 return that;
165 };