Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions scout-ui/src/minicharts/d3fns/few.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ module.exports = function(data, g, width, height, options) {
var barHeight = 25;
var values = _.pluck(data, 'value');
var sumValues = d3.sum(values);
var maxValue = d3.max(values);
var percentFormat = shared.friendlyPercentFormat(maxValue / sumValues * 100);

// data.x is still the label, and data.y the length of the bar
var x = d3.scale.linear()
.domain([0, sumValues])
.range([0, width]);
Expand All @@ -26,7 +27,7 @@ module.exports = function(data, g, width, height, options) {
}
return d.tooltip || tooltipHtml({
label: d.label,
value: shared.percentFormat(d.value / sumValues)
value: percentFormat(d.value / sumValues * 100, false)
});
})
.direction('n')
Expand Down
71 changes: 29 additions & 42 deletions scout-ui/src/minicharts/d3fns/many.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module.exports = function(data, g, width, height, options) {
var values = _.pluck(data, 'value');
var maxValue = d3.max(values);
var sumValues = d3.sum(values);
var percentFormat = shared.friendlyPercentFormat(maxValue / sumValues * 100);

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

if (options.scale) {
var maxVal = d3.max(y.domain());
var triples = function(v) {
return [v, v / 2, 0];
};

var scaleLabels = _.map(triples(maxValue / sumValues * 100), function(x) {
return percentFormat(x, true);
});
var labelScale = d3.scale.ordinal()
.domain(scaleLabels)
.rangePoints([0, height]);

// @todo use a scale and wrap both text and line in g element
var legend = g.append('g')
var legend = g.selectAll('.legend')
.data(scaleLabels)
.enter().append('g')
.attr('class', 'legend');

legend.append('text')
.attr('class', 'legend')
.attr('x', 0)
.attr('dx', '-1em')
.attr('y', 0)
.attr('dy', '0.3em')
.attr('text-anchor', 'end')
.text(shared.percentFormat(maxValue / sumValues));

legend.append('text')
.attr('class', 'legend')
.attr('x', 0)
.attr('dx', '-1em')
.attr('y', height / 2)
.attr('dy', '0.3em')
.attr('text-anchor', 'end')
.text(shared.percentFormat(maxValue / sumValues / 2));

legend.append('text')
.attr('class', 'legend')
legend
.append('text')
.attr('x', 0)
.attr('dx', '-1em')
.attr('y', height)
.attr('y', function(d) {
return labelScale(d);
})
.attr('dy', '0.3em')
.attr('text-anchor', 'end')
.text('0%');
.text(function(d) {
return d;
});

legend.append('line')
.attr('class', 'bg legend')
.attr('x1', -5)
.attr('x2', width)
.attr('y1', 0)
.attr('y2', 0);

legend.append('line')
.attr('class', 'bg legend')
.attr('x1', -5)
.attr('x2', width)
.attr('y1', height / 2)
.attr('y2', height / 2);

legend.append('line')
.attr('class', 'bg legend')
.attr('x1', -5)
.attr('x2', width)
.attr('y1', height)
.attr('y2', height);
.attr('y1', function(d) {
return labelScale(d);
})
.attr('y2', function(d) {
return labelScale(d);
});
}


var bar = g.selectAll('.bar')
.data(data)
.enter().append('g')
Expand Down
1 change: 0 additions & 1 deletion scout-ui/src/minicharts/d3fns/number.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ var d3 = require('d3');
var _ = require('lodash');
var many = require('./many');
var shared = require('./shared');
var tooltipHtml = require('./tooltip.jade');
var debug = require('debug')('scout-ui:minicharts:number');

module.exports = function(opts) {
Expand Down
25 changes: 24 additions & 1 deletion scout-ui/src/minicharts/d3fns/shared.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
var d3 = require('d3');
var debug = require('debug')('scout-ui:minicharts:shared');


// source: http://stackoverflow.com/questions/9539513/is-there-a-reliable-way-in-javascript-to-obtain-the-number-of-decimal-places-of
function decimalPlaces(number) {
return ((+number).toFixed(20)).replace(/^-?\d*\.?|0+$/g, '').length;
}

module.exports = {

Expand All @@ -9,6 +16,22 @@ module.exports = {
left: 40
},

percentFormat: d3.format('%.1f')
friendlyPercentFormat: function(vmax) {
var prec1Format = d3.format('.1r');
var intFormat = d3.format('.0f');
var format = (vmax > 1) ? intFormat : prec1Format;
var maxFormatted = format(vmax);
var maxDecimals = decimalPlaces(maxFormatted);

return function(v, incPrec) {
if (v === vmax) {
return maxFormatted + '%';
}
if (v > 1 && !incPrec) { // v > vmax || maxFormatted % 2 === 0
return d3.round(v, maxDecimals) + '%';
}
// adjust for corrections, if increased precision required
return d3.round(v / vmax * maxFormatted, maxDecimals + 1) + '%';
};
}
};
51 changes: 51 additions & 0 deletions scout-ui/test/minicharts.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
var shared = require('../src/minicharts/d3fns/shared');
var _ = require('lodash');
var assert = require('assert');

function triples(v) {
return [v, v / 2, 0];
}

describe('shared components', function() {
it('should return percentages for top, middle and bottom scale correctly', function() {
assert.deepEqual(_.map(triples(209), function(x) {
return shared.friendlyPercentFormat(209)(x, true);
}), ['209%', '104.5%', '0%']);
assert.deepEqual(_.map(triples(200), function(x) {
return shared.friendlyPercentFormat(200)(x, true);
}), ['200%', '100%', '0%']);
assert.deepEqual(_.map(triples(100), function(x) {
return shared.friendlyPercentFormat(100)(x, true);
}), ['100%', '50%', '0%']);
assert.deepEqual(_.map(triples(99.5), function(x) {
return shared.friendlyPercentFormat(99.5)(x, true);
}), ['100%', '50%', '0%']);
assert.deepEqual(_.map(triples(99.0), function(x) {
return shared.friendlyPercentFormat(99.0)(x, true);
}), ['99%', '49.5%', '0%']);
assert.deepEqual(_.map(triples(99.00001), function(x) {
return shared.friendlyPercentFormat(99.00001)(x, true);
}), ['99%', '49.5%', '0%']);
assert.deepEqual(_.map(triples(49.936), function(x) {
return shared.friendlyPercentFormat(49.936)(x, true);
}), ['50%', '25%', '0%']);
assert.deepEqual(_.map(triples(1.1), function(x) {
return shared.friendlyPercentFormat(1.1)(x, true);
}), ['1%', '0.5%', '0%']);
assert.deepEqual(_.map(triples(0.9), function(x) {
return shared.friendlyPercentFormat(0.9)(x, true);
}), ['0.9%', '0.45%', '0%']);
assert.deepEqual(_.map(triples(0.4), function(x) {
return shared.friendlyPercentFormat(0.4)(x, true);
}), ['0.4%', '0.2%', '0%']);
assert.deepEqual(_.map(triples(0.003), function(x) {
return shared.friendlyPercentFormat(0.003)(x, true);
}), ['0.003%', '0.0015%', '0%']);
assert.deepEqual(_.map(triples(0), function(x) {
return shared.friendlyPercentFormat(0)(x, true);
}), ['0%', '0%', '0%']);
assert.deepEqual(_.map(triples(-1.5), function(x) {
return shared.friendlyPercentFormat(-1.5)(x, true);
}), ['-2%', '-1%', '0%']);
});
});