superset-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From maximebeauche...@apache.org
Subject [incubator-superset] branch master updated: Heatmap improvements (#4897)
Date Mon, 30 Apr 2018 16:36:27 GMT
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin 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 3c7feb7  Heatmap improvements (#4897)
3c7feb7 is described below

commit 3c7feb770af4f7941b3c69f8a03d09c28ab4dc6d
Author: Maxime Beauchemin <maximebeauchemin@gmail.com>
AuthorDate: Mon Apr 30 09:36:24 2018 -0700

    Heatmap improvements (#4897)
    
    * allow option to normalize the color distribution
    * make bounds work client side (instantaneous)
    * make more controls instantaneous
---
 superset/assets/src/explore/controls.jsx      |  8 +++++++-
 superset/assets/src/explore/visTypes.js       | 12 ++++++------
 superset/assets/src/visualizations/heatmap.js | 14 +++++++-------
 superset/viz.py                               |  7 ++-----
 4 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/superset/assets/src/explore/controls.jsx b/superset/assets/src/explore/controls.jsx
index ae964ef..ffe264b 100644
--- a/superset/assets/src/explore/controls.jsx
+++ b/superset/assets/src/explore/controls.jsx
@@ -387,8 +387,10 @@ export const controls = {
   xscale_interval: {
     type: 'SelectControl',
     label: t('XScale Interval'),
+    renderTrigger: true,
     choices: formatSelectOptionsForRange(1, 50),
     default: '1',
+    clearable: false,
     description: t('Number of steps to take between ticks when ' +
     'displaying the X scale'),
   },
@@ -397,7 +399,9 @@ export const controls = {
     type: 'SelectControl',
     label: t('YScale Interval'),
     choices: formatSelectOptionsForRange(1, 50),
-    default: null,
+    default: '1',
+    clearable: false,
+    renderTrigger: true,
     description: t('Number of steps to take between ticks when ' +
     'displaying the Y scale'),
   },
@@ -726,6 +730,7 @@ export const controls = {
 
   bottom_margin: {
     type: 'SelectControl',
+    clearable: false,
     freeForm: true,
     label: t('Bottom Margin'),
     choices: formatSelectOptions(['auto', 50, 75, 100, 125, 150, 200]),
@@ -747,6 +752,7 @@ export const controls = {
   left_margin: {
     type: 'SelectControl',
     freeForm: true,
+    clearable: false,
     label: t('Left Margin'),
     choices: formatSelectOptions(['auto', 50, 75, 100, 125, 150, 200]),
     default: 'auto',
diff --git a/superset/assets/src/explore/visTypes.js b/superset/assets/src/explore/visTypes.js
index 3af1f7e..d05064a 100644
--- a/superset/assets/src/explore/visTypes.js
+++ b/superset/assets/src/explore/visTypes.js
@@ -1488,6 +1488,7 @@ export const visTypes = {
       },
       {
         label: t('Heatmap Options'),
+        expanded: true,
         controlSetRows: [
           ['linear_color_scheme'],
           ['xscale_interval', 'yscale_interval'],
@@ -1495,7 +1496,7 @@ export const visTypes = {
           ['left_margin', 'bottom_margin'],
           ['y_axis_bounds', 'y_axis_format'],
           ['show_legend', 'show_perc'],
-          ['show_values'],
+          ['show_values', 'normalized'],
           ['sort_x_axis', 'sort_y_axis'],
         ],
       },
@@ -1507,14 +1508,13 @@ export const visTypes = {
       all_columns_y: {
         validators: [v.nonEmpty],
       },
+      normalized: t('Whether to apply a normal distribution based on rank on the color scale'),
       y_axis_bounds: {
         label: t('Value bounds'),
-        renderTrigger: false,
-        description: (
+        renderTrigger: true,
+        description: t(
           'Hard value bounds applied for color coding. Is only relevant ' +
-          'and applied when the normalization is applied against the whole ' +
-          'heatmap.'
-        ),
+          'and applied when the normalization is applied against the whole heatmap.'),
       },
       y_axis_format: {
         label: t('Value Format'),
diff --git a/superset/assets/src/visualizations/heatmap.js b/superset/assets/src/visualizations/heatmap.js
index a8d3ccf..7d471d5 100644
--- a/superset/assets/src/visualizations/heatmap.js
+++ b/superset/assets/src/visualizations/heatmap.js
@@ -92,7 +92,7 @@ function heatmapVis(slice, payload) {
   const height = slice.height();
   const hmWidth = width - (margin.left + margin.right);
   const hmHeight = height - (margin.bottom + margin.top);
-  const fp = d3.format('.3p');
+  const fp = d3.format('.2%');
 
   const xScale = ordScale('x', null, fd.sort_x_axis);
   const yScale = ordScale('y', null, fd.sort_y_axis);
@@ -102,7 +102,9 @@ function heatmapVis(slice, payload) {
   const Y = 1;
   const heatmapDim = [xRbScale.domain().length, yRbScale.domain().length];
 
-  const color = colorScalerFactory(fd.linear_color_scheme);
+  const minBound = fd.y_axis_bounds[0] || 0;
+  const maxBound = fd.y_axis_bounds[1] || 1;
+  const colorScaler = colorScalerFactory(fd.linear_color_scheme, null, null, [minBound, maxBound]);
 
   const scale = [
     d3.scale.linear()
@@ -149,11 +151,9 @@ function heatmapVis(slice, payload) {
   }
 
   if (fd.show_legend) {
-    const legendScaler = colorScalerFactory(
-      fd.linear_color_scheme, null, null, payload.data.extents);
     const colorLegend = d3.legend.color()
     .labelFormat(valueFormatter)
-    .scale(legendScaler)
+    .scale(colorScaler)
     .shapePadding(0)
     .cells(50)
     .shapeWidth(10)
@@ -183,7 +183,7 @@ function heatmapVis(slice, payload) {
         s += '<div><b>' + fd.all_columns_y + ': </b>' + obj.y + '<div>';
         s += '<div><b>' + fd.metric + ': </b>' + valueFormatter(obj.v)
+ '<div>';
         if (fd.show_perc) {
-          s += '<div><b>%: </b>' + fp(obj.perc) + '<div>';
+          s += '<div><b>%: </b>' + fp(fd.normalized ? obj.rank : obj.perc)
+ '<div>';
         }
         tip.style('display', null);
       } else {
@@ -246,7 +246,7 @@ function heatmapVis(slice, payload) {
     const image = context.createImageData(heatmapDim[0], heatmapDim[1]);
     const pixs = {};
     data.forEach((d) => {
-      const c = d3.rgb(color(d.perc));
+      const c = d3.rgb(colorScaler(fd.normalized ? d.rank : d.perc));
       const x = xScale(d.x);
       const y = yScale(d.y);
       pixs[x + (y * xScale.domain().length)] = c;
diff --git a/superset/viz.py b/superset/viz.py
index 64064b3..de14f1a 100644
--- a/superset/viz.py
+++ b/superset/viz.py
@@ -1804,11 +1804,6 @@ class HeatmapViz(BaseViz):
         overall = False
         max_ = df.v.max()
         min_ = df.v.min()
-        bounds = fd.get('y_axis_bounds')
-        if bounds and bounds[0] is not None:
-            min_ = bounds[0]
-        if bounds and bounds[1] is not None:
-            max_ = bounds[1]
         if norm == 'heatmap':
             overall = True
         else:
@@ -1820,8 +1815,10 @@ class HeatmapViz(BaseViz):
                     gb.apply(
                         lambda x: (x.v - x.v.min()) / (x.v.max() - x.v.min()))
                 )
+                df['rank'] = gb.apply(lambda x: x.v.rank(pct=True))
         if overall:
             df['perc'] = (df.v - min_) / (max_ - min_)
+            df['rank'] = df.v.rank(pct=True)
         return {
             'records': df.to_dict(orient='records'),
             'extents': [min_, max_],

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

Mime
View raw message