feat: update tooltip and use selector (#31)

This commit is contained in:
Krist Wongsuphasawat 2019-04-01 13:56:13 -07:00 committed by Yongjie Zhao
parent fa0d4ea6bc
commit 818f4628f7
5 changed files with 57 additions and 27 deletions

View File

@ -8,7 +8,7 @@ const missingData = {
keys: data.keys, keys: data.keys,
values: data.values.map(({ y, ...rest }) => ({ values: data.values.map(({ y, ...rest }) => ({
...rest, ...rest,
y: Math.random() < 0.05 ? null : y, y: Math.random() < 0.25 ? null : y,
})), })),
}; };

View File

@ -1,23 +1,28 @@
{ {
"compilerOptions": { "compilerOptions": {
"allowJs": true,
"allowSyntheticDefaultImports": true,
"baseUrl": ".", "baseUrl": ".",
"outDir": "./dist", "outDir": "./dist",
"module": "commonjs", "esModuleInterop": true,
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react",
"moduleResolution": "node",
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"importHelpers": true,
"jsx": "react",
"lib": ["dom", "esnext"],
"module": "commonjs",
"moduleResolution": "node",
"noEmitOnError": true,
"noImplicitReturns": true, "noImplicitReturns": true,
"noImplicitThis": true, "noImplicitThis": true,
"noImplicitAny": true, "noImplicitAny": true,
"importHelpers": true, "noUnusedLocals": true,
"pretty": true,
"removeComments": false,
"strictNullChecks": true, "strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true, "suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true, "skipLibCheck": true,
"skipLibCheck": true "sourceMap": true,
"target": "esnext"
}, },
"include": ["./storybook/stories/**/*", "../superset-ui-*/src/**/*", "./src/**/*", "./spec/**/*"] "include": ["./storybook/stories/**/*", "../superset-ui-*/src/**/*", "./src/**/*", "./spec/**/*"]
} }

View File

@ -12,6 +12,7 @@ import {
import { chartTheme, ChartTheme } from '@data-ui/theme'; import { chartTheme, ChartTheme } from '@data-ui/theme';
import { Margin, Dimension } from '@superset-ui/dimension'; import { Margin, Dimension } from '@superset-ui/dimension';
import { groupBy, flatMap, uniqueId, values } from 'lodash'; import { groupBy, flatMap, uniqueId, values } from 'lodash';
import { createSelector } from 'reselect';
import createTooltip from './createTooltip'; import createTooltip from './createTooltip';
import XYChartLayout from '../utils/XYChartLayout'; import XYChartLayout from '../utils/XYChartLayout';
import WithLegend from '../components/WithLegend'; import WithLegend from '../components/WithLegend';
@ -59,13 +60,22 @@ class LineChart extends PureComponent<Props> {
constructor(props: Props) { constructor(props: Props) {
super(props); super(props);
const { encoding } = this.props;
this.encoder = new Encoder({ encoding }); const createEncoder = createSelector(
(enc: Encoding) => enc,
(enc: Encoding) => new Encoder({ encoding: enc }),
);
this.createEncoder = () => {
this.encoder = createEncoder(this.props.encoding);
};
this.encoder = createEncoder(this.props.encoding);
this.renderChart = this.renderChart.bind(this); this.renderChart = this.renderChart.bind(this);
} }
encoder: Encoder; encoder: Encoder;
private createEncoder: () => void;
renderChart(dim: Dimension) { renderChart(dim: Dimension) {
const { width, height } = dim; const { width, height } = dim;
@ -113,6 +123,7 @@ class LineChart extends PureComponent<Props> {
/>, />,
<AreaSeries <AreaSeries
key={`${series.key}-fill`} key={`${series.key}-fill`}
seriesKey={series.key}
data={series.values} data={series.values}
interpolation="linear" interpolation="linear"
fill={`url(#${gradientId})`} fill={`url(#${gradientId})`}
@ -202,9 +213,9 @@ class LineChart extends PureComponent<Props> {
} }
render() { render() {
const { className, data, width, height, encoding } = this.props; const { className, data, width, height } = this.props;
this.encoder = new Encoder({ encoding }); this.createEncoder();
const renderLegend = this.encoder.hasLegend() const renderLegend = this.encoder.hasLegend()
? // eslint-disable-next-line react/jsx-props-no-multi-spaces ? // eslint-disable-next-line react/jsx-props-no-multi-spaces
() => <ChartLegend<ChannelTypes, Outputs, Encoding> data={data} encoder={this.encoder} /> () => <ChartLegend<ChannelTypes, Outputs, Encoding> data={data} encoder={this.encoder} />

View File

@ -6,6 +6,8 @@ import TooltipTable from '../components/tooltip/TooltipTable';
import { Series, SeriesValue } from './Line'; import { Series, SeriesValue } from './Line';
import Encoder from './Encoder'; import Encoder from './Encoder';
const MARK_STYLE = { marginRight: 4 };
export default function createTooltip(encoder: Encoder, allSeries: Series[]) { export default function createTooltip(encoder: Encoder, allSeries: Series[]) {
function LineTooltip({ function LineTooltip({
datum, datum,
@ -31,13 +33,24 @@ export default function createTooltip(encoder: Encoder, allSeries: Series[]) {
.filter(({ key }) => series[key]) .filter(({ key }) => series[key])
.concat() .concat()
.sort((a, b) => series[b.key].y - series[a.key].y) .sort((a, b) => series[b.key].y - series[a.key].y)
.map(({ key, color }) => ({ .map(({ key, color, strokeDasharray }) => ({
key, key,
keyStyle: { keyColumn: (
color, <>
fontWeight: series[key] === datum ? 600 : 200, <svg width="12" height="8" style={MARK_STYLE}>
}, <line
value: encoder.channels.y.formatValue(series[key].y), x2="12"
y1="3"
y2="3"
stroke={color}
strokeWidth="2"
strokeDasharray={strokeDasharray}
/>
</svg>
{series[key] === datum ? <b>{key}</b> : key}
</>
),
valueColumn: encoder.channels.y.formatValue(series[key].y),
}))} }))}
/> />
)} )}

View File

@ -1,11 +1,12 @@
import React, { CSSProperties, PureComponent } from 'react'; import React, { CSSProperties, PureComponent, ReactNode } from 'react';
type Props = { type Props = {
className?: string; className?: string;
data: { data: {
key: string; key: string | number;
keyColumn: ReactNode;
keyStyle?: CSSProperties; keyStyle?: CSSProperties;
value: string | number; valueColumn: ReactNode;
valueStyle?: CSSProperties; valueStyle?: CSSProperties;
}[]; }[];
}; };
@ -24,11 +25,11 @@ export default class TooltipTable extends PureComponent<Props, {}> {
return ( return (
<table className={className}> <table className={className}>
<tbody> <tbody>
{data.map(({ key, keyStyle, value, valueStyle }) => ( {data.map(({ key, keyColumn, keyStyle, valueColumn, valueStyle }, i) => (
<tr key={key}> <tr key={key}>
<td style={keyStyle}>{key}</td> <td style={keyStyle}>{keyColumn}</td>
<td style={valueStyle ? { ...VALUE_CELL_STYLE, ...valueStyle } : VALUE_CELL_STYLE}> <td style={valueStyle ? { ...VALUE_CELL_STYLE, ...valueStyle } : VALUE_CELL_STYLE}>
{value} {valueColumn}
</td> </td>
</tr> </tr>
))} ))}