Add NVD3's bullet chart (#1775)

* 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.
This commit is contained in:
Daniel Darabos 2016-12-12 16:58:13 +00:00 committed by Maxime Beauchemin
parent afb3c24d5a
commit 2993ff1d75
9 changed files with 171 additions and 1 deletions

View File

@ -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 %

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -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;

View File

@ -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',
];

View File

@ -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: [

View File

@ -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'),

View File

@ -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);
}
@ -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');
@ -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;

View File

@ -987,6 +987,36 @@ class FormFactory(object):
],
"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

View File

@ -896,6 +896,69 @@ class BubbleViz(NVD3Viz):
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"""
@ -2008,6 +2071,7 @@ viz_types_list = [
DistributionBarViz,
DistributionPieViz,
BubbleViz,
BulletViz,
MarkupViz,
WordCloudViz,
BigNumberViz,