diff --git a/panoramix/forms.py b/panoramix/forms.py index aff476699b..814fc0e972 100644 --- a/panoramix/forms.py +++ b/panoramix/forms.py @@ -116,6 +116,14 @@ class FormFactory(object): 'black_white']), default='fire', description=""), + 'normalize_across': SelectField( + 'Normalize Across', choices=self.choicify([ + 'heatmap', 'x', 'y']), + default='heatmap', + description=( + "Color will be rendered based on a ratio " + "of the cell against the sum of across this " + "criteria")), 'canvas_image_rendering': SelectField( 'Rendering', choices=( ('pixelated', 'pixelated (Sharp)'), diff --git a/panoramix/static/panoramix.js b/panoramix/static/panoramix.js index be0f71da6a..019ceacf39 100644 --- a/panoramix/static/panoramix.js +++ b/panoramix/static/panoramix.js @@ -25,7 +25,11 @@ var color = function(){ // Returns a linear scaler our of an array of color if(!Array.isArray(colors)) colors = spectrums[colors]; - var ext = d3.extent(data, accessor); + if(data !== undefined) + var ext = d3.extent(data, accessor); + else + var ext = [0,1]; + var points = []; var chunkSize = (ext[1] - ext[0]) / colors.length; $.each(colors, function(i, c){ diff --git a/panoramix/static/widgets/viz_heatmap.js b/panoramix/static/widgets/viz_heatmap.js index 7c81477652..8a04ab0581 100644 --- a/panoramix/static/widgets/viz_heatmap.js +++ b/panoramix/static/widgets/viz_heatmap.js @@ -7,6 +7,7 @@ px.registerViz('heatmap', function(slice) { var height = slice.height(); var hmWidth = width - (margins.l + margins.r) var hmHeight = height - (margins.b + margins.t) + var fp = d3.format('.3p'); d3.json(slice.jsonEndpoint(), function(error, payload) { var matrix = {}; if (error){ @@ -39,9 +40,7 @@ px.registerViz('heatmap', function(slice) { var X = 0, Y = 1; var heatmapDim = [xRbScale.domain().length, yRbScale.domain().length]; - var color = px.color.colorScalerFactory( - fd.linear_color_scheme, data, function(d){return d.v}); - + var color = px.color.colorScalerFactory(fd.linear_color_scheme); var scale = [ d3.scale.linear() @@ -99,6 +98,7 @@ px.registerViz('heatmap', function(slice) { s += "
" + fd.all_columns_x + ": " + obj.x + "
" s += "
" + fd.all_columns_y +": " + obj.y + "
" s += "
" + fd.metric + ": " + obj.v + "
" + s += "
%: " + fp(obj.perc) + "
" return s; } }) @@ -146,7 +146,7 @@ px.registerViz('heatmap', function(slice) { image = context.createImageData(heatmapDim[0], heatmapDim[1]); var pixs = {}; $.each(data, function(i, d) { - var c = d3.rgb(color(d.v)); + var c = d3.rgb(color(d.perc)); var x = xScale(d.x); var y = yScale(d.y); pixs[x + (y*xScale.domain().length)] = c; diff --git a/panoramix/viz.py b/panoramix/viz.py index bfeb15584f..6fd7702f30 100644 --- a/panoramix/viz.py +++ b/panoramix/viz.py @@ -1213,6 +1213,7 @@ class HeatmapViz(BaseViz): 'linear_color_scheme', ('xscale_interval', 'yscale_interval'), 'canvas_image_rendering', + 'normalize_across', ) },) def query_obj(self): @@ -1233,6 +1234,23 @@ class HeatmapViz(BaseViz): else: df = df[[x, y, v]] df.columns = ['x', 'y', 'v'] + norm = fd.get('normalize_across') + overall = False + if norm == 'heatmap': + overall = True + else: + gb = df.groupby(norm, group_keys=False) + if len(gb) <= 1: + overall = True + else: + df['perc'] = ( + gb.apply( + lambda x: (x.v - x.v.min()) / (x.v.max() - x.v.min())) + ) + if overall: + v = df.v + min_ = v.min() + df['perc'] = (v - min_) / (v.max() - min_) return df.to_json(orient="records")