From 1eb9d3d22f16f2bbabd8a1319475c655a1163e42 Mon Sep 17 00:00:00 2001 From: Chris Williams Date: Fri, 3 Nov 2017 00:03:40 -0700 Subject: [PATCH 1/3] [time table] add tooltip to sparkline --- superset/assets/javascripts/modules/dates.js | 1 - superset/assets/package.json | 2 +- superset/assets/visualizations/time_table.jsx | 67 ++++++++++++------- superset/assets/webpack.config.js | 2 +- 4 files changed, 44 insertions(+), 28 deletions(-) diff --git a/superset/assets/javascripts/modules/dates.js b/superset/assets/javascripts/modules/dates.js index 2c2815e8a1bd..88b62c5890b6 100644 --- a/superset/assets/javascripts/modules/dates.js +++ b/superset/assets/javascripts/modules/dates.js @@ -64,7 +64,6 @@ export const tickMultiFormat = d3.time.format.multi([ ]); export const formatDate = function (dttm) { const d = UTC(new Date(dttm)); - // d = new Date(d.getTime() - 1 * 60 * 60 * 1000); return tickMultiFormat(d); }; export const fDuration = function (t1, t2, f = 'HH:mm:ss.SS') { diff --git a/superset/assets/package.json b/superset/assets/package.json index 62ae28cc00c9..6f6068d6e524 100644 --- a/superset/assets/package.json +++ b/superset/assets/package.json @@ -40,7 +40,7 @@ "homepage": "http://superset.apache.org/", "dependencies": { "@data-ui/event-flow": "0.0.8", - "@data-ui/sparkline": "0.0.1", + "@data-ui/sparkline": "0.0.47", "babel-register": "^6.24.1", "bootstrap": "^3.3.6", "brace": "^0.10.0", diff --git a/superset/assets/visualizations/time_table.jsx b/superset/assets/visualizations/time_table.jsx index f99482d8eb1f..886887f049c7 100644 --- a/superset/assets/visualizations/time_table.jsx +++ b/superset/assets/visualizations/time_table.jsx @@ -3,16 +3,21 @@ import React from 'react'; import propTypes from 'prop-types'; import { Table, Thead, Th, Tr, Td } from 'reactable'; import d3 from 'd3'; -import { Sparkline, LineSeries } from '@data-ui/sparkline'; +import { Sparkline, LineSeries, PointSeries, VerticalReferenceLine, WithTooltip } from '@data-ui/sparkline'; import Mustache from 'mustache'; import MetricOption from '../javascripts/components/MetricOption'; -import TooltipWrapper from '../javascripts/components/TooltipWrapper'; import { d3format, brandColor } from '../javascripts/modules/utils'; +import { formatDate } from '../javascripts/modules/dates'; import InfoTooltipWithTrigger from '../javascripts/components/InfoTooltipWithTrigger'; import './time_table.css'; -const SPARK_MARGIN = 3; +const SPARKLINE_MARGIN = { + top: 8, + right: 8, + bottom: 8, + left: 8, +}; const ACCESSIBLE_COLOR_BOUNDS = ['#ca0020', '#0571b0']; function FormattedNumber({ num, format }) { @@ -23,21 +28,19 @@ function FormattedNumber({ num, format }) { } return {num}; } + FormattedNumber.propTypes = { num: propTypes.number, format: propTypes.string, }; function viz(slice, payload) { + console.log(slice, payload) slice.container.css('height', slice.height()); - const recs = payload.data.records; + const records = payload.data.records; const fd = payload.form_data; - const data = Object.keys(recs).sort().map((iso) => { - const o = recs[iso]; - return o; - }); - const reversedData = data.slice(); - reversedData.reverse(); + const data = Object.keys(records).sort().map(iso => ({ ...records[iso], iso })); + const reversedData = [...data].reverse(); const metricMap = {}; slice.datasource.metrics.forEach((m) => { metricMap[m.metric_name] = m; @@ -53,13 +56,13 @@ function viz(slice, payload) { } const tableData = metrics.map((metric) => { let leftCell; - const context = Object.assign({}, fd, { metric }); + const context = { ...fd, metric }; const url = fd.url ? Mustache.render(fd.url, context) : null; if (!payload.data.is_group_by) { leftCell = ; } else { - leftCell = url ? {metric} : metric; + leftCell = url ? {metric} : metric; } const row = { metric: leftCell }; fd.column_collection.forEach((c) => { @@ -79,33 +82,47 @@ function viz(slice, payload) { } } } - const extent = d3.extent(sparkData); - const tooltip = `min: ${d3format(c.d3format, extent[0])}, \ - max: ${d3format(c.d3format, extent[1])}`; row[c.key] = { data: sparkData[sparkData.length - 1], display: ( - -
+ ( +
+ {d3format(c.d3format, data[index][metric])} +
{formatDate(data[index].iso)}
+
+ )} + > + {({ onMouseLeave, onMouseMove, tooltipData }) => ( + {tooltipData && + } + {tooltipData && + } -
-
), + )} + + ), }; } else { const recent = reversedData[0][metric]; diff --git a/superset/assets/webpack.config.js b/superset/assets/webpack.config.js index 952f73326376..bb1729c144b7 100644 --- a/superset/assets/webpack.config.js +++ b/superset/assets/webpack.config.js @@ -47,7 +47,7 @@ const config = { }, { test: /\.jsx?$/, - exclude: APP_DIR + '/node_modules', + exclude: /node_modules/, loader: 'babel-loader', query: { presets: [ From 101f08803185beb284d4f409614ee1a8a36bbbfe Mon Sep 17 00:00:00 2001 From: Chris Williams Date: Fri, 3 Nov 2017 00:25:26 -0700 Subject: [PATCH 2/3] [time table] open link in new tab --- .../assets/javascripts/components/MetricOption.jsx | 5 +++-- .../spec/javascripts/components/MetricOption_spec.jsx | 9 +++++++++ superset/assets/visualizations/time_table.jsx | 11 ++++------- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/superset/assets/javascripts/components/MetricOption.jsx b/superset/assets/javascripts/components/MetricOption.jsx index d952b06aec6e..8d27ea4de506 100644 --- a/superset/assets/javascripts/components/MetricOption.jsx +++ b/superset/assets/javascripts/components/MetricOption.jsx @@ -5,6 +5,7 @@ import InfoTooltipWithTrigger from './InfoTooltipWithTrigger'; const propTypes = { metric: PropTypes.object.isRequired, + openInNewWindow: PropTypes.bool, showFormula: PropTypes.bool, url: PropTypes.string, }; @@ -12,9 +13,9 @@ const defaultProps = { showFormula: true, }; -export default function MetricOption({ metric, showFormula, url }) { +export default function MetricOption({ metric, openInNewWindow, showFormula, url }) { const verbose = metric.verbose_name || metric.metric_name; - const link = url ? {verbose} : verbose; + const link = url ? {verbose} : verbose; return (
{link} diff --git a/superset/assets/spec/javascripts/components/MetricOption_spec.jsx b/superset/assets/spec/javascripts/components/MetricOption_spec.jsx index 952e9fa125b1..4eeb13ed1f0a 100644 --- a/superset/assets/spec/javascripts/components/MetricOption_spec.jsx +++ b/superset/assets/spec/javascripts/components/MetricOption_spec.jsx @@ -50,4 +50,13 @@ describe('MetricOption', () => { wrapper = shallow(factory(props)); expect(wrapper.find(InfoTooltipWithTrigger)).to.have.length(1); }); + it('sets target="_blank" when openInNewWindow is true', () => { + props.url = 'https://github.com/apache/incubator-superset'; + wrapper = shallow(factory(props)); + expect(wrapper.find('a').prop('target')).to.equal(null); + + props.openInNewWindow = true; + wrapper = shallow(factory(props)); + expect(wrapper.find('a').prop('target')).to.equal('_blank'); + }); }); diff --git a/superset/assets/visualizations/time_table.jsx b/superset/assets/visualizations/time_table.jsx index 886887f049c7..07b68b322e63 100644 --- a/superset/assets/visualizations/time_table.jsx +++ b/superset/assets/visualizations/time_table.jsx @@ -4,7 +4,6 @@ import propTypes from 'prop-types'; import { Table, Thead, Th, Tr, Td } from 'reactable'; import d3 from 'd3'; import { Sparkline, LineSeries, PointSeries, VerticalReferenceLine, WithTooltip } from '@data-ui/sparkline'; -import Mustache from 'mustache'; import MetricOption from '../javascripts/components/MetricOption'; import { d3format, brandColor } from '../javascripts/modules/utils'; @@ -35,7 +34,6 @@ FormattedNumber.propTypes = { }; function viz(slice, payload) { - console.log(slice, payload) slice.container.css('height', slice.height()); const records = payload.data.records; const fd = payload.form_data; @@ -56,13 +54,12 @@ function viz(slice, payload) { } const tableData = metrics.map((metric) => { let leftCell; - const context = { ...fd, metric }; - const url = fd.url ? Mustache.render(fd.url, context) : null; - if (!payload.data.is_group_by) { - leftCell = ; + leftCell = ( + + ); } else { - leftCell = url ? {metric} : metric; + leftCell = fd.url ? {metric} : metric; } const row = { metric: leftCell }; fd.column_collection.forEach((c) => { From 41786df4a2c6cc66c331d1d31530b907d64455fe Mon Sep 17 00:00:00 2001 From: Chris Williams Date: Fri, 3 Nov 2017 11:32:53 -0700 Subject: [PATCH 3/3] [time table] add back Mustache --- superset/assets/visualizations/time_table.jsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/superset/assets/visualizations/time_table.jsx b/superset/assets/visualizations/time_table.jsx index 07b68b322e63..11d7be11607a 100644 --- a/superset/assets/visualizations/time_table.jsx +++ b/superset/assets/visualizations/time_table.jsx @@ -3,6 +3,7 @@ import React from 'react'; import propTypes from 'prop-types'; import { Table, Thead, Th, Tr, Td } from 'reactable'; import d3 from 'd3'; +import Mustache from 'mustache'; import { Sparkline, LineSeries, PointSeries, VerticalReferenceLine, WithTooltip } from '@data-ui/sparkline'; import MetricOption from '../javascripts/components/MetricOption'; @@ -54,12 +55,14 @@ function viz(slice, payload) { } const tableData = metrics.map((metric) => { let leftCell; + const context = { ...fd, metric }; + const url = fd.url ? Mustache.render(fd.url, context) : null; if (!payload.data.is_group_by) { leftCell = ( - + ); } else { - leftCell = fd.url ? {metric} : metric; + leftCell = url ? {metric} : metric; } const row = { metric: leftCell }; fd.column_collection.forEach((c) => {