From ffe8b2c6bb88d87479ed88c4afc43e1a41c8bd0c Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Fri, 22 May 2015 17:07:51 -0400 Subject: [PATCH 1/2] no binning for <20 discrete values, fixed % labels --- scout-ui/src/minicharts/d3fns/few.js | 3 +- scout-ui/src/minicharts/d3fns/many.js | 15 ++-- scout-ui/src/minicharts/d3fns/number.js | 93 ++++++++++++++-------- scout-ui/src/minicharts/d3fns/shared.js | 4 + scout-ui/src/minicharts/d3fns/string.js | 12 +++ scout-ui/src/minicharts/d3fns/tooltip.jade | 2 +- 6 files changed, 88 insertions(+), 41 deletions(-) diff --git a/scout-ui/src/minicharts/d3fns/few.js b/scout-ui/src/minicharts/d3fns/few.js index de2421935b4..ae9368335bb 100644 --- a/scout-ui/src/minicharts/d3fns/few.js +++ b/scout-ui/src/minicharts/d3fns/few.js @@ -1,6 +1,7 @@ var d3 = require('d3'); var _ = require('lodash'); var tooltipHtml = require('./tooltip.jade'); +var shared = require('./shared'); var debug = require('debug')('scout-ui:minicharts:few'); require('d3-tip')(d3); @@ -25,7 +26,7 @@ module.exports = function(data, g, width, height, options) { } return d.tooltip || tooltipHtml({ label: d.label, - value: Math.round(d.value / sumValues * 100) + value: shared.percentFormat(d.value / sumValues) }); }) .direction('n') diff --git a/scout-ui/src/minicharts/d3fns/many.js b/scout-ui/src/minicharts/d3fns/many.js index 65d380275d5..d5ea952f236 100644 --- a/scout-ui/src/minicharts/d3fns/many.js +++ b/scout-ui/src/minicharts/d3fns/many.js @@ -1,6 +1,7 @@ var d3 = require('d3'); var _ = require('lodash'); var tooltipHtml = require('./tooltip.jade'); +var shared = require('./shared'); var debug = require('debug')('scout-ui:minicharts:many'); require('d3-tip')(d3); @@ -18,13 +19,13 @@ module.exports = function(data, g, width, height, options) { .rangeBands([0, width], 0.3, 0.0); var values = _.pluck(data, 'value'); + var maxValue = d3.max(values); + var sumValues = d3.sum(values); var y = d3.scale.linear() - .domain([0, d3.max(values)]) + .domain([0, maxValue]) .range([height, 0]); - var sumY = d3.sum(values); - // set up tooltips var tip = d3.tip() .attr('class', 'd3-tip') @@ -34,7 +35,7 @@ module.exports = function(data, g, width, height, options) { } return d.tooltip || tooltipHtml({ label: d.label, - value: d.value + value: shared.percentFormat(d.value / sumValues) }); }) .direction('n') @@ -46,8 +47,6 @@ module.exports = function(data, g, width, height, options) { if (options.scale) { var maxVal = d3.max(y.domain()); - var format = d3.format('%.1f'); - var legendValues = [format(maxVal), format(maxVal / 2)]; // @todo use a scale and wrap both text and line in g element var legend = g.append('g') @@ -60,7 +59,7 @@ module.exports = function(data, g, width, height, options) { .attr('y', 0) .attr('dy', '0.3em') .attr('text-anchor', 'end') - .text(d3.max(y.domain()) + '%'); + .text(shared.percentFormat(maxValue / sumValues)); legend.append('text') .attr('class', 'legend') @@ -69,7 +68,7 @@ module.exports = function(data, g, width, height, options) { .attr('y', height / 2) .attr('dy', '0.3em') .attr('text-anchor', 'end') - .text(d3.max(y.domain()) / 2 + '%'); + .text(shared.percentFormat(maxValue / sumValues / 2)); legend.append('text') .attr('class', 'legend') diff --git a/scout-ui/src/minicharts/d3fns/number.js b/scout-ui/src/minicharts/d3fns/number.js index 00492bd787f..d061c0ebf03 100644 --- a/scout-ui/src/minicharts/d3fns/number.js +++ b/scout-ui/src/minicharts/d3fns/number.js @@ -13,37 +13,61 @@ module.exports = function(opts) { var height = opts.height - margin.top - margin.bottom; var el = opts.el; - // use the linear scale just to get nice binning values - var x = d3.scale.linear() - .domain(d3.extent(values)) - .range([0, width]); + if (opts.data.unique < 20) { + var data = _(values) + .groupBy(function(d) { + return d; + }) + .map(function(v, k) { + v.label = k; + v.value = v.length; + return v; + }) + .value(); - // Generate a histogram using approx. twenty uniformly-spaced bins - var ticks = x.ticks(20); + // var sumY = d3.sum(_.pluck(data, 'value')); + // debug(data, sumY); + // in a second pass, add tooltips + // _.each(data, function(d) { + // d.percent = Math.round(d.value / sumY * 100); + // d.tooltip = tooltipHtml({ + // label: d.label, + // value: Math.round(d.percent) + // }); + // }); - var hist = d3.layout.histogram() - .bins(ticks); + } else { + // use the linear scale just to get nice binning values + var x = d3.scale.linear() + .domain(d3.extent(values)) + .range([0, width]); - var data = hist(values); - var sumY = d3.sum(_.pluck(data, 'y')); + // Generate a histogram using approx. twenty uniformly-spaced bins + var ticks = x.ticks(20); + var hist = d3.layout.histogram() + .bins(ticks); - _.each(data, function(d, i) { - var label; - if (i === 0) { - label = '< ' + (d.x + d.dx); - } else if (i === data.length - 1) { - label = '≥ ' + d.x; - } else { - label = d.x + '-' + (d.x + d.dx); - } - // remapping keys to conform with all other types - d.value = d.y; - d.label = label; - d.tooltip = tooltipHtml({ - label: label, - value: Math.round(d.y / sumY * 100) + var data = hist(values); + var sumY = d3.sum(_.pluck(data, 'y')); + + _.each(data, function(d, i) { + var label; + if (i === 0) { + label = '< ' + (d.x + d.dx); + } else if (i === data.length - 1) { + label = '≥ ' + d.x; + } else { + label = d.x + '-' + (d.x + d.dx); + } + // remapping keys to conform with all other types + d.value = d.y; + d.label = label; +// d.tooltip = tooltipHtml({ +// label: label, +// value: Math.round(d.value / sumY * 100) +// }); }); - }); + } // clear element first d3.select(el).selectAll('*').remove(); @@ -52,16 +76,23 @@ module.exports = function(opts) { .append('g') .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - many(data, g, width, height - 10, { - scale: true, - bgbars: false, - labels: { + var labels; + if (opts.data.unique < 20) { + labels = true; + } else { + labels = { text: function(d, i) { if (i === 0) return 'min: ' + d3.min(values); if (i === data.length - 1) return 'max: ' + d3.max(values); return ''; } - } + }; + } + + many(data, g, width, height - 10, { + scale: true, + bgbars: false, + labels: labels }); }; diff --git a/scout-ui/src/minicharts/d3fns/shared.js b/scout-ui/src/minicharts/d3fns/shared.js index c2161dcfebb..a247f24b3e7 100644 --- a/scout-ui/src/minicharts/d3fns/shared.js +++ b/scout-ui/src/minicharts/d3fns/shared.js @@ -1,3 +1,5 @@ +var d3 = require('d3'); + module.exports = { margin: { @@ -7,4 +9,6 @@ module.exports = { left: 40 }, + percentFormat: d3.format('%.1f') + }; diff --git a/scout-ui/src/minicharts/d3fns/string.js b/scout-ui/src/minicharts/d3fns/string.js index 56b349abf97..3c32a52514a 100644 --- a/scout-ui/src/minicharts/d3fns/string.js +++ b/scout-ui/src/minicharts/d3fns/string.js @@ -27,6 +27,18 @@ module.exports = function(opts) { .sortByOrder('value', [false]) // descending on value .value(); +// var sumY = d3.sum(_.pluck(data, 'value')); + + // in a second pass, add tooltips + // _.each(data, function(d) { + // d.percent = Math.round(d.value / sumY * 100); + // d.tooltip = tooltipHtml({ + // label: d.label, + // value: Math.round(d.percent) + // }); + // }); + + // clear element first d3.select(el).selectAll('*').remove(); diff --git a/scout-ui/src/minicharts/d3fns/tooltip.jade b/scout-ui/src/minicharts/d3fns/tooltip.jade index 093970460f9..1d6c7758cdc 100644 --- a/scout-ui/src/minicharts/d3fns/tooltip.jade +++ b/scout-ui/src/minicharts/d3fns/tooltip.jade @@ -1,3 +1,3 @@ .tooltip-wrapper .tooltip-label!= label - .tooltip-value #{value}% + .tooltip-value #{value} From fcd15b72daef4ceb9366b8115769a443fd6f07aa Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Fri, 22 May 2015 17:11:06 -0400 Subject: [PATCH 2/2] cleanup and remove dead code. --- scout-ui/src/minicharts/d3fns/number.js | 15 --------------- scout-ui/src/minicharts/d3fns/string.js | 12 ------------ 2 files changed, 27 deletions(-) diff --git a/scout-ui/src/minicharts/d3fns/number.js b/scout-ui/src/minicharts/d3fns/number.js index d061c0ebf03..47c30292cc9 100644 --- a/scout-ui/src/minicharts/d3fns/number.js +++ b/scout-ui/src/minicharts/d3fns/number.js @@ -25,17 +25,6 @@ module.exports = function(opts) { }) .value(); - // var sumY = d3.sum(_.pluck(data, 'value')); - // debug(data, sumY); - // in a second pass, add tooltips - // _.each(data, function(d) { - // d.percent = Math.round(d.value / sumY * 100); - // d.tooltip = tooltipHtml({ - // label: d.label, - // value: Math.round(d.percent) - // }); - // }); - } else { // use the linear scale just to get nice binning values var x = d3.scale.linear() @@ -62,10 +51,6 @@ module.exports = function(opts) { // remapping keys to conform with all other types d.value = d.y; d.label = label; -// d.tooltip = tooltipHtml({ -// label: label, -// value: Math.round(d.value / sumY * 100) -// }); }); } diff --git a/scout-ui/src/minicharts/d3fns/string.js b/scout-ui/src/minicharts/d3fns/string.js index 3c32a52514a..56b349abf97 100644 --- a/scout-ui/src/minicharts/d3fns/string.js +++ b/scout-ui/src/minicharts/d3fns/string.js @@ -27,18 +27,6 @@ module.exports = function(opts) { .sortByOrder('value', [false]) // descending on value .value(); -// var sumY = d3.sum(_.pluck(data, 'value')); - - // in a second pass, add tooltips - // _.each(data, function(d) { - // d.percent = Math.round(d.value / sumY * 100); - // d.tooltip = tooltipHtml({ - // label: d.label, - // value: Math.round(d.percent) - // }); - // }); - - // clear element first d3.select(el).selectAll('*').remove();