Skip to content

Commit f113bfc

Browse files
committed
Merge pull request #28 from 10gen/INT-152-rounding
fixes INT-152 rounding
2 parents fd26e63 + d7ac688 commit f113bfc

File tree

5 files changed

+107
-46
lines changed

5 files changed

+107
-46
lines changed

scout-ui/src/minicharts/d3fns/few.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ module.exports = function(data, g, width, height, options) {
1111
var barHeight = 25;
1212
var values = _.pluck(data, 'value');
1313
var sumValues = d3.sum(values);
14+
var maxValue = d3.max(values);
15+
var percentFormat = shared.friendlyPercentFormat(maxValue / sumValues * 100);
1416

15-
// data.x is still the label, and data.y the length of the bar
1617
var x = d3.scale.linear()
1718
.domain([0, sumValues])
1819
.range([0, width]);
@@ -26,7 +27,7 @@ module.exports = function(data, g, width, height, options) {
2627
}
2728
return d.tooltip || tooltipHtml({
2829
label: d.label,
29-
value: shared.percentFormat(d.value / sumValues)
30+
value: percentFormat(d.value / sumValues * 100, false)
3031
});
3132
})
3233
.direction('n')

scout-ui/src/minicharts/d3fns/many.js

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ module.exports = function(data, g, width, height, options) {
2121
var values = _.pluck(data, 'value');
2222
var maxValue = d3.max(values);
2323
var sumValues = d3.sum(values);
24+
var percentFormat = shared.friendlyPercentFormat(maxValue / sumValues * 100);
2425

2526
var y = d3.scale.linear()
2627
.domain([0, maxValue])
@@ -35,7 +36,7 @@ module.exports = function(data, g, width, height, options) {
3536
}
3637
return d.tooltip || tooltipHtml({
3738
label: d.label,
38-
value: shared.percentFormat(d.value / sumValues)
39+
value: percentFormat(d.value / sumValues * 100, false)
3940
});
4041
})
4142
.direction('n')
@@ -46,62 +47,48 @@ module.exports = function(data, g, width, height, options) {
4647
g.call(tip);
4748

4849
if (options.scale) {
49-
var maxVal = d3.max(y.domain());
50+
var triples = function(v) {
51+
return [v, v / 2, 0];
52+
};
53+
54+
var scaleLabels = _.map(triples(maxValue / sumValues * 100), function(x) {
55+
return percentFormat(x, true);
56+
});
57+
var labelScale = d3.scale.ordinal()
58+
.domain(scaleLabels)
59+
.rangePoints([0, height]);
5060

5161
// @todo use a scale and wrap both text and line in g element
52-
var legend = g.append('g')
62+
var legend = g.selectAll('.legend')
63+
.data(scaleLabels)
64+
.enter().append('g')
5365
.attr('class', 'legend');
5466

55-
legend.append('text')
56-
.attr('class', 'legend')
57-
.attr('x', 0)
58-
.attr('dx', '-1em')
59-
.attr('y', 0)
60-
.attr('dy', '0.3em')
61-
.attr('text-anchor', 'end')
62-
.text(shared.percentFormat(maxValue / sumValues));
63-
64-
legend.append('text')
65-
.attr('class', 'legend')
66-
.attr('x', 0)
67-
.attr('dx', '-1em')
68-
.attr('y', height / 2)
69-
.attr('dy', '0.3em')
70-
.attr('text-anchor', 'end')
71-
.text(shared.percentFormat(maxValue / sumValues / 2));
72-
73-
legend.append('text')
74-
.attr('class', 'legend')
67+
legend
68+
.append('text')
7569
.attr('x', 0)
7670
.attr('dx', '-1em')
77-
.attr('y', height)
71+
.attr('y', function(d) {
72+
return labelScale(d);
73+
})
7874
.attr('dy', '0.3em')
7975
.attr('text-anchor', 'end')
80-
.text('0%');
76+
.text(function(d) {
77+
return d;
78+
});
8179

8280
legend.append('line')
8381
.attr('class', 'bg legend')
8482
.attr('x1', -5)
8583
.attr('x2', width)
86-
.attr('y1', 0)
87-
.attr('y2', 0);
88-
89-
legend.append('line')
90-
.attr('class', 'bg legend')
91-
.attr('x1', -5)
92-
.attr('x2', width)
93-
.attr('y1', height / 2)
94-
.attr('y2', height / 2);
95-
96-
legend.append('line')
97-
.attr('class', 'bg legend')
98-
.attr('x1', -5)
99-
.attr('x2', width)
100-
.attr('y1', height)
101-
.attr('y2', height);
84+
.attr('y1', function(d) {
85+
return labelScale(d);
86+
})
87+
.attr('y2', function(d) {
88+
return labelScale(d);
89+
});
10290
}
10391

104-
10592
var bar = g.selectAll('.bar')
10693
.data(data)
10794
.enter().append('g')

scout-ui/src/minicharts/d3fns/number.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ var d3 = require('d3');
22
var _ = require('lodash');
33
var many = require('./many');
44
var shared = require('./shared');
5-
var tooltipHtml = require('./tooltip.jade');
65
var debug = require('debug')('scout-ui:minicharts:number');
76

87
module.exports = function(opts) {

scout-ui/src/minicharts/d3fns/shared.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
var d3 = require('d3');
2+
var debug = require('debug')('scout-ui:minicharts:shared');
3+
4+
5+
// source: http://stackoverflow.com/questions/9539513/is-there-a-reliable-way-in-javascript-to-obtain-the-number-of-decimal-places-of
6+
function decimalPlaces(number) {
7+
return ((+number).toFixed(20)).replace(/^-?\d*\.?|0+$/g, '').length;
8+
}
29

310
module.exports = {
411

@@ -9,6 +16,22 @@ module.exports = {
916
left: 40
1017
},
1118

12-
percentFormat: d3.format('%.1f')
19+
friendlyPercentFormat: function(vmax) {
20+
var prec1Format = d3.format('.1r');
21+
var intFormat = d3.format('.0f');
22+
var format = (vmax > 1) ? intFormat : prec1Format;
23+
var maxFormatted = format(vmax);
24+
var maxDecimals = decimalPlaces(maxFormatted);
1325

26+
return function(v, incPrec) {
27+
if (v === vmax) {
28+
return maxFormatted + '%';
29+
}
30+
if (v > 1 && !incPrec) { // v > vmax || maxFormatted % 2 === 0
31+
return d3.round(v, maxDecimals) + '%';
32+
}
33+
// adjust for corrections, if increased precision required
34+
return d3.round(v / vmax * maxFormatted, maxDecimals + 1) + '%';
35+
};
36+
}
1437
};

scout-ui/test/minicharts.test.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
var shared = require('../src/minicharts/d3fns/shared');
2+
var _ = require('lodash');
3+
var assert = require('assert');
4+
5+
function triples(v) {
6+
return [v, v / 2, 0];
7+
}
8+
9+
describe('shared components', function() {
10+
it('should return percentages for top, middle and bottom scale correctly', function() {
11+
assert.deepEqual(_.map(triples(209), function(x) {
12+
return shared.friendlyPercentFormat(209)(x, true);
13+
}), ['209%', '104.5%', '0%']);
14+
assert.deepEqual(_.map(triples(200), function(x) {
15+
return shared.friendlyPercentFormat(200)(x, true);
16+
}), ['200%', '100%', '0%']);
17+
assert.deepEqual(_.map(triples(100), function(x) {
18+
return shared.friendlyPercentFormat(100)(x, true);
19+
}), ['100%', '50%', '0%']);
20+
assert.deepEqual(_.map(triples(99.5), function(x) {
21+
return shared.friendlyPercentFormat(99.5)(x, true);
22+
}), ['100%', '50%', '0%']);
23+
assert.deepEqual(_.map(triples(99.0), function(x) {
24+
return shared.friendlyPercentFormat(99.0)(x, true);
25+
}), ['99%', '49.5%', '0%']);
26+
assert.deepEqual(_.map(triples(99.00001), function(x) {
27+
return shared.friendlyPercentFormat(99.00001)(x, true);
28+
}), ['99%', '49.5%', '0%']);
29+
assert.deepEqual(_.map(triples(49.936), function(x) {
30+
return shared.friendlyPercentFormat(49.936)(x, true);
31+
}), ['50%', '25%', '0%']);
32+
assert.deepEqual(_.map(triples(1.1), function(x) {
33+
return shared.friendlyPercentFormat(1.1)(x, true);
34+
}), ['1%', '0.5%', '0%']);
35+
assert.deepEqual(_.map(triples(0.9), function(x) {
36+
return shared.friendlyPercentFormat(0.9)(x, true);
37+
}), ['0.9%', '0.45%', '0%']);
38+
assert.deepEqual(_.map(triples(0.4), function(x) {
39+
return shared.friendlyPercentFormat(0.4)(x, true);
40+
}), ['0.4%', '0.2%', '0%']);
41+
assert.deepEqual(_.map(triples(0.003), function(x) {
42+
return shared.friendlyPercentFormat(0.003)(x, true);
43+
}), ['0.003%', '0.0015%', '0%']);
44+
assert.deepEqual(_.map(triples(0), function(x) {
45+
return shared.friendlyPercentFormat(0)(x, true);
46+
}), ['0%', '0%', '0%']);
47+
assert.deepEqual(_.map(triples(-1.5), function(x) {
48+
return shared.friendlyPercentFormat(-1.5)(x, true);
49+
}), ['-2%', '-1%', '0%']);
50+
});
51+
});

0 commit comments

Comments
 (0)