Skip to content

Commit

Permalink
Add NVD3's bullet chart (apache#1775)
Browse files Browse the repository at this point in the history
* Add NVD3's bullet chart.

* Add empty lines before nested function definitions.

* Add thumbnail for bullet chart.

* Add bullet chart to gallery.rst.

* Add "requiresTime: false", fix indentation.

* Avoid scaling bullet chart vertically.

* Use a default if no range is specified.

* Fix coloring of bullet chart.
  • Loading branch information
darabos authored and mistercrunch committed Dec 12, 2016
1 parent afb3c24 commit 2993ff1
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 1 deletion.
3 changes: 3 additions & 0 deletions docs/gallery.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ Gallery
.. image:: _static/img/viz_thumbnails/big_number_total.png
:scale: 25 %

.. image:: _static/img/viz_thumbnails/bullet.png
:scale: 25 %

.. image:: _static/img/viz_thumbnails/dist_bar.png
:scale: 25 %

Expand Down
Binary file added superset/assets/images/viz_thumbnails/bullet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions superset/assets/javascripts/explorev2/stores/fields.js
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,48 @@ export const fields = {
],
description: 'The color for points and clusters in RGB',
},

ranges: {
type: 'TextField',
label: 'Ranges',
default: '',
description: 'Ranges to highlight with shading',
},

range_labels: {
type: 'TextField',
label: 'Range labels',
default: '',
description: 'Labels for the ranges',
},

markers: {
type: 'TextField',
label: 'Markers',
default: '',
description: 'List of values to mark with triangles',
},

marker_labels: {
type: 'TextField',
label: 'Marker labels',
default: '',
description: 'Labels for the markers',
},

marker_lines: {
type: 'TextField',
label: 'Marker lines',
default: '',
description: 'List of values to mark with lines',
},

marker_line_labels: {
type: 'TextField',
label: 'Marker line labels',
default: '',
description: 'Labels for the marker lines',
},
};
export default fields;

Expand Down
5 changes: 5 additions & 0 deletions superset/assets/javascripts/explorev2/stores/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,8 @@ export function initialState(vizType = 'table', datasourceType = 'table') {
};
}

// Control Panel fields that re-render chart without need for 'Query button'
export const autoQueryFields = [
'datasource',
'viz_type',
];
16 changes: 16 additions & 0 deletions superset/assets/javascripts/explorev2/stores/visTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,22 @@ const visTypes = {
],
},

bullet: {
label: 'Bullet Chart',
requiresTime: false,
controlPanelSections: [
{
label: null,
fieldSetRows: [
['metric'],
['ranges', 'range_labels'],
['markers', 'marker_labels'],
['marker_lines', 'marker_line_labels'],
],
},
],
},

big_number: {
label: 'Big Number with Trendline',
controlPanelSections: [
Expand Down
1 change: 1 addition & 0 deletions superset/assets/visualizations/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const vizMap = {
big_number_total: require('./big_number.js'),
box_plot: require('./nvd3_vis.js'),
bubble: require('./nvd3_vis.js'),
bullet: require('./nvd3_vis.js'),
cal_heatmap: require('./cal_heatmap.js'),
compare: require('./nvd3_vis.js'),
directed_force: require('./directed_force.js'),
Expand Down
11 changes: 10 additions & 1 deletion superset/assets/visualizations/nvd3_vis.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,10 @@ function nvd3Vis(slice) {
chart.maxBoxWidth(75); // prevent boxes from being incredibly wide
break;

case 'bullet':
chart = nv.models.bulletChart();
break;

default:
throw new Error('Unrecognized visualization for nvd3' + vizType);
}
Expand All @@ -261,6 +265,9 @@ function nvd3Vis(slice) {
}

let height = slice.height() - 15;
if (vizType === 'bullet') {
height = Math.min(height, 50);
}

chart.height(height);
slice.container.css('height', height + 'px');
Expand Down Expand Up @@ -309,7 +316,9 @@ function nvd3Vis(slice) {
chart.y2Axis.tickFormat(d3.format(fd.y_axis_format));
}
}
chart.color((d) => category21(d[colorKey]));
if (vizType !== 'bullet') {
chart.color((d) => category21(d[colorKey]));
}

if (fd.x_axis_label && fd.x_axis_label !== '' && chart.xAxis) {
let distance = 0;
Expand Down
30 changes: 30 additions & 0 deletions superset/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,36 @@ def __init__(self, viz):
],
"description": _("The color for points and clusters in RGB")
}),
'ranges': (TextField, {
"label": _("Ranges"),
"default": "",
"description": _("Ranges to highlight with shading")
}),
'range_labels': (TextField, {
"label": _("Range labels"),
"default": "",
"description": _("Labels for the ranges")
}),
'markers': (TextField, {
"label": _("Markers"),
"default": "",
"description": _("List of values to mark with triangles")
}),
'marker_labels': (TextField, {
"label": _("Marker labels"),
"default": "",
"description": _("Labels for the markers")
}),
'marker_lines': (TextField, {
"label": _("Marker lines"),
"default": "",
"description": _("List of values to mark with lines")
}),
'marker_line_labels': (TextField, {
"label": _("Marker line labels"),
"default": "",
"description": _("Labels for the marker lines")
}),
}

# Override default arguments with form overrides
Expand Down
64 changes: 64 additions & 0 deletions superset/viz.py
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,69 @@ def get_data(self):
return chart_data


class BulletViz(NVD3Viz):

"""Based on the NVD3 bullet chart"""

viz_type = "bullet"
verbose_name = _("Bullet Chart")
is_timeseries = False
fieldsets = ({
'label': None,
'fields': (
'metric',
'ranges', 'range_labels',
'markers', 'marker_labels',
'marker_lines', 'marker_line_labels',
)
},)

def query_obj(self):
form_data = self.form_data
d = super(BulletViz, self).query_obj()
self.metric = form_data.get('metric')

def as_strings(field):
value = form_data.get(field)
return value.split(',') if value else []

def as_floats(field):
return [float(x) for x in as_strings(field)]

self.ranges = as_floats('ranges')
self.range_labels = as_strings('range_labels')
self.markers = as_floats('markers')
self.marker_labels = as_strings('marker_labels')
self.marker_lines = as_floats('marker_lines')
self.marker_line_labels = as_strings('marker_line_labels')

d['metrics'] = [
self.metric,
]
if not self.metric:
raise Exception("Pick a metric to display")
return d

def get_df(self, query_obj=None):
df = super(BulletViz, self).get_df(query_obj)
df = df.fillna(0)
df['metric'] = df[[self.metric]]
return df

def get_data(self):
df = self.get_df()
values = df['metric'].values
return {
'measures': values.tolist(),
'ranges': self.ranges or [0, values.max() * 1.1],
'rangeLabels': self.range_labels or None,
'markers': self.markers or None,
'markerLabels': self.marker_labels or None,
'markerLines': self.marker_lines or None,
'markerLineLabels': self.marker_line_labels or None,
}


class BigNumberViz(BaseViz):

"""Put emphasis on a single metric with this big number viz"""
Expand Down Expand Up @@ -2008,6 +2071,7 @@ def get_data(self):
DistributionBarViz,
DistributionPieViz,
BubbleViz,
BulletViz,
MarkupViz,
WordCloudViz,
BigNumberViz,
Expand Down

0 comments on commit 2993ff1

Please sign in to comment.