mirror of https://github.com/apache/superset.git
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:
parent
afb3c24d5a
commit
2993ff1d75
|
@ -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 |
|
@ -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;
|
||||
|
||||
|
|
|
@ -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',
|
||||
];
|
||||
|
|
|
@ -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: [
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue