diff --git a/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/Line/Stories.jsx b/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/Line/Stories.jsx new file mode 100644 index 000000000..1118f6302 --- /dev/null +++ b/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/Line/Stories.jsx @@ -0,0 +1,42 @@ +/* eslint-disable no-magic-numbers */ +import React from 'react'; +import { SuperChart } from '@superset-ui/chart'; +import data from './data'; + +export default [ + { + renderStory: () => ( + + ), + storyName: 'Basic', + storyPath: 'preset-chart-xy|LineChartPlugin', + }, +]; diff --git a/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/Line/data.js b/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/Line/data.js new file mode 100644 index 000000000..17c103293 --- /dev/null +++ b/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/Line/data.js @@ -0,0 +1,908 @@ +/* eslint-disable sort-keys, no-magic-numbers */ +export default [ + { + key: ['Christopher'], + values: [ + { + x: -157766400000.0, + y: 24703, + }, + { + x: -126230400000.0, + y: 27861, + }, + { + x: -94694400000.0, + y: 29436, + }, + { + x: -63158400000.0, + y: 31463, + }, + { + x: -31536000000.0, + y: 35718, + }, + { + x: 0.0, + y: 41758, + }, + { + x: 31536000000.0, + y: 48172, + }, + { + x: 63072000000.0, + y: 52092, + }, + { + x: 94694400000.0, + y: 48217, + }, + { + x: 126230400000.0, + y: 48476, + }, + { + x: 157766400000.0, + y: 46438, + }, + { + x: 189302400000.0, + y: 45086, + }, + { + x: 220924800000.0, + y: 46610, + }, + { + x: 252460800000.0, + y: 47107, + }, + { + x: 283996800000.0, + y: 50514, + }, + { + x: 315532800000.0, + y: 48969, + }, + { + x: 347155200000.0, + y: 50108, + }, + { + x: 378691200000.0, + y: 59055, + }, + { + x: 410227200000.0, + y: 59188, + }, + { + x: 441763200000.0, + y: 59859, + }, + { + x: 473385600000.0, + y: 59516, + }, + { + x: 504921600000.0, + y: 56633, + }, + { + x: 536457600000.0, + y: 54466, + }, + { + x: 567993600000.0, + y: 52996, + }, + { + x: 599616000000.0, + y: 53205, + }, + { + x: 631152000000.0, + y: 52322, + }, + { + x: 662688000000.0, + y: 47109, + }, + { + x: 694224000000.0, + y: 42470, + }, + { + x: 725846400000.0, + y: 38257, + }, + { + x: 757382400000.0, + y: 34823, + }, + { + x: 788918400000.0, + y: 32728, + }, + { + x: 820454400000.0, + y: 30988, + }, + { + x: 852076800000.0, + y: 29179, + }, + { + x: 883612800000.0, + y: 27083, + }, + { + x: 915148800000.0, + y: 25700, + }, + { + x: 946684800000.0, + y: 24959, + }, + { + x: 978307200000.0, + y: 23180, + }, + { + x: 1009843200000.0, + y: 21731, + }, + { + x: 1041379200000.0, + y: 20793, + }, + { + x: 1072915200000.0, + y: 19739, + }, + { + x: 1104537600000.0, + y: 19190, + }, + { + x: 1136073600000.0, + y: 19674, + }, + { + x: 1167609600000.0, + y: 19986, + }, + { + x: 1199145600000.0, + y: 17771, + }, + ], + }, + { + key: ['David'], + values: [ + { + x: -157766400000.0, + y: 67646, + }, + { + x: -126230400000.0, + y: 66207, + }, + { + x: -94694400000.0, + y: 66581, + }, + { + x: -63158400000.0, + y: 63531, + }, + { + x: -31536000000.0, + y: 63502, + }, + { + x: 0.0, + y: 61570, + }, + { + x: 31536000000.0, + y: 52948, + }, + { + x: 63072000000.0, + y: 46218, + }, + { + x: 94694400000.0, + y: 40968, + }, + { + x: 126230400000.0, + y: 41654, + }, + { + x: 157766400000.0, + y: 39019, + }, + { + x: 189302400000.0, + y: 39165, + }, + { + x: 220924800000.0, + y: 40407, + }, + { + x: 252460800000.0, + y: 40533, + }, + { + x: 283996800000.0, + y: 41898, + }, + { + x: 315532800000.0, + y: 41743, + }, + { + x: 347155200000.0, + y: 40486, + }, + { + x: 378691200000.0, + y: 40283, + }, + { + x: 410227200000.0, + y: 39048, + }, + { + x: 441763200000.0, + y: 38346, + }, + { + x: 473385600000.0, + y: 38395, + }, + { + x: 504921600000.0, + y: 37021, + }, + { + x: 536457600000.0, + y: 36672, + }, + { + x: 567993600000.0, + y: 35214, + }, + { + x: 599616000000.0, + y: 35139, + }, + { + x: 631152000000.0, + y: 33661, + }, + { + x: 662688000000.0, + y: 30347, + }, + { + x: 694224000000.0, + y: 28344, + }, + { + x: 725846400000.0, + y: 26947, + }, + { + x: 757382400000.0, + y: 24784, + }, + { + x: 788918400000.0, + y: 22967, + }, + { + x: 820454400000.0, + y: 22941, + }, + { + x: 852076800000.0, + y: 21824, + }, + { + x: 883612800000.0, + y: 20816, + }, + { + x: 915148800000.0, + y: 20267, + }, + { + x: 946684800000.0, + y: 19695, + }, + { + x: 978307200000.0, + y: 19281, + }, + { + x: 1009843200000.0, + y: 18600, + }, + { + x: 1041379200000.0, + y: 18557, + }, + { + x: 1072915200000.0, + y: 18315, + }, + { + x: 1104537600000.0, + y: 18017, + }, + { + x: 1136073600000.0, + y: 17510, + }, + { + x: 1167609600000.0, + y: 17400, + }, + { + x: 1199145600000.0, + y: 16049, + }, + ], + }, + { + key: ['James'], + values: [ + { + x: -157766400000.0, + y: 67506, + }, + { + x: -126230400000.0, + y: 65036, + }, + { + x: -94694400000.0, + y: 61554, + }, + { + x: -63158400000.0, + y: 60584, + }, + { + x: -31536000000.0, + y: 59824, + }, + { + x: 0.0, + y: 61597, + }, + { + x: 31536000000.0, + y: 54463, + }, + { + x: 63072000000.0, + y: 46960, + }, + { + x: 94694400000.0, + y: 42782, + }, + { + x: 126230400000.0, + y: 41258, + }, + { + x: 157766400000.0, + y: 39471, + }, + { + x: 189302400000.0, + y: 38203, + }, + { + x: 220924800000.0, + y: 39916, + }, + { + x: 252460800000.0, + y: 39783, + }, + { + x: 283996800000.0, + y: 39237, + }, + { + x: 315532800000.0, + y: 39185, + }, + { + x: 347155200000.0, + y: 38176, + }, + { + x: 378691200000.0, + y: 38750, + }, + { + x: 410227200000.0, + y: 36228, + }, + { + x: 441763200000.0, + y: 35728, + }, + { + x: 473385600000.0, + y: 35750, + }, + { + x: 504921600000.0, + y: 33955, + }, + { + x: 536457600000.0, + y: 32552, + }, + { + x: 567993600000.0, + y: 32418, + }, + { + x: 599616000000.0, + y: 32658, + }, + { + x: 631152000000.0, + y: 32288, + }, + { + x: 662688000000.0, + y: 30460, + }, + { + x: 694224000000.0, + y: 28450, + }, + { + x: 725846400000.0, + y: 26193, + }, + { + x: 757382400000.0, + y: 24706, + }, + { + x: 788918400000.0, + y: 22691, + }, + { + x: 820454400000.0, + y: 21122, + }, + { + x: 852076800000.0, + y: 20368, + }, + { + x: 883612800000.0, + y: 19651, + }, + { + x: 915148800000.0, + y: 18508, + }, + { + x: 946684800000.0, + y: 17939, + }, + { + x: 978307200000.0, + y: 17023, + }, + { + x: 1009843200000.0, + y: 16905, + }, + { + x: 1041379200000.0, + y: 16832, + }, + { + x: 1072915200000.0, + y: 16459, + }, + { + x: 1104537600000.0, + y: 16046, + }, + { + x: 1136073600000.0, + y: 16139, + }, + { + x: 1167609600000.0, + y: 15821, + }, + { + x: 1199145600000.0, + y: 14920, + }, + ], + }, + { + key: ['John'], + values: [ + { + x: -157766400000.0, + y: 71390, + }, + { + x: -126230400000.0, + y: 64858, + }, + { + x: -94694400000.0, + y: 61480, + }, + { + x: -63158400000.0, + y: 60754, + }, + { + x: -31536000000.0, + y: 58644, + }, + { + x: 0.0, + y: 58348, + }, + { + x: 31536000000.0, + y: 51382, + }, + { + x: 63072000000.0, + y: 43028, + }, + { + x: 94694400000.0, + y: 39061, + }, + { + x: 126230400000.0, + y: 37553, + }, + { + x: 157766400000.0, + y: 34970, + }, + { + x: 189302400000.0, + y: 33876, + }, + { + x: 220924800000.0, + y: 34103, + }, + { + x: 252460800000.0, + y: 33895, + }, + { + x: 283996800000.0, + y: 35305, + }, + { + x: 315532800000.0, + y: 35131, + }, + { + x: 347155200000.0, + y: 34761, + }, + { + x: 378691200000.0, + y: 34560, + }, + { + x: 410227200000.0, + y: 33047, + }, + { + x: 441763200000.0, + y: 32484, + }, + { + x: 473385600000.0, + y: 31397, + }, + { + x: 504921600000.0, + y: 30103, + }, + { + x: 536457600000.0, + y: 29462, + }, + { + x: 567993600000.0, + y: 29301, + }, + { + x: 599616000000.0, + y: 29751, + }, + { + x: 631152000000.0, + y: 29011, + }, + { + x: 662688000000.0, + y: 27727, + }, + { + x: 694224000000.0, + y: 26156, + }, + { + x: 725846400000.0, + y: 24918, + }, + { + x: 757382400000.0, + y: 24119, + }, + { + x: 788918400000.0, + y: 23174, + }, + { + x: 820454400000.0, + y: 22104, + }, + { + x: 852076800000.0, + y: 21330, + }, + { + x: 883612800000.0, + y: 20556, + }, + { + x: 915148800000.0, + y: 20280, + }, + { + x: 946684800000.0, + y: 20032, + }, + { + x: 978307200000.0, + y: 18839, + }, + { + x: 1009843200000.0, + y: 17400, + }, + { + x: 1041379200000.0, + y: 17170, + }, + { + x: 1072915200000.0, + y: 16381, + }, + { + x: 1104537600000.0, + y: 15692, + }, + { + x: 1136073600000.0, + y: 15083, + }, + { + x: 1167609600000.0, + y: 14348, + }, + { + x: 1199145600000.0, + y: 13110, + }, + ], + }, + { + key: ['Michael'], + values: [ + { + x: -157766400000.0, + y: 80812, + }, + { + x: -126230400000.0, + y: 79709, + }, + { + x: -94694400000.0, + y: 82204, + }, + { + x: -63158400000.0, + y: 81785, + }, + { + x: -31536000000.0, + y: 84893, + }, + { + x: 0.0, + y: 85015, + }, + { + x: 31536000000.0, + y: 77321, + }, + { + x: 63072000000.0, + y: 71197, + }, + { + x: 94694400000.0, + y: 67598, + }, + { + x: 126230400000.0, + y: 67304, + }, + { + x: 157766400000.0, + y: 68149, + }, + { + x: 189302400000.0, + y: 66686, + }, + { + x: 220924800000.0, + y: 67344, + }, + { + x: 252460800000.0, + y: 66875, + }, + { + x: 283996800000.0, + y: 67473, + }, + { + x: 315532800000.0, + y: 68375, + }, + { + x: 347155200000.0, + y: 68467, + }, + { + x: 378691200000.0, + y: 67904, + }, + { + x: 410227200000.0, + y: 67708, + }, + { + x: 441763200000.0, + y: 67457, + }, + { + x: 473385600000.0, + y: 64667, + }, + { + x: 504921600000.0, + y: 63959, + }, + { + x: 536457600000.0, + y: 63442, + }, + { + x: 567993600000.0, + y: 63924, + }, + { + x: 599616000000.0, + y: 65233, + }, + { + x: 631152000000.0, + y: 65138, + }, + { + x: 662688000000.0, + y: 60646, + }, + { + x: 694224000000.0, + y: 54216, + }, + { + x: 725846400000.0, + y: 49443, + }, + { + x: 757382400000.0, + y: 44361, + }, + { + x: 788918400000.0, + y: 41311, + }, + { + x: 820454400000.0, + y: 38284, + }, + { + x: 852076800000.0, + y: 37459, + }, + { + x: 883612800000.0, + y: 36525, + }, + { + x: 915148800000.0, + y: 33820, + }, + { + x: 946684800000.0, + y: 31956, + }, + { + x: 978307200000.0, + y: 29612, + }, + { + x: 1009843200000.0, + y: 28156, + }, + { + x: 1041379200000.0, + y: 27031, + }, + { + x: 1072915200000.0, + y: 25418, + }, + { + x: 1104537600000.0, + y: 23678, + }, + { + x: 1136073600000.0, + y: 22498, + }, + { + x: 1167609600000.0, + y: 21805, + }, + { + x: 1199145600000.0, + y: 20271, + }, + ], + }, +]; diff --git a/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/Line/index.js b/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/Line/index.js new file mode 100644 index 000000000..eee6be318 --- /dev/null +++ b/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/Line/index.js @@ -0,0 +1,8 @@ +import { LineChartPlugin } from '../../../../../superset-ui-preset-chart-xy/src'; +import Stories from './Stories'; + +new LineChartPlugin().configure({ key: 'line2' }).register(); + +export default { + examples: [...Stories], +}; diff --git a/packages/superset-ui-preset-chart-xy/package.json b/packages/superset-ui-preset-chart-xy/package.json index 0f2d66c4c..011617862 100644 --- a/packages/superset-ui-preset-chart-xy/package.json +++ b/packages/superset-ui-preset-chart-xy/package.json @@ -35,6 +35,7 @@ "@vx/responsive": "^0.0.184", "@vx/shape": "^0.0.184", "@vx/scale": "^0.0.182", + "d3-array": "^2.0.3", "prop-types": "^15.6.2" }, "peerDependencies": { @@ -43,6 +44,7 @@ "@superset-ui/color": "^0.10.0", "@superset-ui/dimension": "^0.10.0", "@superset-ui/number-format": "^0.10.0", + "@superset-ui/time-format": "^0.10.0", "@superset-ui/translation": "^0.10.0", "react": "^15 || ^16" } diff --git a/packages/superset-ui-preset-chart-xy/src/BoxPlot/BoxPlot.jsx b/packages/superset-ui-preset-chart-xy/src/BoxPlot/BoxPlot.jsx index d94b4852b..210c15f6a 100644 --- a/packages/superset-ui-preset-chart-xy/src/BoxPlot/BoxPlot.jsx +++ b/packages/superset-ui-preset-chart-xy/src/BoxPlot/BoxPlot.jsx @@ -133,7 +133,7 @@ class BoxPlot extends React.PureComponent { return ( ( + + )); + + const layout = new XYChartLayout({ ...config, children }); + + return layout.createChartWithFrame(dim => ( + + {children} + {layout.createXAxis()} + {layout.createYAxis()} + + )); + } + + render() { + const { className, data, width, height, encoding } = this.props; + + return ( + renderLegend(data, encoding.color)} + renderChart={parent => this.renderChart(parent)} + hideLegend={!encoding.color.legend} + /> + ); + } +} + +LineChart.propTypes = propTypes; +LineChart.defaultProps = defaultProps; + +export default LineChart; diff --git a/packages/superset-ui-preset-chart-xy/src/Line/createTooltip.jsx b/packages/superset-ui-preset-chart-xy/src/Line/createTooltip.jsx new file mode 100644 index 000000000..ebe3839be --- /dev/null +++ b/packages/superset-ui-preset-chart-xy/src/Line/createTooltip.jsx @@ -0,0 +1,5 @@ +import React from 'react'; + +export default function createTooltip() { + return () =>
tooltip!
; +} diff --git a/packages/superset-ui-preset-chart-xy/src/Line/images/thumbnail.png b/packages/superset-ui-preset-chart-xy/src/Line/images/thumbnail.png new file mode 100644 index 000000000..7df5084c4 Binary files /dev/null and b/packages/superset-ui-preset-chart-xy/src/Line/images/thumbnail.png differ diff --git a/packages/superset-ui-preset-chart-xy/src/Line/images/thumbnailLarge.png b/packages/superset-ui-preset-chart-xy/src/Line/images/thumbnailLarge.png new file mode 100644 index 000000000..67f8fe887 Binary files /dev/null and b/packages/superset-ui-preset-chart-xy/src/Line/images/thumbnailLarge.png differ diff --git a/packages/superset-ui-preset-chart-xy/src/Line/index.js b/packages/superset-ui-preset-chart-xy/src/Line/index.js new file mode 100644 index 000000000..30953c12a --- /dev/null +++ b/packages/superset-ui-preset-chart-xy/src/Line/index.js @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { t } from '@superset-ui/translation'; +import { ChartMetadata, ChartPlugin } from '@superset-ui/chart'; +import transformProps from './transformProps'; +import thumbnail from './images/thumbnail.png'; + +const metadata = new ChartMetadata({ + description: '', + name: t('Box Plot'), + thumbnail, + useLegacyApi: true, +}); + +export default class LineChartPlugin extends ChartPlugin { + constructor() { + super({ + loadChart: () => import('./Line'), + metadata, + transformProps, + }); + } +} diff --git a/packages/superset-ui-preset-chart-xy/src/Line/transformProps.js b/packages/superset-ui-preset-chart-xy/src/Line/transformProps.js new file mode 100644 index 000000000..bad42f936 --- /dev/null +++ b/packages/superset-ui-preset-chart-xy/src/Line/transformProps.js @@ -0,0 +1,56 @@ +import { getNumberFormatter } from '@superset-ui/number-format'; +import { getTimeFormatter } from '@superset-ui/time-format'; + +/* eslint-disable sort-keys */ + +export default function transformProps(chartProps) { + const { width, height, datasource = {}, formData, payload } = chartProps; + const { verboseMap = {} } = datasource; + const { + colorScheme, + groupby, + metrics, + xAxisLabel, + xAxisFormat, + yAxisLabel, + yAxisFormat, + } = formData; + + return { + data: payload.data, + width, + height, + encoding: { + x: { + accessor: d => d.x, + scale: { + type: 'time', + }, + axis: { + orientation: 'bottom', + label: xAxisLabel, + numTicks: 5, + tickFormat: getTimeFormatter(xAxisFormat), + }, + }, + y: { + accessor: d => d.y, + scale: { + type: 'linear', + }, + axis: { + orientation: 'left', + label: yAxisLabel, + tickFormat: getNumberFormatter(yAxisFormat), + }, + }, + color: { + accessor: d => d.key.join('/'), + scale: { + scheme: colorScheme, + }, + legend: true, + }, + }, + }; +} diff --git a/packages/superset-ui-preset-chart-xy/src/index.js b/packages/superset-ui-preset-chart-xy/src/index.js index d795b8729..498637196 100644 --- a/packages/superset-ui-preset-chart-xy/src/index.js +++ b/packages/superset-ui-preset-chart-xy/src/index.js @@ -1,3 +1,2 @@ -/* eslint-disable import/prefer-default-export */ - export { default as BoxPlotChartPlugin } from './BoxPlot'; +export { default as LineChartPlugin } from './Line'; diff --git a/packages/superset-ui-preset-chart-xy/src/utils/computeXAxisLayout.js b/packages/superset-ui-preset-chart-xy/src/utils/computeXAxisLayout.js index 6d8f9dd08..1997910fa 100644 --- a/packages/superset-ui-preset-chart-xy/src/utils/computeXAxisLayout.js +++ b/packages/superset-ui-preset-chart-xy/src/utils/computeXAxisLayout.js @@ -23,7 +23,8 @@ export default function computeXAxisLayout({ ); const maxWidth = Math.max(...labelDimensions.map(d => d.width)); - const widthPerTick = axisWidth / (tickLabels.length + 1); + // cheap heuristic, can improve + const widthPerTick = axisWidth / tickLabels.length; let finalStrategy; if (labellingStrategy !== 'auto') { diff --git a/packages/superset-ui-preset-chart-xy/src/utils/renderLegend.jsx b/packages/superset-ui-preset-chart-xy/src/utils/renderLegend.jsx index 3b19b50b8..d4e0f5137 100644 --- a/packages/superset-ui-preset-chart-xy/src/utils/renderLegend.jsx +++ b/packages/superset-ui-preset-chart-xy/src/utils/renderLegend.jsx @@ -4,12 +4,12 @@ import { LegendOrdinal, LegendItem, LegendLabel } from '@vx/legend'; import { scaleOrdinal } from '@vx/scale'; export default function renderLegend(data, colorEncoding) { - const { field, scale } = colorEncoding; + const { accessor, field, scale } = colorEncoding; const { scheme, namespace } = scale; const colorFn = CategoricalColorNamespace.getScale(scheme, namespace); const keySet = new Set(); data.forEach(d => { - keySet.add(d[field]); + keySet.add(accessor ? accessor(d) : d[field]); }); const keys = [...keySet.values()]; const colorScale = scaleOrdinal({