From 15ee6d82e30dbc7be783754b567bc85b7f322c14 Mon Sep 17 00:00:00 2001 From: Shashank Shekhar Date: Wed, 10 Aug 2016 15:04:19 -0700 Subject: [PATCH] Histogram (#888) * Add Histogram as a visualization The css and js file use the histogram code from https://bl.ocks.org/mbostock/3048450. THe viz.py extends from BaseViz to create chart data only for one histogram * using d3.layout.histogram * CSS updated The new css has been used from the d3 chart http://bl.ocks.org/mbostock/1933560 * bars are visible * added semicolons * histogram from http://bl.ocks.org/mbostock/1933560 It takes as input no of bins. The histogram cycles through a set of colors for different lengths of the bar. It places a y axis coordinate on top or on the upper end of the bar whichever is suitable. * update style changes --- .../images/viz_thumbnails/histogram.png | Bin 0 -> 64899 bytes caravel/assets/javascripts/modules/caravel.js | 1 + caravel/assets/visualizations/histogram.css | 17 ++ caravel/assets/visualizations/histogram.js | 152 ++++++++++++++++++ caravel/viz.py | 69 ++++++++ docs/gallery.rst | 3 + 6 files changed, 242 insertions(+) create mode 100644 caravel/assets/images/viz_thumbnails/histogram.png create mode 100644 caravel/assets/visualizations/histogram.css create mode 100644 caravel/assets/visualizations/histogram.js diff --git a/caravel/assets/images/viz_thumbnails/histogram.png b/caravel/assets/images/viz_thumbnails/histogram.png new file mode 100644 index 0000000000000000000000000000000000000000..f7bbe62407fea8cfbb12ee133ff2f9fcb1732b70 GIT binary patch literal 64899 zcmeFac{tU3+cv(^xEs{oyFsF1r$LfbA~H0|P-G4*Dk(z?#UitIyX=H&C3eYBrVt{Q z!a@_3%52FB?No+^m3ds&dw!Pg;rSiU@%-@~$NPKU=Q!Sdci&qqYkj}p&*yVp=XIXv zb={W_>Fu94TYNT!LYb$nwbzhBnT9W?QD)7+zx*X-E|9;S+I4Ujg_3!7&iJwE`1=%B z!~MG{>F*`l@t2i0T80NH6tA@uO28i!$|$}S&_|V zJNUeC&nul@UPZq>aq|5LU;f?ohkG^V{^ePeE)((oj%$qTNln49U-!Gm>D)`tkL~;I z=P9@zN_D+;C1lROLj^J0p~QQiY}P^ zV!_N=lVAKf^}pe5zIW-awh0cFKPz!6reUd#^3HO4Bh@NDEzS1j**T?WzT~AJVe{XN zS%iOW^w8&+hp&m@r563hrY{l=9Qv9nyx>@)P7_LnX@H`lVrqK2USl4e6DRWI;ASyn zd;8?wcMk=w(#Umc47+jTQ8mlb!ot|pG%+Y>_EMX$$jH=!f}LyDtm$I@rC4%5Ia%A* z*0v$b_R49FsgqN>*FZHz6Tm^wWj;%5!H2%j@XtvtO@^*~noIm1i73 z&^dpYSzor9JWY+(u{Ry8v|LtBj)^7nbYYmM^g zxS_B1!5{aqh2!ugQbj){c@?Gj={x$@!B+-fvW>p{BHY9?b3~^GEV1@6*m~-H4gP&M zF)`7-bkO~AzPu)fNi)*by&{#o|LSsaWw-m|Dhub8h|QB!Hcsch5sMog^->-Fbit}8 zCMG7sCUl2pXiFPwsL9CO{Fd5S=T`Ewyw+&%use4)vgsz)))`B;o;>%`UogQRXyo~s z$;!%(et$mS#K7RL`JR**aRw5;M7<$HHN&x^%*{rdG;iTzKHy2Lo02sSu)Fl33; zfhc8@+-ARgLn9-P4Y8c2z7e0%{%U;%@4?gBhF)HI-H%&Dqg>zb!0(ms>B`jxFWu@^XMU=y zF9hqBlA6k@<@fdVDcDu4{MyssszvE??+4?4MYwNzmG(MM z)iIn%izjElTJh|J3tyb89k`k@!7ZB5HKWpR_V)EHy1Y00#A}9c-eq~sr$-N2<~j{D zmA!dWRhMRIa^%Q^7cce>v{&y>PEO9+Shj3p#oQU3v?Ud}&enKi&zD|0Izf1koTE=g zo}{PZtlh_v#_1{xmu>Q#I%Dp&^41&NydcfEj>@>eJP+O`>BU>Z!ou(*JBv)lg~3

+C!o<@xPaUfaDZ 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�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 U*SYsh{()rP9K+wE^j7crUmTSPl>h($ literal 0 HcmV?d00001 diff --git a/caravel/assets/javascripts/modules/caravel.js b/caravel/assets/javascripts/modules/caravel.js index de7f5899f8a4c..f19b5a66fe28a 100644 --- a/caravel/assets/javascripts/modules/caravel.js +++ b/caravel/assets/javascripts/modules/caravel.js @@ -32,6 +32,7 @@ const sourceMap = { cal_heatmap: 'cal_heatmap.js', horizon: 'horizon.js', mapbox: 'mapbox.jsx', + histogram: 'histogram.js', }; const color = function () { // Color related utility functions go in this object diff --git a/caravel/assets/visualizations/histogram.css b/caravel/assets/visualizations/histogram.css new file mode 100644 index 0000000000000..05fc086512c84 --- /dev/null +++ b/caravel/assets/visualizations/histogram.css @@ -0,0 +1,17 @@ +.axis line { + fill: none; + stroke: black; + shape-rendering: crispEdges; +} + +.axis text { + font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: 15px; +} + +.axis path, .axis line { + fill: none; + stroke: #000; + shape-rendering: crispEdges; +} diff --git a/caravel/assets/visualizations/histogram.js b/caravel/assets/visualizations/histogram.js new file mode 100644 index 0000000000000..10b6aea7a24e3 --- /dev/null +++ b/caravel/assets/visualizations/histogram.js @@ -0,0 +1,152 @@ +// JS +const d3 = require('d3') +const px = window.px || require('../javascripts/modules/caravel.js') + +// CSS +require('./histogram.css') + +function histogram(slice) { + + 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 navBarTitleSize = 12; + 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*3); + // Calculate bins for the data + const bins = d3.layout.histogram().bins(numBins)(data); + + // Set the x-values + x.domain(bins.map(function(d) { return d.x;})) + .rangeRoundBands([0, width], .1); + // Set the y-values + y.domain([0, d3.max(bins, function(d) { return 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', function(d) { return x(d.x); }) + .attr('y', function(d) { return y(d.y); }) + .attr('height', function(d) { + return y.range()[0] - y(d.y); + }) + .attr('fill', function(d) { return px.color.category21(d.length); }) + .order(); + + // Find maximum length to position the ticks on top of the bar correctly + const maxLength = d3.max(bins, function(d) { return 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', function(d) { return x(d.x) + (x.rangeBand()/2);}) + .attr('text-anchor', 'middle') + .attr('font-weight', 'bold') + .attr('font-size', '15px') + .text(function(d) { return formatNumber(d.y); }) + .attr('fill', function(d) { + if(textAboveBar(d)) { return 'black'; } else { return '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 render = function() { + + d3.json(slice.jsonEndpoint(), function(error, json) { + if(error !== null) { + slice.error(error.responseText, error); + return ''; + } + + const numBins = Number(json.form_data.link_length) || 10; + + div.selectAll('*').remove(); + _draw(json.data, numBins); + slice.done(json); + }); + }; + + return { + render: render, + resize: render, + }; +} + +module.exports = histogram; + diff --git a/caravel/viz.py b/caravel/viz.py index 13449b720dd3c..57ef270a11dde 100755 --- a/caravel/viz.py +++ b/caravel/viz.py @@ -1201,6 +1201,74 @@ def get_data(self): return df.to_dict(orient="records") +class HistogramViz(BaseViz): + + """Histogram""" + + viz_type = "histogram" + verbose_name = _("Histogram") + is_timeseries = False + fieldsets = ({ + 'label': None, + 'fields': ( + ('all_columns_x',), + 'row_limit', + ) + }, { + 'label': _("Histogram Options"), + 'fields': ( + 'link_length', + ) + },) + + form_overrides = { + 'all_columns_x': { + 'label': _('Numeric Column'), + 'description': _("Select the numeric column to draw the histogram"), + }, + 'link_length': { + 'label': _("No of Bins"), + 'description': _("Select number of bins for the histogram"), + 'default': 5 + } + } + + + 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('ROW_LIMIT'))) + numeric_column = self.form_data.get('all_columns_x') + if numeric_column is None: + raise Exception("Must have one numeric column specified") + d['columns'] = [numeric_column] + return d + + + def get_df(self, query_obj=None): + """Returns a pandas dataframe based on the query object""" + if not query_obj: + query_obj = self.query_obj() + + self.results = self.datasource.query(**query_obj) + self.query = self.results.query + df = self.results.df + + if df is None or df.empty: + raise Exception("No data, to build histogram") + + df.replace([np.inf, -np.inf], np.nan) + df = df.fillna(0) + return df + + + def get_data(self): + """Returns the chart data""" + df = self.get_df() + chart_data = df[df.columns[0]].values.tolist() + return chart_data + + class DistributionBarViz(DistributionPieViz): """A good old bar chart""" @@ -1921,6 +1989,7 @@ def get_data(self): CalHeatmapViz, HorizonViz, MapboxViz, + HistogramViz, SeparatorViz, ] diff --git a/docs/gallery.rst b/docs/gallery.rst index 9c7ee0b4e1b4f..e25cb19287a84 100644 --- a/docs/gallery.rst +++ b/docs/gallery.rst @@ -81,3 +81,6 @@ Gallery .. image:: _static/img/viz_thumbnails/separator.png :scale: 25 % + +.. image:: _static/img/viz_thumbnails/histogram.png + :scale: 25 %