This is an automated email from the ASF dual-hosted git repository.

graceguo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 4135854  Superset issue #4512: fixing histogram (#4513)
4135854 is described below

commit 413585448e660cd5421d52e4f510d5de57e92d42
Author: Ariel Shemtov <arielshemt...@gmail.com>
AuthorDate: Fri Mar 2 13:45:46 2018 -0800

    Superset issue #4512: fixing histogram (#4513)
    
    * fixing histogram axes and colors, adding normalized and x-axis label 
options
    
    * adding y-axis label option
---
 .../assets/javascripts/explore/stores/controls.jsx |  8 ++
 .../assets/javascripts/explore/stores/visTypes.js  |  2 +
 superset/assets/visualizations/histogram.js        | 91 +++++++++++-----------
 3 files changed, 57 insertions(+), 44 deletions(-)

diff --git a/superset/assets/javascripts/explore/stores/controls.jsx 
b/superset/assets/javascripts/explore/stores/controls.jsx
index 5e2c44e..1a5b554 100644
--- a/superset/assets/javascripts/explore/stores/controls.jsx
+++ b/superset/assets/javascripts/explore/stores/controls.jsx
@@ -1985,5 +1985,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 df00bc5..a4ffe4d 100644
--- a/superset/assets/javascripts/explore/stores/visTypes.js
+++ b/superset/assets/javascripts/explore/stores/visTypes.js
@@ -1110,6 +1110,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 b5bbf09..b4bf6fc 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;

-- 
To stop receiving notification emails like this one, please contact
grace...@apache.org.

Reply via email to