diff --git a/superset/assets/src/explore/controls.jsx b/superset/assets/src/explore/controls.jsx index 8c063a7fc70db..152d4a72efdd7 100644 --- a/superset/assets/src/explore/controls.jsx +++ b/superset/assets/src/explore/controls.jsx @@ -1078,7 +1078,7 @@ export const controls = { isInt: true, validators: [v.integer], renderTrigger: true, - default: 0, + default: 2, label: t('Cell Padding'), description: t('The distance between cells, in pixels'), }, diff --git a/superset/assets/src/visualizations/cal_heatmap.css b/superset/assets/src/visualizations/cal_heatmap.css index b6be2d09d8288..6fd4f5b059e18 100644 --- a/superset/assets/src/visualizations/cal_heatmap.css +++ b/superset/assets/src/visualizations/cal_heatmap.css @@ -8,7 +8,3 @@ margin-left: 20px; margin-top: 5px; } -.graph-legend rect { - stroke: #aaa; - stroke-location: inside; -} diff --git a/superset/assets/src/visualizations/cal_heatmap.js b/superset/assets/src/visualizations/cal_heatmap.js index 97c6e57132516..af91dcee6891c 100644 --- a/superset/assets/src/visualizations/cal_heatmap.js +++ b/superset/assets/src/visualizations/cal_heatmap.js @@ -1,31 +1,73 @@ import d3 from 'd3'; - +import PropTypes from 'prop-types'; import { colorScalerFactory } from '../modules/colors'; import CalHeatMap from '../../vendor/cal-heatmap/cal-heatmap'; -import '../../vendor/cal-heatmap/cal-heatmap.css'; import { d3TimeFormatPreset, d3FormatPreset } from '../modules/utils'; -import './cal_heatmap.css'; import { UTC } from '../modules/dates'; +import '../../vendor/cal-heatmap/cal-heatmap.css'; +import './cal_heatmap.css'; const UTCTS = uts => UTC(new Date(uts)).getTime(); -function calHeatmap(slice, payload) { - const fd = slice.formData; - const steps = fd.steps; - const valueFormatter = d3FormatPreset(fd.y_axis_format); - const timeFormatter = d3TimeFormatPreset(fd.x_axis_time_format); +const propTypes = { + data: PropTypes.shape({ + // Object hashed by metric name, + // then hashed by timestamp (in seconds, not milliseconds) as float + // the innermost value is count + // e.g. { count_distinct_something: { 1535034236.0: 3 } } + data: PropTypes.object, + domain: PropTypes.string, + range: PropTypes.number, + // timestamp in milliseconds + start: PropTypes.number, + subdomain: PropTypes.string, + }), + height: PropTypes.number, + cellPadding: PropTypes.number, + cellRadius: PropTypes.number, + cellSize: PropTypes.number, + linearColorScheme: PropTypes.string, + showLegend: PropTypes.bool, + showMetricName: PropTypes.bool, + showValues: PropTypes.bool, + steps: PropTypes.number, + timeFormat: PropTypes.string, + valueFormat: PropTypes.string, + verboseMap: PropTypes.object, +}; + +function Calendar(element, props) { + PropTypes.checkPropTypes(propTypes, props, 'prop', 'Calendar'); + + const { + data, + height, + cellPadding = 3, + cellRadius = 0, + cellSize = 10, + linearColorScheme, + showLegend, + showMetricName, + showValues, + steps, + timeFormat, + valueFormat, + verboseMap, + } = props; - const container = d3.select(slice.selector).style('height', slice.height()); + const valueFormatter = d3FormatPreset(valueFormat); + const timeFormatter = d3TimeFormatPreset(timeFormat); + + const container = d3.select(element) + .style('height', height); container.selectAll('*').remove(); const div = container.append('div'); - const data = payload.data; - const subDomainTextFormat = fd.show_values ? (date, value) => valueFormatter(value) : null; - const cellPadding = fd.cell_padding !== '' ? fd.cell_padding : 2; - const cellRadius = fd.cell_radius || 0; - const cellSize = fd.cell_size || 10; + const subDomainTextFormat = showValues ? (date, value) => valueFormatter(value) : null; // Trick to convert all timestamps to UTC + // TODO: Verify if this conversion is really necessary + // since all timestamps should always be in UTC. const metricsData = {}; Object.keys(data.data).forEach((metric) => { metricsData[metric] = {}; @@ -36,15 +78,16 @@ function calHeatmap(slice, payload) { Object.keys(metricsData).forEach((metric) => { const calContainer = div.append('div'); - if (fd.show_metric_name) { - calContainer.append('h4').text(slice.verboseMetricName(metric)); + if (showMetricName) { + calContainer.text(`Metric: ${verboseMap[metric] || metric}`); } const timestamps = metricsData[metric]; const extents = d3.extent(Object.keys(timestamps), key => timestamps[key]); const step = (extents[1] - extents[0]) / (steps - 1); - const colorScale = colorScalerFactory(fd.linear_color_scheme, null, null, extents); + const colorScale = colorScalerFactory(linearColorScheme, null, null, extents); - const legend = d3.range(steps).map(i => extents[0] + (step * i)); + const legend = d3.range(steps) + .map(i => extents[0] + (step * i)); const legendColors = legend.map(colorScale); const cal = new CalHeatMap(); @@ -72,7 +115,7 @@ function calHeatmap(slice, payload) { max: legendColors[legendColors.length - 1], empty: 'white', }, - displayLegend: fd.show_legend, + displayLegend: showLegend, itemName: '', valueFormatter, timeFormatter, @@ -80,4 +123,41 @@ function calHeatmap(slice, payload) { }); }); } -module.exports = calHeatmap; + +Calendar.propTypes = propTypes; + +function adaptor(slice, payload) { + const { selector, formData, datasource } = slice; + const { + cell_padding: cellPadding, + cell_radius: cellRadius, + cell_size: cellSize, + linear_color_scheme: linearColorScheme, + show_legend: showLegend, + show_metric_name: showMetricName, + show_values: showValues, + steps, + x_axis_time_format: timeFormat, + y_axis_format: valueFormat, + } = formData; + const { verbose_map: verboseMap } = datasource; + const element = document.querySelector(selector); + + return Calendar(element, { + data: payload.data, + height: slice.height(), + cellPadding, + cellRadius, + cellSize, + linearColorScheme, + showLegend, + showMetricName, + showValues, + steps, + timeFormat, + valueFormat, + verboseMap, + }); +} + +export default adaptor; diff --git a/superset/assets/vendor/cal-heatmap/cal-heatmap.css b/superset/assets/vendor/cal-heatmap/cal-heatmap.css index 068997c19a184..d6e18bc7dc49d 100644 --- a/superset/assets/vendor/cal-heatmap/cal-heatmap.css +++ b/superset/assets/vendor/cal-heatmap/cal-heatmap.css @@ -4,11 +4,6 @@ display: block; } -.cal-heatmap-container .graph -{ - font-family: "Lucida Grande", Lucida, Verdana, sans-serif; -} - .cal-heatmap-container .graph-label { fill: #999;