You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ma...@apache.org on 2018/04/30 16:36:27 UTC
[incubator-superset] branch master updated: Heatmap improvements
(#4897)
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 <ma...@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.