superset-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From maximebeauche...@apache.org
Subject [incubator-superset] branch master updated: [time series table] visual improvements (#3957)
Date Fri, 01 Dec 2017 04:48:19 GMT
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 76a2f95  [time series table] visual improvements (#3957)
76a2f95 is described below

commit 76a2f952310cd66ec71e83f99f9e49d6499b7044
Author: Chris Williams <williaster@users.noreply.github.com>
AuthorDate: Thu Nov 30 20:48:17 2017 -0800

    [time series table] visual improvements (#3957)
    
    * [time series table] visual improvements
    
    * [time series table] don't set cell color if text color isn't set
---
 .../controls/TimeSeriesColumnControl.jsx           | 33 +++++---
 superset/assets/javascripts/modules/dates.js       | 17 +++-
 superset/assets/package.json                       |  4 +-
 superset/assets/stylesheets/superset.less          |  4 +
 superset/assets/visualizations/time_table.jsx      | 91 +++++++++++++---------
 5 files changed, 96 insertions(+), 53 deletions(-)

diff --git a/superset/assets/javascripts/explore/components/controls/TimeSeriesColumnControl.jsx
b/superset/assets/javascripts/explore/components/controls/TimeSeriesColumnControl.jsx
index cd8ec98..2634dd7 100644
--- a/superset/assets/javascripts/explore/components/controls/TimeSeriesColumnControl.jsx
+++ b/superset/assets/javascripts/explore/components/controls/TimeSeriesColumnControl.jsx
@@ -33,7 +33,7 @@ const colTypeOptions = [
 export default class TimeSeriesColumnControl extends React.Component {
   constructor(props) {
     super(props);
-    const state = Object.assign({}, props);
+    const state = { ...props };
     delete state.onChange;
     this.state = state;
     this.onChange = this.onChange.bind(this);
@@ -61,7 +61,7 @@ export default class TimeSeriesColumnControl extends React.Component {
     return (
       <Row style={{ marginTop: '5px' }}>
         <Col md={5}>
-          {label}{' '}
+          {`${label} `}
           <InfoTooltipWithTrigger
             placement="top"
             tooltip={tooltip}
@@ -75,7 +75,7 @@ export default class TimeSeriesColumnControl extends React.Component {
   renderPopover() {
     return (
       <Popover id="ts-col-popo" title="Column Configuration">
-        <div style={{ width: '280px' }}>
+        <div style={{ width: 300 }}>
           {this.formRow(
             'Label',
             'The column header label',
@@ -166,13 +166,11 @@ export default class TimeSeriesColumnControl extends React.Component
{
             />,
           )}
           {this.state.colType !== 'spark' && this.formRow(
-            'Bounds',
+            'Color bounds',
             (
-              'Number bounds used for color coding from red to green. ' +
-              'Reverse the number for green to red. To get boolean ' +
-              'red or green without spectrum, you can use either only ' +
-              'min, or max, depending on whether small or big should be ' +
-              'green or red.'
+              `Number bounds used for color encoding from red to blue.
+              Reverse the numbers for blue to red. To get pure red or blue,
+              you can enter either only min or max.`
             ),
             'bounds',
             <BoundsControl
@@ -181,14 +179,25 @@ export default class TimeSeriesColumnControl extends React.Component
{
             />,
           )}
           {this.formRow(
-            'D3 format',
-            'D3 format string',
+            'Number format',
+            'Optional d3 number format string',
             'd3-format',
             <FormControl
               value={this.state.d3format}
               onChange={this.onTextInputChange.bind(this, 'd3format')}
               bsSize="small"
-              placeholder="D3 format string"
+              placeholder="Number format string"
+            />,
+          )}
+          {this.state.colType === 'spark' && this.formRow(
+            'Date format',
+            'Optional d3 date format string',
+            'date-format',
+            <FormControl
+              value={this.state.dateFormat}
+              onChange={this.onTextInputChange.bind(this, 'dateFormat')}
+              bsSize="small"
+              placeholder="Date format string"
             />,
           )}
         </div>
diff --git a/superset/assets/javascripts/modules/dates.js b/superset/assets/javascripts/modules/dates.js
index 88b62c5..c1bf47d 100644
--- a/superset/assets/javascripts/modules/dates.js
+++ b/superset/assets/javascripts/modules/dates.js
@@ -66,10 +66,23 @@ export const formatDate = function (dttm) {
   const d = UTC(new Date(dttm));
   return tickMultiFormat(d);
 };
-export const fDuration = function (t1, t2, f = 'HH:mm:ss.SS') {
+
+export const formatDateThunk = function (format) {
+  if (!format) {
+    return formatDate;
+  }
+
+  const formatter = d3.time.format(format);
+  return (dttm) => {
+    const d = UTC(new Date(dttm));
+    return formatter(d);
+  };
+};
+
+export const fDuration = function (t1, t2, format = 'HH:mm:ss.SS') {
   const diffSec = t2 - t1;
   const duration = moment(new Date(diffSec));
-  return duration.utc().format(f);
+  return duration.utc().format(format);
 };
 
 export const now = function () {
diff --git a/superset/assets/package.json b/superset/assets/package.json
index c3c2174..eb3af55 100644
--- a/superset/assets/package.json
+++ b/superset/assets/package.json
@@ -39,8 +39,8 @@
   },
   "homepage": "http://superset.apache.org/",
   "dependencies": {
-    "@data-ui/event-flow": "0.0.8",
-    "@data-ui/sparkline": "0.0.47",
+    "@data-ui/event-flow": "^0.0.8",
+    "@data-ui/sparkline": "^0.0.49",
     "babel-register": "^6.24.1",
     "bootstrap": "^3.3.6",
     "brace": "^0.10.0",
diff --git a/superset/assets/stylesheets/superset.less b/superset/assets/stylesheets/superset.less
index 49c6544..6f6b502 100644
--- a/superset/assets/stylesheets/superset.less
+++ b/superset/assets/stylesheets/superset.less
@@ -218,6 +218,10 @@ div.widget {
     float: left;
 }
 
+table.table-no-hover tr:hover {
+    background-color: initial;
+}
+
 .editable-title input {
     padding: 2px 6px 3px 6px;
 }
diff --git a/superset/assets/visualizations/time_table.jsx b/superset/assets/visualizations/time_table.jsx
index cb145c8..0347c41 100644
--- a/superset/assets/visualizations/time_table.jsx
+++ b/superset/assets/visualizations/time_table.jsx
@@ -7,8 +7,8 @@ import Mustache from 'mustache';
 import { Sparkline, LineSeries, PointSeries, VerticalReferenceLine, WithTooltip } from '@data-ui/sparkline';
 
 import MetricOption from '../javascripts/components/MetricOption';
-import { d3format, brandColor } from '../javascripts/modules/utils';
-import { formatDate } from '../javascripts/modules/dates';
+import { d3format } from '../javascripts/modules/utils';
+import { formatDateThunk } from '../javascripts/modules/dates';
 import InfoTooltipWithTrigger from '../javascripts/components/InfoTooltipWithTrigger';
 import './time_table.css';
 
@@ -18,6 +18,13 @@ const SPARKLINE_MARGIN = {
   bottom: 8,
   left: 8,
 };
+const sparklineTooltipProps = {
+  style: {
+    opacity: 0.8,
+  },
+  offsetTop: 0,
+};
+
 const ACCESSIBLE_COLOR_BOUNDS = ['#ca0020', '#0571b0'];
 
 function FormattedNumber({ num, format }) {
@@ -65,16 +72,16 @@ function viz(slice, payload) {
       leftCell = url ? <a href={url} target="_blank">{metric}</a> : metric;
     }
     const row = { metric: leftCell };
-    fd.column_collection.forEach((c) => {
-      if (c.colType === 'spark') {
+    fd.column_collection.forEach((column) => {
+      if (column.colType === 'spark') {
         let sparkData;
-        if (!c.timeRatio) {
+        if (!column.timeRatio) {
           sparkData = data.map(d => d[metric]);
         } else {
           // Period ratio sparkline
           sparkData = [];
-          for (let i = c.timeRatio; i < data.length; i++) {
-            const prevData = data[i - c.timeRatio][metric];
+          for (let i = column.timeRatio; i < data.length; i++) {
+            const prevData = data[i - column.timeRatio][metric];
             if (prevData && prevData !== 0) {
               sparkData.push(data[i][metric] / prevData);
             } else {
@@ -82,13 +89,16 @@ function viz(slice, payload) {
             }
           }
         }
-        row[c.key] = {
+        const formatDate = formatDateThunk(column.dateFormat);
+        row[column.key] = {
           data: sparkData[sparkData.length - 1],
           display: (
             <WithTooltip
+              tooltipProps={sparklineTooltipProps}
+              hoverStyles={null}
               renderTooltip={({ index }) => (
                 <div>
-                  <strong>{d3format(c.d3format, sparkData[index])}</strong>
+                  <strong>{d3format(column.d3format, sparkData[index])}</strong>
                   <div>{formatDate(data[index].iso)}</div>
                 </div>
               )}
@@ -96,8 +106,8 @@ function viz(slice, payload) {
               {({ onMouseLeave, onMouseMove, tooltipData }) => (
                 <Sparkline
                   ariaLabel={`spark-${metric}`}
-                  width={parseInt(c.width, 10) || 300}
-                  height={parseInt(c.height, 10) || 50}
+                  width={parseInt(column.width, 10) || 300}
+                  height={parseInt(column.height, 10) || 50}
                   margin={SPARKLINE_MARGIN}
                   data={sparkData}
                   onMouseLeave={onMouseLeave}
@@ -105,7 +115,7 @@ function viz(slice, payload) {
                 >
                   <LineSeries
                     showArea={false}
-                    stroke={brandColor}
+                    stroke="#767676"
                   />
                   {tooltipData &&
                     <VerticalReferenceLine
@@ -116,7 +126,7 @@ function viz(slice, payload) {
                   {tooltipData &&
                     <PointSeries
                       points={[tooltipData.index]}
-                      fill={brandColor}
+                      fill="#767676"
                       strokeWidth={1}
                     />}
                 </Sparkline>
@@ -127,47 +137,53 @@ function viz(slice, payload) {
       } else {
         const recent = reversedData[0][metric];
         let v;
-        if (c.colType === 'time') {
+        if (column.colType === 'time') {
           // Time lag ratio
-          v = reversedData[parseInt(c.timeLag, 10)][metric];
-          if (c.comparisonType === 'diff') {
+          v = reversedData[parseInt(column.timeLag, 10)][metric];
+          if (column.comparisonType === 'diff') {
             v = recent - v;
-          } else if (c.comparisonType === 'perc') {
+          } else if (column.comparisonType === 'perc') {
             v = recent / v;
-          } else if (c.comparisonType === 'perc_change') {
+          } else if (column.comparisonType === 'perc_change') {
             v = (recent / v) - 1;
           }
-        } else if (c.colType === 'contrib') {
+        } else if (column.colType === 'contrib') {
           // contribution to column total
           v = recent / Object.keys(reversedData[0])
-          .map(k => k !== 'iso' ? reversedData[0][k] : null)
-          .reduce((a, b) => a + b);
-        } else if (c.colType === 'avg') {
+            .map(k => k !== 'iso' ? reversedData[0][k] : null)
+            .reduce((a, b) => a + b);
+        } else if (column.colType === 'avg') {
           // Average over the last {timeLag}
           v = reversedData
-          .map((k, i) => i < c.timeLag ? k[metric] : 0)
-          .reduce((a, b) => a + b) / c.timeLag;
+          .map((k, i) => i < column.timeLag ? k[metric] : 0)
+          .reduce((a, b) => a + b) / column.timeLag;
         }
         let color;
-        if (c.bounds && c.bounds[0] !== null && c.bounds[1] !== null) {
+        if (column.bounds && column.bounds[0] !== null && column.bounds[1]
!== null) {
           const scaler = d3.scale.linear()
             .domain([
-              c.bounds[0],
-              c.bounds[0] + ((c.bounds[1] - c.bounds[0]) / 2),
-              c.bounds[1]])
+              column.bounds[0],
+              column.bounds[0] + ((column.bounds[1] - column.bounds[0]) / 2),
+              column.bounds[1],
+            ])
             .range([ACCESSIBLE_COLOR_BOUNDS[0], 'grey', ACCESSIBLE_COLOR_BOUNDS[1]]);
           color = scaler(v);
-        } else if (c.bounds && c.bounds[0] !== null) {
-          color = v >= c.bounds[0] ? ACCESSIBLE_COLOR_BOUNDS[1] : ACCESSIBLE_COLOR_BOUNDS[0];
-        } else if (c.bounds && c.bounds[1] !== null) {
-          color = v < c.bounds[1] ? ACCESSIBLE_COLOR_BOUNDS[1] : ACCESSIBLE_COLOR_BOUNDS[0];
+        } else if (column.bounds && column.bounds[0] !== null) {
+          color = v >= column.bounds[0] ? ACCESSIBLE_COLOR_BOUNDS[1] : ACCESSIBLE_COLOR_BOUNDS[0];
+        } else if (column.bounds && column.bounds[1] !== null) {
+          color = v < column.bounds[1] ? ACCESSIBLE_COLOR_BOUNDS[1] : ACCESSIBLE_COLOR_BOUNDS[0];
         }
-        row[c.key] = {
+        row[column.key] = {
           data: v,
           display: (
-            <span style={{ color }}>
-              <FormattedNumber num={v} format={c.d3format} />
-            </span>),
+            <div style={{ color }}>
+              <FormattedNumber num={v} format={column.d3format} />
+            </div>
+          ),
+          style: color && {
+            boxShadow: `inset 0px -2.5px 0px 0px ${color}`,
+            borderRight: '2px solid #fff',
+          },
         };
       }
     });
@@ -175,7 +191,7 @@ function viz(slice, payload) {
   });
   ReactDOM.render(
     <Table
-      className="table table-condensed"
+      className="table table-no-hover"
       defaultSort={defaultSort}
       sortBy={defaultSort}
       sortable={fd.column_collection.map(c => c.key)}
@@ -201,6 +217,7 @@ function viz(slice, payload) {
               column={c.key}
               key={c.key}
               value={row[c.key].data}
+              style={row[c.key].style}
             >
               {row[c.key].display}
             </Td>))}

-- 
To stop receiving notification emails like this one, please contact
['"commits@superset.apache.org" <commits@superset.apache.org>'].

Mime
View raw message