You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@superset.apache.org by GitBox <gi...@apache.org> on 2019/01/08 17:09:41 UTC

[GitHub] kristw closed pull request #3777: nvd3 histogram implementation

kristw closed pull request #3777: nvd3 histogram implementation
URL: https://github.com/apache/incubator-superset/pull/3777
 
 
   

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/visTypes.js b/superset/assets/javascripts/explore/stores/visTypes.js
index 94115bb076..3378477e6f 100644
--- a/superset/assets/javascripts/explore/stores/visTypes.js
+++ b/superset/assets/javascripts/explore/stores/visTypes.js
@@ -678,6 +678,11 @@ export const visTypes = {
         expanded: true,
         controlSetRows: [
           ['all_columns_x'],
+          ['color_scheme'],
+          ['show_legend', 'show_bar_value'],
+          ['bar_stacked', 'reduce_x_ticks'],
+          ['y_axis_format', 'bottom_margin'],
+          ['x_axis_label', 'y_axis_label'],
           ['row_limit'],
         ],
       },
diff --git a/superset/assets/visualizations/histogram.css b/superset/assets/visualizations/histogram.css
deleted file mode 100644
index 7a59c088ec..0000000000
--- a/superset/assets/visualizations/histogram.css
+++ /dev/null
@@ -1,16 +0,0 @@
-.axis line {
-  fill: none;
-  stroke: black;
-  shape-rendering: crispEdges;
-}
-
-.axis text {
-  font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif;
-  font-size: 11px;
-}
-
-.axis path, .axis line {
-    fill: none;
-    stroke: #000;
-    shape-rendering: crispEdges;
-}
diff --git a/superset/assets/visualizations/histogram.js b/superset/assets/visualizations/histogram.js
deleted file mode 100644
index b5bbf09519..0000000000
--- a/superset/assets/visualizations/histogram.js
+++ /dev/null
@@ -1,134 +0,0 @@
-import d3 from 'd3';
-import { getColorFromScheme } from '../javascripts/modules/colors';
-
-require('./histogram.css');
-
-function histogram(slice, payload) {
-  const div = d3.select(slice.selector);
-  const draw = function (data, numBins) {
-    // Set Margins
-    const margin = {
-      top: 50,
-      right: 10,
-      bottom: 20,
-      left: 50,
-    };
-    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 Histogram objects
-    const formatNumber = d3.format(',.0f');
-    const formatTicks = d3.format(',.00f');
-    const x = d3.scale.ordinal();
-    const y = d3.scale.linear();
-    const xAxis = d3.svg.axis()
-    .scale(x)
-    .orient('bottom')
-    .ticks(numBins)
-    .tickFormat(formatTicks);
-    const yAxis = d3.svg.axis()
-    .scale(y)
-    .orient('left')
-    .ticks(numBins);
-    // Calculate bins for the data
-    const bins = d3.layout.histogram().bins(numBins)(data);
-
-    // Set the x-values
-    x.domain(bins.map(d => d.x))
-    .rangeRoundBands([0, width], 0.1);
-    // Set the y-values
-    y.domain([0, d3.max(bins, d => d.y)])
-    .range([height, 0]);
-
-    // Create the svg value with the bins
-    const svg = div.selectAll('svg')
-    .data([bins])
-    .enter()
-    .append('svg');
-
-    // Make a rectangular background fill
-    svg.append('rect')
-    .attr('width', '100%')
-    .attr('height', '100%')
-    .attr('fill', '#f6f6f6');
-
-    // Transform the svg to make space for the margins
-    const gEnter = svg
-    .append('g')
-    .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
-
-    // Add the bars and the x axis
-    gEnter.append('g').attr('class', 'bars');
-    gEnter.append('g').attr('class', 'x axis');
-
-    // Add width and height to the svg
-    svg.attr('width', slice.width())
-    .attr('height', slice.height());
-
-    // Create the bars in the svg
-    const bar = svg.select('.bars').selectAll('.bar').data(bins);
-    bar.enter().append('rect');
-    bar.exit().remove();
-    // Set the Height and Width for each bar
-    bar.attr('width', x.rangeBand())
-    .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))
-    .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')
-    .attr('transform', 'translate(' + margin.left + ',' + (height + margin.top) + ')')
-    .text('values')
-    .call(xAxis);
-
-    // Update the Y Axis and add minor lines
-    svg.append('g')
-    .attr('class', 'axis')
-    .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
-    .text('count')
-    .call(yAxis)
-    .selectAll('g')
-    .filter(function (d) { return d; })
-    .classed('minor', true);
-  };
-
-  const numBins = Number(slice.formData.link_length) || 10;
-  div.selectAll('*').remove();
-  draw(payload.data, numBins);
-}
-
-module.exports = histogram;
diff --git a/superset/assets/visualizations/main.js b/superset/assets/visualizations/main.js
index 78e81ab6d7..029b8fcf99 100644
--- a/superset/assets/visualizations/main.js
+++ b/superset/assets/visualizations/main.js
@@ -14,7 +14,7 @@ const vizMap = {
   dist_bar: require('./nvd3_vis.js'),
   filter_box: require('./filter_box.jsx'),
   heatmap: require('./heatmap.js'),
-  histogram: require('./histogram.js'),
+  histogram: require('./nvd3_vis.js'),
   horizon: require('./horizon.js'),
   iframe: require('./iframe.js'),
   line: require('./nvd3_vis.js'),
diff --git a/superset/assets/visualizations/nvd3_vis.js b/superset/assets/visualizations/nvd3_vis.js
index bbef132c94..f2b74c6e9b 100644
--- a/superset/assets/visualizations/nvd3_vis.js
+++ b/superset/assets/visualizations/nvd3_vis.js
@@ -195,6 +195,7 @@ function nvd3Vis(slice, payload) {
         break;
 
       case 'dist_bar':
+      case 'histogram':
         chart = nv.models.multiBarChart()
         .showControls(fd.show_controls)
         .reduceXTicks(reduceXTicks)
@@ -205,7 +206,7 @@ function nvd3Vis(slice, payload) {
 
         stacked = fd.bar_stacked;
         chart.stacked(stacked);
-        if (fd.order_bars) {
+        if (fd.order_bars || vizType == 'histogram') {
           data.forEach((d) => {
             d.values.sort((a, b) => tryNumify(a.x) < tryNumify(b.x) ? -1 : 1);
           });
diff --git a/superset/viz.py b/superset/viz.py
index 025e9c52b0..9fbd6f250d 100644
--- a/superset/viz.py
+++ b/superset/viz.py
@@ -1172,16 +1172,14 @@ def get_data(self, df):
         return df.to_dict(orient="records")
 
 
-class HistogramViz(BaseViz):
+class HistogramViz(NVD3Viz):
 
     """Histogram"""
 
     viz_type = "histogram"
     verbose_name = _("Histogram")
-    is_timeseries = False
 
     def query_obj(self):
-        """Returns the query object for this visualization"""
         d = super(HistogramViz, self).query_obj()
         d['row_limit'] = self.form_data.get(
             'row_limit', int(config.get('VIZ_ROW_LIMIT')))
@@ -1192,9 +1190,16 @@ def query_obj(self):
         return d
 
     def get_data(self, df):
-        """Returns the chart data"""
-        chart_data = df[df.columns[0]].values.tolist()
-        return chart_data
+        num_bins = int(self.form_data['link_length'])
+        num_column = self.form_data['all_columns_x']
+        binned_data = df[df.columns[0]].value_counts(bins=num_bins)
+        nvd3_chart_data = []
+        for x_interval, v in binned_data.iteritems():
+            nvd3_chart_data.append({
+                "x": str(round(x_interval.left)),
+                "y": v
+            })
+        return [{"key": num_column, "values": nvd3_chart_data}]
 
 
 class DistributionBarViz(DistributionPieViz):


 

----------------------------------------------------------------
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:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org