graceguo-supercat closed pull request #4513: Superset issue #4512: fixing histogram URL: https://github.com/apache/incubator-superset/pull/4513
This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/superset/assets/javascripts/explore/stores/controls.jsx b/superset/assets/javascripts/explore/stores/controls.jsx index a15333e29d..f7de17e97b 100644 --- a/superset/assets/javascripts/explore/stores/controls.jsx +++ b/superset/assets/javascripts/explore/stores/controls.jsx @@ -1981,5 +1981,13 @@ export const controls = { description: t('Whether to fill the objects'), default: false, }, + + normalized: { + type: 'CheckboxControl', + label: t('Normalized'), + renderTrigger: true, + description: t('Whether to normalize the histogram'), + default: false, + }, }; export default controls; diff --git a/superset/assets/javascripts/explore/stores/visTypes.js b/superset/assets/javascripts/explore/stores/visTypes.js index a41b81b339..bfdd0b72df 100644 --- a/superset/assets/javascripts/explore/stores/visTypes.js +++ b/superset/assets/javascripts/explore/stores/visTypes.js @@ -1087,6 +1087,8 @@ export const visTypes = { controlSetRows: [ ['color_scheme'], ['link_length'], + ['x_axis_label', 'y_axis_label'], + ['normalized'], ], }, ], diff --git a/superset/assets/visualizations/histogram.js b/superset/assets/visualizations/histogram.js index b5bbf09519..b4bf6fcc74 100644 --- a/superset/assets/visualizations/histogram.js +++ b/superset/assets/visualizations/histogram.js @@ -4,40 +4,54 @@ import { getColorFromScheme } from '../javascripts/modules/colors'; require('./histogram.css'); function histogram(slice, payload) { + const data = payload.data; const div = d3.select(slice.selector); - const draw = function (data, numBins) { + const numBins = Number(slice.formData.link_length) || 10; + const normalized = slice.formData.normalized; + const xAxisLabel = slice.formData.x_axis_label; + const yAxisLabel = slice.formData.y_axis_label; + + const draw = function () { // Set Margins + const left = yAxisLabel ? 70 : 50; const margin = { top: 50, right: 10, bottom: 20, - left: 50, + left, }; const navBarHeight = 36; const navBarBuffer = 10; const width = slice.width() - margin.left - margin.right; const height = slice.height() - margin.top - margin.bottom - navBarHeight - navBarBuffer; + // set number of ticks + const maxTicks = 20; + const numTicks = d3.min([maxTicks, numBins]); + // Set Histogram objects - const formatNumber = d3.format(',.0f'); - const formatTicks = d3.format(',.00f'); - const x = d3.scale.ordinal(); + const x = d3.scale.linear(); const y = d3.scale.linear(); const xAxis = d3.svg.axis() .scale(x) .orient('bottom') - .ticks(numBins) - .tickFormat(formatTicks); + .ticks(numTicks, 's'); const yAxis = d3.svg.axis() .scale(y) .orient('left') - .ticks(numBins); + .ticks(numTicks, 's'); // Calculate bins for the data - const bins = d3.layout.histogram().bins(numBins)(data); + let bins = d3.layout.histogram().bins(numBins)(data); + if (normalized) { + const total = data.length; + bins = bins.map(d => ({ ...d, y: d.y / total })); + } // Set the x-values - x.domain(bins.map(d => d.x)) - .rangeRoundBands([0, width], 0.1); + const max = d3.max(data); + const min = d3.min(data); + x.domain([min, max]) + .range([0, width], 0.1); // Set the y-values y.domain([0, d3.max(bins, d => d.y)]) .range([height, 0]); @@ -72,42 +86,13 @@ function histogram(slice, payload) { bar.enter().append('rect'); bar.exit().remove(); // Set the Height and Width for each bar - bar.attr('width', x.rangeBand()) + bar.attr('width', (x(bins[0].dx) - x(0)) - 1) .attr('x', d => x(d.x)) .attr('y', d => y(d.y)) .attr('height', d => y.range()[0] - y(d.y)) - .style('fill', d => getColorFromScheme(d.length, slice.formData.color_scheme)) + .style('fill', getColorFromScheme(1, slice.formData.color_scheme)) .order(); - // Find maximum length to position the ticks on top of the bar correctly - const maxLength = d3.max(bins, d => d.length); - function textAboveBar(d) { - return d.length / maxLength < 0.1; - } - - // Add a bar text to each bar in the histogram - svg.selectAll('.bartext') - .data(bins) - .enter() - .append('text') - .attr('dy', '.75em') - .attr('y', function (d) { - let padding = 0.0; - if (textAboveBar(d)) { - padding = 12.0; - } else { - padding = -8.0; - } - return y(d.y) - padding; - }) - .attr('x', d => x(d.x) + (x.rangeBand() / 2)) - .attr('text-anchor', 'middle') - .attr('font-weight', 'bold') - .attr('font-size', '15px') - .text(d => formatNumber(d.y)) - .attr('fill', d => textAboveBar(d) ? 'black' : 'white') - .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - // Update the x-axis svg.append('g') .attr('class', 'axis') @@ -124,11 +109,29 @@ function histogram(slice, payload) { .selectAll('g') .filter(function (d) { return d; }) .classed('minor', true); + + // add axis labels if passed + if (xAxisLabel) { + svg.append('text') + .attr('transform', + 'translate(' + ((width + margin.left) / 2) + ' ,' + + (height + margin.top + 50) + ')') + .style('text-anchor', 'middle') + .text(xAxisLabel); + } + if (yAxisLabel) { + svg.append('text') + .attr('transform', 'rotate(-90)') + .attr('y', '1em') + .attr('x', 0 - (height / 2)) + .attr('dy', '1em') + .style('text-anchor', 'middle') + .text(yAxisLabel); + } }; - const numBins = Number(slice.formData.link_length) || 10; div.selectAll('*').remove(); - draw(payload.data, numBins); + draw(); } module.exports = histogram; ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services