diff --git a/frontend/src/metabase/internal/pages/StaticVizPage.jsx b/frontend/src/metabase/internal/pages/StaticVizPage.jsx index 8c986c56c0047040d0abb05d9661a06578765830..1dc03e51fa1fafed3e87f169c3f5a2a40dd640db 100644 --- a/frontend/src/metabase/internal/pages/StaticVizPage.jsx +++ b/frontend/src/metabase/internal/pages/StaticVizPage.jsx @@ -17,181 +17,7 @@ export default function StaticVizPage() { /static-viz/ and see the effects. You might need to hard refresh to see updates. </Text> - <Box py={3}> - <Subhead>Line chart with timeseries data</Subhead> - <StaticChart - type="timeseries/line" - options={{ - data: [ - ["2020-01-10", 10], - ["2020-06-10", 60], - ["2020-12-10", 80], - ], - accessors: { - x: row => new Date(row[0]).valueOf(), - y: row => row[1], - }, - labels: { - left: "Count", - bottom: "Created At", - }, - }} - /> - </Box> - <Box py={3}> - <Subhead>Area chart with timeseries data</Subhead> - <StaticChart - type="timeseries/area" - options={{ - data: [ - ["2020-01-10", 10], - ["2020-06-10", 60], - ["2020-12-10", 80], - ], - accessors: { - x: row => new Date(row[0]).valueOf(), - y: row => row[1], - }, - settings: { - x: { - date_style: "MMM", - }, - }, - labels: { - left: "Count", - bottom: "Created At", - }, - colors: { - brand: "#88BF4D", - }, - }} - /> - </Box> - <Box py={3}> - <Subhead>Bar chart with timeseries data</Subhead> - <StaticChart - type="timeseries/bar" - options={{ - data: [ - ["2020-10-21", 20], - ["2020-10-22", 30], - ["2020-10-23", 25], - ["2020-10-24", 10], - ["2020-10-25", 15], - ], - accessors: { - x: row => new Date(row[0]).valueOf(), - y: row => row[1], - }, - settings: { - x: { - date_style: "MM/DD/YYYY", - }, - y: { - number_style: "currency", - currency: "USD", - currency_style: "symbol", - decimals: 0, - }, - }, - labels: { - left: "Price", - bottom: "Created At", - }, - }} - /> - </Box> - <Box py={3}> - <Subhead>Line chart with categorical data</Subhead> - <StaticChart - type="categorical/line" - options={{ - data: [ - ["Alden Sparks", 70], - ["Areli Guerra", 30], - ["Arturo Hopkins", 80], - ["Beatrice Lane", 120], - ["Brylee Davenport", 100], - ["Cali Nixon", 60], - ["Dane Terrell", 150], - ["Deshawn Rollins", 40], - ["Isabell Bright", 70], - ["Kaya Rowe", 20], - ["Roderick Herman", 50], - ["Ruth Dougherty", 75], - ], - accessors: { - x: row => row[0], - y: row => row[1], - }, - labels: { - left: "Tasks", - bottom: "People", - }, - }} - /> - </Box> - <Box py={3}> - <Subhead>Area chart with categorical data</Subhead> - <StaticChart - type="categorical/area" - options={{ - data: [ - ["Alden Sparks", 70], - ["Areli Guerra", 30], - ["Arturo Hopkins", 80], - ["Beatrice Lane", 120], - ["Brylee Davenport", 100], - ["Cali Nixon", 60], - ["Dane Terrell", 150], - ["Deshawn Rollins", 40], - ["Isabell Bright", 70], - ["Kaya Rowe", 20], - ["Roderick Herman", 50], - ["Ruth Dougherty", 75], - ], - accessors: { - x: row => row[0], - y: row => row[1], - }, - labels: { - left: "Tasks", - bottom: "People", - }, - }} - /> - </Box> - <Box py={3}> - <Subhead>Bar chart with categorical data</Subhead> - <StaticChart - type="categorical/bar" - options={{ - data: [ - ["Alden Sparks", 70], - ["Areli Guerra", 30], - ["Arturo Hopkins", 80], - ["Beatrice Lane", 120], - ["Brylee Davenport", 100], - ["Cali Nixon", 60], - ["Dane Terrell", 150], - ["Deshawn Rollins", 40], - ["Isabell Bright", 70], - ["Kaya Rowe", 20], - ["Roderick Herman", 50], - ["Ruth Dougherty", 75], - ], - accessors: { - x: row => row[0], - y: row => row[1], - }, - labels: { - left: "Tasks", - bottom: "People", - }, - }} - /> - </Box> <Box py={3}> <Subhead>Donut chart with categorical data</Subhead> <StaticChart diff --git a/frontend/src/metabase/static-viz/components/CategoricalAreaChart/CategoricalAreaChart.jsx b/frontend/src/metabase/static-viz/components/CategoricalAreaChart/CategoricalAreaChart.jsx deleted file mode 100644 index d5df42bd7b48a765b6c895ba861d1c20a7616729..0000000000000000000000000000000000000000 --- a/frontend/src/metabase/static-viz/components/CategoricalAreaChart/CategoricalAreaChart.jsx +++ /dev/null @@ -1,163 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { AxisBottom, AxisLeft } from "@visx/axis"; -import { GridRows } from "@visx/grid"; -import { scaleBand, scaleLinear } from "@visx/scale"; -import { AreaClosed, LinePath } from "@visx/shape"; -import { Text } from "@visx/text"; -import { - getXTickWidth, - getXTickLabelProps, - getYTickLabelProps, - getYTickWidth, - getRotatedXTickHeight, - getLabelProps, -} from "../../lib/axes"; -import { formatNumber } from "../../lib/numbers"; -import { truncateText } from "../../lib/text"; - -const propTypes = { - data: PropTypes.array.isRequired, - accessors: PropTypes.shape({ - x: PropTypes.func.isRequired, - y: PropTypes.func.isRequired, - }).isRequired, - settings: PropTypes.shape({ - x: PropTypes.object, - y: PropTypes.object, - colors: PropTypes.object, - }), - labels: PropTypes.shape({ - left: PropTypes.string, - bottom: PropTypes.string, - }), -}; - -const layout = { - width: 540, - height: 300, - margin: { - top: 0, - left: 55, - right: 40, - bottom: 40, - }, - font: { - size: 11, - family: "Lato, sans-serif", - }, - colors: { - brand: "#509ee3", - textLight: "#b8bbc3", - textMedium: "#949aab", - }, - barPadding: 0.2, - labelFontWeight: 700, - labelPadding: 12, - maxTickWidth: 100, - areaOpacity: 0.2, - strokeDasharray: "4", -}; - -const CategoricalAreaChart = ({ data, accessors, settings, labels }) => { - const colors = settings?.colors; - const isVertical = data.length > 10; - const xTickWidth = getXTickWidth( - data, - accessors, - layout.maxTickWidth, - layout.font.size, - ); - const xTickHeight = getRotatedXTickHeight(xTickWidth); - const yTickWidth = getYTickWidth(data, accessors, settings, layout.font.size); - const xLabelOffset = xTickHeight + layout.labelPadding + layout.font.size; - const yLabelOffset = yTickWidth + layout.labelPadding; - const xMin = yLabelOffset + layout.font.size * 1.5; - const xMax = layout.width - layout.margin.right; - const yMin = isVertical ? xLabelOffset : layout.margin.bottom; - const yMax = layout.height - yMin; - const innerWidth = xMax - xMin; - const textBaseline = Math.floor(layout.font.size / 2); - const leftLabel = labels?.left; - const bottomLabel = !isVertical ? labels?.bottom : undefined; - const palette = { ...layout.colors, ...colors }; - - const xScale = scaleBand({ - domain: data.map(accessors.x), - range: [xMin, xMax], - round: true, - padding: layout.barPadding, - }); - - const yScale = scaleLinear({ - domain: [0, Math.max(...data.map(accessors.y))], - range: [yMax, 0], - nice: true, - }); - - const getXTickProps = ({ x, y, formattedValue, ...props }) => { - const textWidth = isVertical ? xTickWidth : xScale.bandwidth(); - const truncatedText = truncateText( - formattedValue, - textWidth, - layout.font.size, - ); - const transform = isVertical - ? `rotate(45, ${x} ${y}) translate(-${textBaseline} 0)` - : undefined; - - return { ...props, x, y, transform, children: truncatedText }; - }; - - return ( - <svg width={layout.width} height={layout.height}> - <GridRows - scale={yScale} - left={xMin} - width={innerWidth} - strokeDasharray={layout.strokeDasharray} - /> - <AreaClosed - data={data} - yScale={yScale} - fill={palette.brand} - opacity={layout.areaOpacity} - x={d => xScale(accessors.x(d)) + xScale.bandwidth() / 2} - y={d => yScale(accessors.y(d))} - /> - <AxisLeft - scale={yScale} - left={xMin} - label={leftLabel} - labelOffset={yLabelOffset} - hideTicks - hideAxisLine - labelProps={getLabelProps(layout)} - tickFormat={value => formatNumber(value, settings?.y)} - tickLabelProps={() => getYTickLabelProps(layout)} - /> - <LinePath - data={data} - stroke={palette.brand} - strokeWidth={layout.strokeWidth} - x={d => xScale(accessors.x(d)) + xScale.bandwidth() / 2} - y={d => yScale(accessors.y(d))} - /> - <AxisBottom - scale={xScale} - top={yMax} - label={bottomLabel} - numTicks={data.length} - stroke={palette.textLight} - tickStroke={palette.textLight} - labelProps={getLabelProps(layout)} - tickComponent={props => <Text {...getXTickProps(props)} />} - tickLabelProps={() => getXTickLabelProps(layout, isVertical)} - /> - </svg> - ); -}; - -CategoricalAreaChart.propTypes = propTypes; - -export default CategoricalAreaChart; diff --git a/frontend/src/metabase/static-viz/components/CategoricalAreaChart/index.js b/frontend/src/metabase/static-viz/components/CategoricalAreaChart/index.js deleted file mode 100644 index f57673cb6a5794ded8347e5090413b7be93e9905..0000000000000000000000000000000000000000 --- a/frontend/src/metabase/static-viz/components/CategoricalAreaChart/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./CategoricalAreaChart"; diff --git a/frontend/src/metabase/static-viz/components/CategoricalBarChart/CategoricalBarChart.jsx b/frontend/src/metabase/static-viz/components/CategoricalBarChart/CategoricalBarChart.jsx deleted file mode 100644 index bcd586c60dff2c911d153283aa494d427fd2306a..0000000000000000000000000000000000000000 --- a/frontend/src/metabase/static-viz/components/CategoricalBarChart/CategoricalBarChart.jsx +++ /dev/null @@ -1,160 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { AxisBottom, AxisLeft } from "@visx/axis"; -import { GridRows } from "@visx/grid"; -import { scaleBand, scaleLinear } from "@visx/scale"; -import { Bar } from "@visx/shape"; -import { Text } from "@visx/text"; -import { - getXTickWidth, - getXTickLabelProps, - getYTickLabelProps, - getYTickWidth, - getRotatedXTickHeight, - getLabelProps, -} from "../../lib/axes"; -import { formatNumber } from "../../lib/numbers"; -import { truncateText } from "../../lib/text"; - -const propTypes = { - data: PropTypes.array.isRequired, - accessors: PropTypes.shape({ - x: PropTypes.func.isRequired, - y: PropTypes.func.isRequired, - }).isRequired, - settings: PropTypes.shape({ - x: PropTypes.object, - y: PropTypes.object, - colors: PropTypes.object, - }), - labels: PropTypes.shape({ - left: PropTypes.string, - bottom: PropTypes.string, - }), -}; - -const layout = { - width: 540, - height: 300, - margin: { - top: 0, - left: 55, - right: 40, - bottom: 40, - }, - font: { - size: 11, - family: "Lato, sans-serif", - }, - colors: { - brand: "#509ee3", - textLight: "#b8bbc3", - textMedium: "#949aab", - }, - barPadding: 0.2, - labelFontWeight: 700, - labelPadding: 12, - maxTickWidth: 100, - strokeDasharray: "4", -}; - -const CategoricalBarChart = ({ data, accessors, settings, labels }) => { - const colors = settings?.colors; - const isVertical = data.length > 10; - const xTickWidth = getXTickWidth( - data, - accessors, - layout.maxTickWidth, - layout.font.size, - ); - const xTickHeight = getRotatedXTickHeight(xTickWidth); - const yTickWidth = getYTickWidth(data, accessors, settings, layout.font.size); - const xLabelOffset = xTickHeight + layout.labelPadding + layout.font.size; - const yLabelOffset = yTickWidth + layout.labelPadding; - const xMin = yLabelOffset + layout.font.size * 1.5; - const xMax = layout.width - layout.margin.right; - const yMin = isVertical ? xLabelOffset : layout.margin.bottom; - const yMax = layout.height - yMin; - const innerWidth = xMax - xMin; - const innerHeight = yMax - layout.margin.top; - const textBaseline = Math.floor(layout.font.size / 2); - const leftLabel = labels?.left; - const bottomLabel = !isVertical ? labels?.bottom : undefined; - const palette = { ...layout.colors, ...colors }; - - const xScale = scaleBand({ - domain: data.map(accessors.x), - range: [xMin, xMax], - round: true, - padding: layout.barPadding, - }); - - const yScale = scaleLinear({ - domain: [0, Math.max(...data.map(accessors.y))], - range: [yMax, 0], - nice: true, - }); - - const getBarProps = d => { - const width = xScale.bandwidth(); - const height = innerHeight - yScale(accessors.y(d)); - const x = xScale(accessors.x(d)); - const y = yMax - height; - - return { x, y, width, height, fill: palette.brand }; - }; - - const getXTickProps = ({ x, y, formattedValue, ...props }) => { - const textWidth = isVertical ? xTickWidth : xScale.bandwidth(); - const truncatedText = truncateText( - formattedValue, - textWidth, - layout.font.size, - ); - const transform = isVertical - ? `rotate(45, ${x} ${y}) translate(-${textBaseline} 0)` - : undefined; - - return { ...props, x, y, transform, children: truncatedText }; - }; - - return ( - <svg width={layout.width} height={layout.height}> - <GridRows - scale={yScale} - left={xMin} - width={innerWidth} - strokeDasharray={layout.strokeDasharray} - /> - {data.map((d, index) => ( - <Bar key={index} {...getBarProps(d)} /> - ))} - <AxisLeft - scale={yScale} - left={xMin} - label={leftLabel} - labelOffset={yLabelOffset} - hideTicks - hideAxisLine - labelProps={getLabelProps(layout)} - tickFormat={value => formatNumber(value, settings?.y)} - tickLabelProps={() => getYTickLabelProps(layout)} - /> - <AxisBottom - scale={xScale} - top={yMax} - label={bottomLabel} - numTicks={data.length} - stroke={palette.textLight} - tickStroke={palette.textLight} - labelProps={getLabelProps(layout)} - tickComponent={props => <Text {...getXTickProps(props)} />} - tickLabelProps={() => getXTickLabelProps(layout, isVertical)} - /> - </svg> - ); -}; - -CategoricalBarChart.propTypes = propTypes; - -export default CategoricalBarChart; diff --git a/frontend/src/metabase/static-viz/components/CategoricalBarChart/index.js b/frontend/src/metabase/static-viz/components/CategoricalBarChart/index.js deleted file mode 100644 index 74a0f3cb5bcf04aa23becf9afa26ea01741fbf4b..0000000000000000000000000000000000000000 --- a/frontend/src/metabase/static-viz/components/CategoricalBarChart/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./CategoricalBarChart"; diff --git a/frontend/src/metabase/static-viz/components/CategoricalLineChart/CategoricalLineChart.jsx b/frontend/src/metabase/static-viz/components/CategoricalLineChart/CategoricalLineChart.jsx deleted file mode 100644 index feff35025dd3bd79d1b193f9c31d3f6f4ed5a534..0000000000000000000000000000000000000000 --- a/frontend/src/metabase/static-viz/components/CategoricalLineChart/CategoricalLineChart.jsx +++ /dev/null @@ -1,154 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { AxisBottom, AxisLeft } from "@visx/axis"; -import { GridRows } from "@visx/grid"; -import { scaleBand, scaleLinear } from "@visx/scale"; -import { LinePath } from "@visx/shape"; -import { Text } from "@visx/text"; -import { - getXTickWidth, - getXTickLabelProps, - getYTickLabelProps, - getYTickWidth, - getRotatedXTickHeight, - getLabelProps, -} from "../../lib/axes"; -import { formatNumber } from "../../lib/numbers"; -import { truncateText } from "../../lib/text"; - -const propTypes = { - data: PropTypes.array.isRequired, - accessors: PropTypes.shape({ - x: PropTypes.func.isRequired, - y: PropTypes.func.isRequired, - }).isRequired, - settings: PropTypes.shape({ - x: PropTypes.object, - y: PropTypes.object, - colors: PropTypes.object, - }), - labels: PropTypes.shape({ - left: PropTypes.string, - bottom: PropTypes.string, - }), -}; - -const layout = { - width: 540, - height: 300, - margin: { - top: 0, - left: 55, - right: 40, - bottom: 40, - }, - font: { - size: 11, - family: "Lato, sans-serif", - }, - colors: { - brand: "#509ee3", - textLight: "#b8bbc3", - textMedium: "#949aab", - }, - barPadding: 0.2, - labelFontWeight: 700, - labelPadding: 12, - maxTickWidth: 100, - strokeDasharray: "4", -}; - -const CategoricalLineChart = ({ data, accessors, settings, labels }) => { - const colors = settings?.colors; - const isVertical = data.length > 10; - const xTickWidth = getXTickWidth( - data, - accessors, - layout.maxTickWidth, - layout.font.size, - ); - const xTickHeight = getRotatedXTickHeight(xTickWidth); - const yTickWidth = getYTickWidth(data, accessors, settings, layout.font.size); - const xLabelOffset = xTickHeight + layout.labelPadding + layout.font.size; - const yLabelOffset = yTickWidth + layout.labelPadding; - const xMin = yLabelOffset + layout.font.size * 1.5; - const xMax = layout.width - layout.margin.right; - const yMin = isVertical ? xLabelOffset : layout.margin.bottom; - const yMax = layout.height - yMin; - const innerWidth = xMax - xMin; - const textBaseline = Math.floor(layout.font.size / 2); - const leftLabel = labels?.left; - const bottomLabel = !isVertical ? labels?.bottom : undefined; - const palette = { ...layout.colors, ...colors }; - - const xScale = scaleBand({ - domain: data.map(accessors.x), - range: [xMin, xMax], - round: true, - padding: layout.barPadding, - }); - - const yScale = scaleLinear({ - domain: [0, Math.max(...data.map(accessors.y))], - range: [yMax, 0], - nice: true, - }); - - const getXTickProps = ({ x, y, formattedValue, ...props }) => { - const textWidth = isVertical ? xTickWidth : xScale.bandwidth(); - const truncatedText = truncateText( - formattedValue, - textWidth, - layout.font.size, - ); - const transform = isVertical - ? `rotate(45, ${x} ${y}) translate(-${textBaseline} 0)` - : undefined; - - return { ...props, x, y, transform, children: truncatedText }; - }; - - return ( - <svg width={layout.width} height={layout.height}> - <GridRows - scale={yScale} - left={xMin} - width={innerWidth} - strokeDasharray={layout.strokeDasharray} - /> - <LinePath - data={data} - stroke={palette.brand} - strokeWidth={layout.strokeWidth} - x={d => xScale(accessors.x(d)) + xScale.bandwidth() / 2} - y={d => yScale(accessors.y(d))} - /> - <AxisLeft - scale={yScale} - left={xMin} - label={leftLabel} - labelOffset={yLabelOffset} - hideTicks - hideAxisLine - labelProps={getLabelProps(layout)} - tickFormat={value => formatNumber(value, settings?.y)} - tickLabelProps={() => getYTickLabelProps(layout)} - /> - <AxisBottom - scale={xScale} - top={yMax} - label={bottomLabel} - numTicks={data.length} - stroke={palette.textLight} - tickStroke={palette.textLight} - labelProps={getLabelProps(layout)} - tickComponent={props => <Text {...getXTickProps(props)} />} - tickLabelProps={() => getXTickLabelProps(layout, isVertical)} - /> - </svg> - ); -}; - -CategoricalLineChart.propTypes = propTypes; - -export default CategoricalLineChart; diff --git a/frontend/src/metabase/static-viz/components/CategoricalLineChart/index.js b/frontend/src/metabase/static-viz/components/CategoricalLineChart/index.js deleted file mode 100644 index c6ab45b493ba70c1456a68f583d756115b8d988b..0000000000000000000000000000000000000000 --- a/frontend/src/metabase/static-viz/components/CategoricalLineChart/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./CategoricalLineChart"; diff --git a/frontend/src/metabase/static-viz/components/TimeSeriesAreaChart/TimeSeriesAreaChart.jsx b/frontend/src/metabase/static-viz/components/TimeSeriesAreaChart/TimeSeriesAreaChart.jsx deleted file mode 100644 index dab4072cf1cb0a61f085dcbd74255eb38c0c4184..0000000000000000000000000000000000000000 --- a/frontend/src/metabase/static-viz/components/TimeSeriesAreaChart/TimeSeriesAreaChart.jsx +++ /dev/null @@ -1,139 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { scaleLinear, scaleTime } from "@visx/scale"; -import { GridRows } from "@visx/grid"; -import { AxisBottom, AxisLeft } from "@visx/axis"; -import { AreaClosed, LinePath } from "@visx/shape"; -import { - getLabelProps, - getXTickLabelProps, - getYTickLabelProps, - getYTickWidth, -} from "../../lib/axes"; -import { formatDate } from "../../lib/dates"; -import { formatNumber } from "../../lib/numbers"; -import { sortTimeSeries } from "../../lib/sort"; - -const propTypes = { - data: PropTypes.array.isRequired, - accessors: PropTypes.shape({ - x: PropTypes.func, - y: PropTypes.func, - }).isRequired, - settings: PropTypes.shape({ - x: PropTypes.object, - y: PropTypes.object, - colors: PropTypes.object, - }), - labels: PropTypes.shape({ - left: PropTypes.string, - bottom: PropTypes.string, - }), -}; - -const layout = { - width: 540, - height: 300, - margin: { - top: 0, - left: 55, - right: 40, - bottom: 40, - }, - font: { - size: 11, - family: "Lato, sans-serif", - }, - colors: { - brand: "#509ee3", - brandLight: "#DDECFA", - textLight: "#b8bbc3", - textMedium: "#949aab", - }, - numTicks: 5, - strokeWidth: 2, - labelFontWeight: 700, - labelPadding: 12, - areaOpacity: 0.2, - strokeDasharray: "4", -}; - -const TimeSeriesAreaChart = ({ data, accessors, settings, labels }) => { - data = sortTimeSeries(data); - const colors = settings?.colors; - const yTickWidth = getYTickWidth(data, accessors, settings, layout.font.size); - const yLabelOffset = yTickWidth + layout.labelPadding; - const xMin = yLabelOffset + layout.font.size * 1.5; - const xMax = layout.width - layout.margin.right; - const yMax = layout.height - layout.margin.bottom; - const innerWidth = xMax - xMin; - const leftLabel = labels?.left; - const bottomLabel = labels?.bottom; - const palette = { ...layout.colors, ...colors }; - - const xScale = scaleTime({ - domain: [ - Math.min(...data.map(accessors.x)), - Math.max(...data.map(accessors.x)), - ], - range: [xMin, xMax], - }); - - const yScale = scaleLinear({ - domain: [0, Math.max(...data.map(accessors.y))], - range: [yMax, 0], - nice: true, - }); - - return ( - <svg width={layout.width} height={layout.height}> - <GridRows - scale={yScale} - left={xMin} - width={innerWidth} - strokeDasharray={layout.strokeDasharray} - /> - <AreaClosed - data={data} - yScale={yScale} - fill={palette.brand} - opacity={layout.areaOpacity} - x={d => xScale(accessors.x(d))} - y={d => yScale(accessors.y(d))} - /> - <LinePath - data={data} - stroke={palette.brand} - strokeWidth={layout.strokeWidth} - x={d => xScale(accessors.x(d))} - y={d => yScale(accessors.y(d))} - /> - <AxisLeft - scale={yScale} - left={xMin} - label={leftLabel} - labelOffset={yLabelOffset} - hideTicks - hideAxisLine - labelProps={getLabelProps(layout)} - tickFormat={value => formatNumber(value, settings?.y)} - tickLabelProps={() => getYTickLabelProps(layout)} - /> - <AxisBottom - scale={xScale} - top={yMax} - label={bottomLabel} - numTicks={layout.numTicks} - stroke={palette.textLight} - tickStroke={palette.textLight} - labelProps={getLabelProps(layout)} - tickFormat={value => formatDate(value, settings?.x)} - tickLabelProps={() => getXTickLabelProps(layout)} - /> - </svg> - ); -}; - -TimeSeriesAreaChart.propTypes = propTypes; - -export default TimeSeriesAreaChart; diff --git a/frontend/src/metabase/static-viz/components/TimeSeriesAreaChart/index.js b/frontend/src/metabase/static-viz/components/TimeSeriesAreaChart/index.js deleted file mode 100644 index 97b1d21fca2e79a02f01faa17c661e4c35057c23..0000000000000000000000000000000000000000 --- a/frontend/src/metabase/static-viz/components/TimeSeriesAreaChart/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./TimeSeriesAreaChart"; diff --git a/frontend/src/metabase/static-viz/components/TimeSeriesBarChart/TimeSeriesBarChart.jsx b/frontend/src/metabase/static-viz/components/TimeSeriesBarChart/TimeSeriesBarChart.jsx deleted file mode 100644 index 5ef188346ab458db0908dc227e84de5c33b43caf..0000000000000000000000000000000000000000 --- a/frontend/src/metabase/static-viz/components/TimeSeriesBarChart/TimeSeriesBarChart.jsx +++ /dev/null @@ -1,134 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { AxisBottom, AxisLeft } from "@visx/axis"; -import { GridRows } from "@visx/grid"; -import { scaleBand, scaleLinear } from "@visx/scale"; -import { Bar } from "@visx/shape"; -import { - getLabelProps, - getXTickLabelProps, - getYTickLabelProps, - getYTickWidth, -} from "../../lib/axes"; -import { formatDate } from "../../lib/dates"; -import { formatNumber } from "../../lib/numbers"; -import { sortTimeSeries } from "../../lib/sort"; - -const propTypes = { - data: PropTypes.array.isRequired, - accessors: PropTypes.shape({ - x: PropTypes.func.isRequired, - y: PropTypes.func.isRequired, - }).isRequired, - settings: PropTypes.shape({ - x: PropTypes.object, - y: PropTypes.object, - colors: PropTypes.object, - }), - labels: PropTypes.shape({ - left: PropTypes.string, - bottom: PropTypes.string, - }), -}; - -const layout = { - width: 540, - height: 300, - margin: { - top: 0, - left: 55, - right: 40, - bottom: 40, - }, - font: { - size: 11, - family: "Lato, sans-serif", - }, - colors: { - brand: "#509ee3", - textLight: "#b8bbc3", - textMedium: "#949aab", - }, - numTicks: 5, - barPadding: 0.2, - labelFontWeight: 700, - labelPadding: 12, - strokeDasharray: "4", -}; - -const TimeSeriesBarChart = ({ data, accessors, settings, labels }) => { - data = sortTimeSeries(data); - const colors = settings?.colors; - const yTickWidth = getYTickWidth(data, accessors, settings, layout.font.size); - const yLabelOffset = yTickWidth + layout.labelPadding; - const xMin = yLabelOffset + layout.font.size * 1.5; - const xMax = layout.width - layout.margin.right; - const yMax = layout.height - layout.margin.bottom; - const innerWidth = xMax - xMin; - const innerHeight = yMax - layout.margin.top; - const leftLabel = labels?.left; - const bottomLabel = labels?.bottom; - const palette = { ...layout.colors, ...colors }; - - const xScale = scaleBand({ - domain: data.map(accessors.x), - range: [xMin, xMax], - round: true, - padding: layout.barPadding, - }); - - const yScale = scaleLinear({ - domain: [0, Math.max(...data.map(accessors.y))], - range: [yMax, 0], - nice: true, - }); - - const getBarProps = d => { - const width = xScale.bandwidth(); - const height = innerHeight - yScale(accessors.y(d)); - const x = xScale(accessors.x(d)); - const y = yMax - height; - - return { x, y, width, height, fill: palette.brand }; - }; - - return ( - <svg width={layout.width} height={layout.height}> - <GridRows - scale={yScale} - left={xMin} - width={innerWidth} - strokeDasharray={layout.strokeDasharray} - /> - {data.map((d, index) => ( - <Bar key={index} {...getBarProps(d)} /> - ))} - <AxisLeft - scale={yScale} - left={xMin} - label={leftLabel} - labelOffset={yLabelOffset} - hideTicks - hideAxisLine - labelProps={getLabelProps(layout)} - tickFormat={value => formatNumber(value, settings?.y)} - tickLabelProps={() => getYTickLabelProps(layout)} - /> - <AxisBottom - scale={xScale} - top={yMax} - label={bottomLabel} - numTicks={layout.numTicks} - stroke={palette.textLight} - tickStroke={palette.textLight} - labelProps={getLabelProps(layout)} - tickFormat={value => formatDate(value, settings?.x)} - tickLabelProps={() => getXTickLabelProps(layout)} - /> - </svg> - ); -}; - -TimeSeriesBarChart.propTypes = propTypes; - -export default TimeSeriesBarChart; diff --git a/frontend/src/metabase/static-viz/components/TimeSeriesBarChart/index.js b/frontend/src/metabase/static-viz/components/TimeSeriesBarChart/index.js deleted file mode 100644 index b105a05e679569c5abadb5b391442481800caca6..0000000000000000000000000000000000000000 --- a/frontend/src/metabase/static-viz/components/TimeSeriesBarChart/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./TimeSeriesBarChart"; diff --git a/frontend/src/metabase/static-viz/components/TimeSeriesLineChart/TimeSeriesLineChart.jsx b/frontend/src/metabase/static-viz/components/TimeSeriesLineChart/TimeSeriesLineChart.jsx deleted file mode 100644 index eb3dfdc50afe246ec8bb872a2dec766d001a2316..0000000000000000000000000000000000000000 --- a/frontend/src/metabase/static-viz/components/TimeSeriesLineChart/TimeSeriesLineChart.jsx +++ /dev/null @@ -1,129 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { scaleLinear, scaleTime } from "@visx/scale"; -import { GridRows } from "@visx/grid"; -import { AxisBottom, AxisLeft } from "@visx/axis"; -import { LinePath } from "@visx/shape"; -import { - getXTickLabelProps, - getYTickWidth, - getYTickLabelProps, - getLabelProps, -} from "../../lib/axes"; -import { formatDate } from "../../lib/dates"; -import { formatNumber } from "../../lib/numbers"; -import { sortTimeSeries } from "../../lib/sort"; - -const propTypes = { - data: PropTypes.array.isRequired, - accessors: PropTypes.shape({ - x: PropTypes.func, - y: PropTypes.func, - }).isRequired, - settings: PropTypes.shape({ - x: PropTypes.object, - y: PropTypes.object, - colors: PropTypes.object, - }), - labels: PropTypes.shape({ - left: PropTypes.string, - bottom: PropTypes.string, - }), -}; - -const layout = { - width: 540, - height: 300, - margin: { - top: 0, - left: 55, - right: 40, - bottom: 40, - }, - font: { - size: 11, - family: "Lato, sans-serif", - }, - colors: { - brand: "#509ee3", - textLight: "#b8bbc3", - textMedium: "#949aab", - }, - numTicks: 5, - labelFontWeight: 700, - labelPadding: 12, - strokeWidth: 2, - strokeDasharray: "4", -}; - -const TimeSeriesLineChart = ({ data, accessors, settings, labels }) => { - data = sortTimeSeries(data); - const colors = settings?.colors; - const yTickWidth = getYTickWidth(data, accessors, settings, layout.font.size); - const yLabelOffset = yTickWidth + layout.labelPadding; - const xMin = yLabelOffset + layout.font.size * 1.5; - const xMax = layout.width - layout.margin.right; - const yMax = layout.height - layout.margin.bottom; - const innerWidth = xMax - xMin; - const leftLabel = labels?.left; - const bottomLabel = labels?.bottom; - const palette = { ...layout.colors, ...colors }; - - const xScale = scaleTime({ - domain: [ - Math.min(...data.map(accessors.x)), - Math.max(...data.map(accessors.x)), - ], - range: [xMin, xMax], - }); - - const yScale = scaleLinear({ - domain: [0, Math.max(...data.map(accessors.y))], - range: [yMax, 0], - nice: true, - }); - - return ( - <svg width={layout.width} height={layout.height}> - <GridRows - scale={yScale} - left={xMin} - width={innerWidth} - strokeDasharray={layout.strokeDasharray} - /> - <LinePath - data={data} - stroke={palette.brand} - strokeWidth={layout.strokeWidth} - x={d => xScale(accessors.x(d))} - y={d => yScale(accessors.y(d))} - /> - <AxisLeft - scale={yScale} - left={xMin} - label={leftLabel} - labelOffset={yLabelOffset} - hideTicks - hideAxisLine - labelProps={getLabelProps(layout)} - tickFormat={value => formatNumber(value, settings?.y)} - tickLabelProps={() => getYTickLabelProps(layout)} - /> - <AxisBottom - scale={xScale} - top={yMax} - label={bottomLabel} - numTicks={layout.numTicks} - stroke={palette.textLight} - tickStroke={palette.textLight} - labelProps={getLabelProps(layout)} - tickFormat={value => formatDate(value, settings?.x)} - tickLabelProps={() => getXTickLabelProps(layout)} - /> - </svg> - ); -}; - -TimeSeriesLineChart.propTypes = propTypes; - -export default TimeSeriesLineChart; diff --git a/frontend/src/metabase/static-viz/components/TimeSeriesLineChart/index.js b/frontend/src/metabase/static-viz/components/TimeSeriesLineChart/index.js deleted file mode 100644 index d23115fed8d48444c9258a97b9bb5f2011290cfa..0000000000000000000000000000000000000000 --- a/frontend/src/metabase/static-viz/components/TimeSeriesLineChart/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./TimeSeriesLineChart"; diff --git a/frontend/src/metabase/static-viz/containers/StaticChart/StaticChart.jsx b/frontend/src/metabase/static-viz/containers/StaticChart/StaticChart.jsx index 742d84aae226d14dff52d928c392415df53d4447..8722e4840f1e1f57dac7d5246e90c8a1aa9c8b6e 100644 --- a/frontend/src/metabase/static-viz/containers/StaticChart/StaticChart.jsx +++ b/frontend/src/metabase/static-viz/containers/StaticChart/StaticChart.jsx @@ -1,13 +1,7 @@ import React from "react"; import PropTypes from "prop-types"; -import CategoricalAreaChart from "../../components/CategoricalAreaChart"; -import CategoricalBarChart from "../../components/CategoricalBarChart"; import CategoricalDonutChart from "../../components/CategoricalDonutChart"; -import CategoricalLineChart from "../../components/CategoricalLineChart"; import CategoricalWaterfallChart from "../../components/CategoricalWaterfallChart"; -import TimeSeriesAreaChart from "../../components/TimeSeriesAreaChart"; -import TimeSeriesBarChart from "../../components/TimeSeriesBarChart"; -import TimeSeriesLineChart from "../../components/TimeSeriesLineChart"; import ProgressBar from "../../components/ProgressBar"; import Funnel from "../../components/FunnelChart"; import TimeSeriesWaterfallChart from "../../components/TimeSeriesWaterfallChart"; @@ -15,14 +9,8 @@ import LineAreaBarChart from "../../components/LineAreaBarChart"; const propTypes = { type: PropTypes.oneOf([ - "categorical/area", - "categorical/bar", "categorical/donut", - "categorical/line", "categorical/waterfall", - "timeseries/area", - "timeseries/bar", - "timeseries/line", "timeseries/waterfall", "progress", "combo-chart", @@ -33,22 +21,10 @@ const propTypes = { const StaticChart = ({ type, options }) => { switch (type) { - case "categorical/area": - return <CategoricalAreaChart {...options} />; - case "categorical/bar": - return <CategoricalBarChart {...options} />; case "categorical/donut": return <CategoricalDonutChart {...options} />; - case "categorical/line": - return <CategoricalLineChart {...options} />; case "categorical/waterfall": return <CategoricalWaterfallChart {...options} />; - case "timeseries/area": - return <TimeSeriesAreaChart {...options} />; - case "timeseries/bar": - return <TimeSeriesBarChart {...options} />; - case "timeseries/line": - return <TimeSeriesLineChart {...options} />; case "timeseries/waterfall": return <TimeSeriesWaterfallChart {...options} />; case "progress": diff --git a/frontend/src/metabase/static-viz/containers/StaticChart/StaticChart.unit.spec.js b/frontend/src/metabase/static-viz/containers/StaticChart/StaticChart.unit.spec.js index 93d5dd8c25abcc59cce899fd97613fd8f0e0b7b5..d5aa8326d544e68f52f5e73fc17b2a9d6cd7bcfb 100644 --- a/frontend/src/metabase/static-viz/containers/StaticChart/StaticChart.unit.spec.js +++ b/frontend/src/metabase/static-viz/containers/StaticChart/StaticChart.unit.spec.js @@ -3,108 +3,6 @@ import { render, screen } from "@testing-library/react"; import StaticChart from "./StaticChart"; describe("StaticChart", () => { - it("should render categorical/line", () => { - render( - <StaticChart - type="categorical/line" - options={{ - data: [ - ["Gadget", 20], - ["Widget", 31], - ], - accessors: { - x: row => row[0], - y: row => row[1], - }, - settings: { - y: { - number_style: "currency", - currency: "USD", - currency_style: "symbol", - }, - }, - labels: { - left: "Count", - bottom: "Category", - }, - }} - />, - ); - - screen.getByText("Gadget"); - screen.getByText("Widget"); - screen.getAllByText("Count"); - screen.getAllByText("Category"); - }); - - it("should render categorical/area", () => { - render( - <StaticChart - type="categorical/area" - options={{ - data: [ - ["Gadget", 20], - ["Widget", 31], - ], - accessors: { - x: row => row[0], - y: row => row[1], - }, - settings: { - y: { - number_style: "currency", - currency: "USD", - currency_style: "symbol", - }, - }, - labels: { - left: "Count", - bottom: "Category", - }, - }} - />, - ); - - screen.getByText("Gadget"); - screen.getByText("Widget"); - screen.getAllByText("Count"); - screen.getAllByText("Category"); - }); - - it("should render categorical/bar", () => { - render( - <StaticChart - type="categorical/bar" - options={{ - data: [ - ["Gadget", 20], - ["Widget", 31], - ], - accessors: { - x: row => row[0], - y: row => row[1], - }, - settings: { - y: { - number_style: "currency", - currency: "USD", - currency_style: "symbol", - }, - }, - labels: { - left: "Count", - bottom: "Category", - }, - }} - />, - ); - - screen.getByText("Gadget"); - screen.getByText("Widget"); - screen.getAllByText("Count"); - screen.getAllByText("Category"); - }); - it("should render categorical/donut", () => { render( <StaticChart @@ -136,94 +34,4 @@ describe("StaticChart", () => { screen.getByText("$5,100.00"); screen.getAllByText("TOTAL"); }); - - it("should render timeseries/line", () => { - render( - <StaticChart - type="timeseries/line" - options={{ - data: [ - ["2010-11-07", 20], - ["2020-11-08", 30], - ], - accessors: { - x: row => new Date(row[0]).valueOf(), - y: row => row[1], - }, - settings: { - x: { - date_style: "dddd", - }, - }, - labels: { - left: "Count", - bottom: "Time", - }, - }} - />, - ); - - screen.getAllByText("Count"); - screen.getAllByText("Time"); - }); - - it("should render timeseries/area", () => { - render( - <StaticChart - type="timeseries/area" - options={{ - data: [ - ["2010-11-07", 20], - ["2020-11-08", 30], - ], - accessors: { - x: row => new Date(row[0]).valueOf(), - y: row => row[1], - }, - settings: { - x: { - date_style: "MMM", - }, - }, - labels: { - left: "Count", - bottom: "Time", - }, - }} - />, - ); - - screen.getAllByText("Count"); - screen.getAllByText("Time"); - }); - - it("should render timeseries/bar", () => { - render( - <StaticChart - type="timeseries/bar" - options={{ - data: [ - ["2010-11-07", 20], - ["2020-11-08", 30], - ], - accessors: { - x: row => new Date(row[0]).valueOf(), - y: row => row[1], - }, - settings: { - x: { - date_style: "dddd", - }, - }, - labels: { - left: "Count", - bottom: "Time", - }, - }} - />, - ); - - screen.getAllByText("Count"); - screen.getAllByText("Time"); - }); }); diff --git a/frontend/test/metabase-visual/internal/static-viz.cy.spec.js b/frontend/test/metabase-visual/internal/static-viz.cy.spec.js index b5f372308b5d8ac5167388bc4b77ab57a7287bbc..fa63560ce7b3ec5fab84796c23426fbdfe44089a 100644 --- a/frontend/test/metabase-visual/internal/static-viz.cy.spec.js +++ b/frontend/test/metabase-visual/internal/static-viz.cy.spec.js @@ -9,8 +9,7 @@ describe("visual tests > internal > static-viz", () => { it("basic charts", () => { cy.visit("/_internal/static-viz"); - cy.findByText("Bar chart with timeseries data"); - cy.findByText("Line chart with timeseries data"); + cy.findByText("Waterfall chart with categorical data and total"); cy.findByText("Donut chart with categorical data"); cy.percySnapshot();