diff --git a/jest.config.ts b/jest.config.ts index fb0926a5ee7..74e96aa5a49 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -19,9 +19,9 @@ const config: Config = { '^.+\\.m?[jt]sx?$': 'babel-jest', '^.+\\.svg$': 'jest-transform-stub' }, - setupFilesAfterEnv: ['/packages/testSetup.ts'], + setupFilesAfterEnv: ['/packages/testSetup.ts', 'jest-canvas-mock'], testPathIgnorePatterns: ['/packages/react-integration/'], - transformIgnorePatterns: ['node_modules/victory-*/', '/node_modules/(?!(case-anything)/)'], + transformIgnorePatterns: ['/node_modules/victory-*/', '/node_modules/(?!(chart\\.js|echarts|zrender)).*\\.js$'], coveragePathIgnorePatterns: ['/dist/'], moduleNameMapper: { '\\.(css|less)$': '/packages/react-styles/__mocks__/styleMock.js' diff --git a/packages/react-charts/package.json b/packages/react-charts/package.json index fcf1f96c237..17c913dc2c0 100644 --- a/packages/react-charts/package.json +++ b/packages/react-charts/package.json @@ -7,6 +7,9 @@ "types": "dist/esm/index.d.ts", "typesVersions": { "*": { + "echarts": [ + "dist/esm/echarts/index.d.ts" + ], "victory": [ "dist/esm/victory/index.d.ts" ] @@ -42,7 +45,13 @@ "lodash": "^4.17.21", "tslib": "^2.8.1" }, + "devDependencies": { + "@types/lodash": "^4.17.16", + "fs-extra": "^11.3.0", + "jest-canvas-mock": "^2.5.2" + }, "peerDependencies": { + "echarts": "^5.6.0", "react": "^17 || ^18", "react-dom": "^17 || ^18", "victory-area": "^37.3.6", @@ -64,6 +73,9 @@ "victory-zoom-container": "^37.3.6" }, "peerDependenciesMeta": { + "echarts": { + "optional": true + }, "victory-area": { "optional": true }, @@ -120,9 +132,5 @@ "clean": "rimraf dist echarts victory", "build:single:packages": "node ../../scripts/build-single-packages.mjs --config single-packages.config.json", "subpaths": "node ../../scripts/exportSubpaths.mjs --config subpaths.config.json" - }, - "devDependencies": { - "@types/lodash": "^4.17.16", - "fs-extra": "^11.3.0" } } diff --git a/packages/react-charts/single-packages.config.json b/packages/react-charts/single-packages.config.json index 4a9651bb17d..8b418fd2095 100644 --- a/packages/react-charts/single-packages.config.json +++ b/packages/react-charts/single-packages.config.json @@ -1,4 +1,4 @@ { "packageName": "@patternfly/react-charts", - "exclude": ["dist/esm/deprecated/index.js", "dist/esm/next/index.js"] + "exclude": ["dist/esm/deprecated/index.js"] } diff --git a/packages/react-charts/src/echarts/__mocks__/echarts.ts b/packages/react-charts/src/echarts/__mocks__/echarts.ts new file mode 100644 index 00000000000..52c5c5c2c22 --- /dev/null +++ b/packages/react-charts/src/echarts/__mocks__/echarts.ts @@ -0,0 +1,6 @@ +const echarts: any = jest.createMockFromModule('echarts'); +echarts.init = jest.fn(() => ({ + setOption: jest.fn(), + dispose: jest.fn() +})); +module.exports = echarts; diff --git a/packages/react-charts/src/echarts/components/charts/Line/Line.tsx b/packages/react-charts/src/echarts/components/charts/Line/Line.tsx new file mode 100644 index 00000000000..903984d73ce --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Line/Line.tsx @@ -0,0 +1,22 @@ +import defaultsDeep from 'lodash/defaultsDeep'; + +import { ThemeDefinition } from '../../themes/Theme'; + +/** + * Returns series properties for Line chart + * + * @param serie + * @param theme + * @param isSkeleton + * @private + */ +export const getLineSeries = (serie: any, theme: ThemeDefinition, isSkeleton: boolean) => { + const defaults = { + emphasis: { + ...(isSkeleton ? { disabled: true } : { focus: 'adjacency' }) + }, + showSymbol: false, + type: 'line' + }; + return defaultsDeep(serie, defaults); +}; diff --git a/packages/react-charts/src/echarts/components/charts/Line/__tests__/Line.test.tsx b/packages/react-charts/src/echarts/components/charts/Line/__tests__/Line.test.tsx new file mode 100644 index 00000000000..a9a7a21cd43 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Line/__tests__/Line.test.tsx @@ -0,0 +1,91 @@ +import React from 'react'; +import { setupJestCanvasMock } from 'jest-canvas-mock'; +import { render, screen } from '@testing-library/react'; +import { PatternflyECharts } from '../../PatternflyECharts'; + +import * as echarts from 'echarts/core'; +import { LineChart } from 'echarts/charts'; +import { GridComponent, TitleComponent, TooltipComponent } from 'echarts/components'; +import { SVGRenderer } from 'echarts/renderers'; + +// Register required components +echarts.use([GridComponent, LineChart, SVGRenderer, TitleComponent, TooltipComponent]); + +beforeEach(() => { + jest.resetAllMocks(); + jest.mock('echarts'); + setupJestCanvasMock(); +}); + +const props: any = { + height: 400, + id: 'line-chart', + option: { + xAxis: { + type: 'category', + data: ['2015', '2016', '2017', '2018'] + }, + yAxis: { + axisLabel: { + formatter: (value) => (value !== 0 ? `${value}` : '') + }, + splitNumber: 3, + type: 'value' + }, + series: [ + { + data: [1, 2, 5, 3], + name: 'Cats', + type: 'line' + }, + { + data: [2, 1, 7, 4], + name: 'Dogs', + lineStyle: { + type: 'dashed' + }, + type: 'line' + }, + { + data: [3, 4, 9, 5], + name: 'Birds', + type: 'line' + }, + { + data: [3, 3, 8, 7], + name: 'Mice', + type: 'line' + } + ], + title: { + text: 'This is a Line chart' + } + }, + width: 800 +}; + +// Remove dynamic _echarts_instance_ ID +const removeInstanceID = (fragment) => { + fragment.getElementById('line-chart').removeAttribute('_echarts_instance_'); + return fragment; +}; + +test('renders component', () => { + const { asFragment } = render(); + expect(removeInstanceID(asFragment())).toMatchSnapshot(); +}); + +test('renders title', async () => { + render(); + + const title = await screen.findByText(props.option.title.text); + expect(title).toMatchSnapshot(); +}); + +test('renders height and width', async () => { + const { asFragment } = render(); + + const svg = asFragment().querySelector('svg'); + expect(svg).toHaveAttribute('height', `${props.height}`); + expect(svg).toHaveAttribute('width', `${props.width}`); +}); diff --git a/packages/react-charts/src/echarts/components/charts/Line/__tests__/__snapshots__/Line.test.tsx.snap b/packages/react-charts/src/echarts/components/charts/Line/__tests__/__snapshots__/Line.test.tsx.snap new file mode 100644 index 00000000000..b30833d6d9b --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Line/__tests__/__snapshots__/Line.test.tsx.snap @@ -0,0 +1,268 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders component 1`] = ` + +
+
+ + + + + + + + + + + + + + + + + + + + + 2015 + + + 2016 + + + 2017 + + + 2018 + + + + + + + + + + + + + + + + This is a Line chart + + + + + + + + + + + + + + + + + +
+
+
+ +`; + +exports[`renders title 1`] = ` + + This is a Line chart + +`; diff --git a/packages/react-charts/src/echarts/components/charts/Line/examples/next/Basic.tsx b/packages/react-charts/src/echarts/components/charts/Line/examples/next/Basic.tsx new file mode 100644 index 00000000000..51227f62be6 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Line/examples/next/Basic.tsx @@ -0,0 +1,70 @@ +import React from 'react'; +import { PatternflyECharts } from '@patternfly/react-charts/echarts'; + +import * as echarts from 'echarts/core'; +import { LineChart } from 'echarts/charts'; +import { GridComponent, TitleComponent, TooltipComponent } from 'echarts/components'; +import { SVGRenderer } from 'echarts/renderers'; + +// Register required components +echarts.use([GridComponent, LineChart, SVGRenderer, TitleComponent, TooltipComponent]); + +// eslint-disable-next-line patternfly-react/no-anonymous-functions +export const Basic: React.FunctionComponent = () => ( + (value !== 0 ? `${value}` : '') + }, + splitNumber: 3, + type: 'value' + }, + series: [ + { + data: [1, 2, 5, 3], + name: 'Cats', + type: 'line' + }, + { + data: [2, 1, 7, 4], + name: 'Dogs', + lineStyle: { + type: 'dashed' + }, + type: 'line' + }, + { + data: [3, 4, 9, 5], + name: 'Birds', + type: 'line' + }, + { + data: [3, 3, 8, 7], + name: 'Mice', + type: 'line' + } + ], + title: { + left: 'center', + text: 'This is a Line chart' + } + }} + width={825} + /> +); diff --git a/packages/react-charts/src/echarts/components/charts/Line/examples/next/PatternflyECharts b/packages/react-charts/src/echarts/components/charts/Line/examples/next/PatternflyECharts new file mode 120000 index 00000000000..05507e76db0 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Line/examples/next/PatternflyECharts @@ -0,0 +1 @@ +../../../PatternflyECharts \ No newline at end of file diff --git a/packages/react-charts/src/echarts/components/charts/Line/examples/next/Responsive.tsx b/packages/react-charts/src/echarts/components/charts/Line/examples/next/Responsive.tsx new file mode 100644 index 00000000000..2fb0e91df52 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Line/examples/next/Responsive.tsx @@ -0,0 +1,89 @@ +import React from 'react'; +import { PatternflyECharts, ThemeColor } from '@patternfly/react-charts/echarts'; +import { getResizeObserver } from '@patternfly/react-core'; + +import * as echarts from 'echarts/core'; +import { LineChart } from 'echarts/charts'; +import { GridComponent, TitleComponent, TooltipComponent } from 'echarts/components'; +import { SVGRenderer } from 'echarts/renderers'; + +// Register required components +echarts.use([GridComponent, LineChart, SVGRenderer, TitleComponent, TooltipComponent]); + +// eslint-disable-next-line patternfly-react/no-anonymous-functions +export const Responsive: React.FunctionComponent = () => { + const containerRef = React.useRef(); + const [width, setWidth] = React.useState(0); + + React.useEffect(() => { + const handleResize = () => { + if (containerRef.current && containerRef.current.clientWidth) { + setWidth(containerRef.current.clientWidth); + } + }; + let observer = () => {}; + observer = getResizeObserver(containerRef.current, handleResize); + + return () => { + observer(); + }; + }, [containerRef, width]); + + return ( +
+ (value !== 0 ? `${value}` : '') + }, + splitNumber: 3, + type: 'value' + }, + series: [ + { + data: [1, 2, 5, 3], + name: 'Cats', + type: 'line' + }, + { + data: [2, 1, 7, 4], + name: 'Dogs', + lineStyle: { + type: 'dashed' + }, + type: 'line' + }, + { + data: [3, 4, 9, 5], + name: 'Birds', + type: 'line' + }, + { + data: [3, 3, 8, 7], + name: 'Mice', + type: 'line' + } + ], + title: { + left: 'center', + text: 'This is a Line chart', + type: 'line' + } + }} + themeColor={ThemeColor.green} + width={width} + /> +
+ ); +}; diff --git a/packages/react-charts/src/echarts/components/charts/Line/examples/next/Skeleton.tsx b/packages/react-charts/src/echarts/components/charts/Line/examples/next/Skeleton.tsx new file mode 100644 index 00000000000..16542560833 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Line/examples/next/Skeleton.tsx @@ -0,0 +1,76 @@ +import React from 'react'; +import { PatternflyECharts, ThemeColor } from '@patternfly/react-charts/echarts'; +import { Switch } from '@patternfly/react-core'; + +import * as echarts from 'echarts/core'; +import { LineChart } from 'echarts/charts'; +import { GridComponent, TitleComponent, TooltipComponent } from 'echarts/components'; +import { SVGRenderer } from 'echarts/renderers'; + +// Register required components +echarts.use([GridComponent, LineChart, SVGRenderer, TitleComponent, TooltipComponent]); + +// eslint-disable-next-line patternfly-react/no-anonymous-functions +export const Skeleton: React.FunctionComponent = () => { + const [isChecked, setIsChecked] = React.useState(true); + + const handleChange = (_event: React.FormEvent, checked: boolean) => { + setIsChecked(checked); + }; + + return ( + <> + + + + ); +}; diff --git a/packages/react-charts/src/echarts/components/charts/Line/examples/next/Theme.tsx b/packages/react-charts/src/echarts/components/charts/Line/examples/next/Theme.tsx new file mode 100644 index 00000000000..3cb4b5ed45b --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Line/examples/next/Theme.tsx @@ -0,0 +1,94 @@ +/* eslint-disable camelcase */ +import React from 'react'; +import { getComputedStyleValue, getCustomTheme, PatternflyECharts, ThemeColor } from '@patternfly/react-charts/echarts'; + +import * as echarts from 'echarts/core'; +import { LineChart } from 'echarts/charts'; +import { GridComponent, TitleComponent, TooltipComponent } from 'echarts/components'; +import { SVGRenderer } from 'echarts/renderers'; + +import chart_color_blue_300 from '@patternfly/react-tokens/dist/esm/chart_color_blue_300'; +import chart_color_green_300 from '@patternfly/react-tokens/dist/esm/chart_color_green_300'; +import chart_color_purple_300 from '@patternfly/react-tokens/dist/esm/chart_color_purple_300'; +import chart_color_teal_300 from '@patternfly/react-tokens/dist/esm/chart_color_teal_300'; +import chart_color_yellow_300 from '@patternfly/react-tokens/dist/esm/chart_color_yellow_300'; + +// Register required components +echarts.use([GridComponent, LineChart, SVGRenderer, TitleComponent, TooltipComponent]); + +// eslint-disable-next-line patternfly-react/no-anonymous-functions +export const Theme: React.FunctionComponent = () => { + const myCustomTheme = getCustomTheme(ThemeColor.default, { + color: [ + getComputedStyleValue(chart_color_purple_300), + getComputedStyleValue(chart_color_blue_300), + getComputedStyleValue(chart_color_green_300), + getComputedStyleValue(chart_color_teal_300), + getComputedStyleValue(chart_color_yellow_300) + ] + }); + + return ( + (value !== 0 ? `${value}` : '') + }, + splitNumber: 3, + type: 'value' + }, + series: [ + { + data: [1, 2, 5, 3], + name: 'Cats', + symbol: 'rect', + type: 'line' + }, + { + data: [2, 1, 7, 4], + name: 'Dogs', + lineStyle: { + type: 'dashed' + }, + symbol: 'arrow', + type: 'line' + }, + { + data: [3, 4, 9, 5], + name: 'Birds', + symbol: 'circle', + type: 'line' + }, + { + data: [3, 3, 8, 7], + name: 'Mice', + symbol: 'emptyCircle', + type: 'line' + } + ], + title: { + left: 'center', + text: 'This is a Line chart' + } + }} + theme={myCustomTheme} + width={825} + /> + ); +}; diff --git a/packages/react-charts/src/echarts/components/charts/Line/examples/next/index.md b/packages/react-charts/src/echarts/components/charts/Line/examples/next/index.md new file mode 100644 index 00000000000..e5215b03ec5 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Line/examples/next/index.md @@ -0,0 +1,52 @@ +--- +id: Line chart +section: charts +propComponents: [ + 'PatternflyEChartș', + 'EChartsOptionPropș', + 'TooltipOptionPropș' +] +beta: true +--- + +import * as echarts from 'echarts'; +import { LineChart } from 'echarts/charts'; +import { GridComponent, TitleComponent, ToolboxComponent, TooltipComponent } from 'echarts/components'; +import { SVGRenderer } from 'echarts/renderers'; +import { getComputedStyleValue, getCustomTheme, PatternflyECharts, ThemeColor } from '@patternfly/react-charts/echarts'; + +import chart_color_blue_300 from '@patternfly/react-tokens/dist/esm/chart_color_blue_300'; +import chart_color_green_300 from '@patternfly/react-tokens/dist/esm/chart_color_green_300'; +import chart_color_purple_300 from '@patternfly/react-tokens/dist/esm/chart_color_purple_300'; +import chart_color_teal_300 from '@patternfly/react-tokens/dist/esm/chart_color_teal_300'; +import chart_color_yellow_300 from '@patternfly/react-tokens/dist/esm/chart_color_yellow_300'; + +## Introduction +Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! + +The examples below are based on the [Apache ECharts](https://echarts.apache.org/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. + +## Examples +### Basic with right aligned legend + +```ts file="./Basic.tsx" + +``` + +### Green with responsive container and bottom aligned legend +```ts file="./Responsive.tsx" + +``` + +### Custom theme +This demonstrates how to create a color scale via a custom theme, which may be applied to multiple charts. + +```ts file="./Theme.tsx" + +``` + +### Skeleton + +```ts file="./Skeleton.tsx" + +``` diff --git a/packages/react-charts/src/echarts/components/charts/Line/index.ts b/packages/react-charts/src/echarts/components/charts/Line/index.ts new file mode 100644 index 00000000000..34a969a3d62 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Line/index.ts @@ -0,0 +1 @@ +export * from './Line'; diff --git a/packages/react-charts/src/echarts/components/charts/PatternflyECharts/PatternflyECharts.tsx b/packages/react-charts/src/echarts/components/charts/PatternflyECharts/PatternflyECharts.tsx new file mode 100644 index 00000000000..fce4a4094f0 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/PatternflyECharts/PatternflyECharts.tsx @@ -0,0 +1,245 @@ +import * as React from 'react'; +import { useCallback, useReducer, useRef } from 'react'; +import cloneDeep from 'lodash/cloneDeep'; +import defaultsDeep from 'lodash/defaultsDeep'; + +import * as echarts from 'echarts/core'; +import { EChartsInitOpts } from 'echarts/types/dist/echarts'; +import { EChartsOption } from 'echarts/types/dist/option'; +import { TooltipOption } from 'echarts/types/dist/shared'; + +import { getLineSeries } from '../Line'; +import { getSankeySeries } from '../Sankey'; + +import { ThemeDefinition } from '../../themes/Theme'; +import { getMutationObserver } from '../../utils/observe'; +import { getClassName } from '../../utils/styles'; +import { getTheme } from '../../utils/theme'; +import { getLegendTooltip, getSankeyTooltip } from '../../utils/tooltip'; +import { ThemeColor } from '../../themes/ThemeColor'; + +/** + * See https://echarts.apache.org/en/option.html#tooltip + */ +export interface TooltipOptionProps extends TooltipOption { + /** + * The destination label shown in the tooltip -- for Sankey only + */ + destinationLabel?: string; + /** + * The source label shown in the tooltip -- for Sankey only + */ + sourceLabel?: string; +} + +/** + * See https://echarts.apache.org/en/option.html + */ +export interface EChartsOptionProps extends EChartsOption { + /** + * Tooltip component -- see https://echarts.apache.org/en/option.html#tooltip + */ + tooltip?: TooltipOptionProps | TooltipOptionProps[]; +} + +/** + * This component is based on the Apache ECharts chart library. It provides additional functionality, custom + * components, and theming for PatternFly. This provides a collection of React based components you can use to build + * PatternFly patterns with consistent markup, styling, and behavior. + * + * See https://echarts.apache.org/en/api.html#echarts + * + * @beta + */ +export interface PatternflyEChartsProps { + /** + * The className prop specifies a class name that will be applied to outermost element + */ + className?: string; + /** + * Specify height explicitly, in pixels + */ + height?: number; + /** + * The id prop specifies an ID that will be applied to outermost element. + */ + id?: string; + /** + * Flag indicating to use the legend tooltip (default). This may be overridden by the `option.tooltip` property. + */ + isLegendTooltip?: boolean; + /** + * Flag indicating to use the SVG renderer (default). This may be overridden by the `opts.renderer` property. + */ + isSvgRenderer?: boolean; + /** + * This creates a Mutation Observer to watch the given DOM selector. + * + * When the pf-v6-theme-dark selector is added or removed, this component will be notified to update its computed + * theme styles. However, if the dark theme is not updated dynamically (e.g., via a toggle), there is no need to add + * this Mutation Observer. + * + * Note: Don't provide ".pf-v6-theme-dark" as the node selector as it won't exist in the page for light theme. + * The underlying querySelectorAll() function needs to find the element the dark theme selector will be added to. + * + * See https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Locating_DOM_elements_using_selectors + * + * @propType string + * @example + * @example + * @example + */ + nodeSelector?: string; + /** + * ECharts uses this object to configure its properties; for example, series, title, and tooltip + * + * See https://echarts.apache.org/en/option.html + */ + option?: EChartsOptionProps; + /** + * Optional chart configuration + * + * See https://echarts.apache.org/en/api.html#echarts.init + */ + opts?: EChartsInitOpts; + /** + * The theme prop specifies a theme to use for determining styles and layout properties for a component. Any styles or + * props defined in theme may be overwritten by props specified on the component instance. + * + * See https://echarts.apache.org/handbook/en/concepts/style/#theme + */ + theme?: ThemeDefinition; + /** + * Specifies the theme color. Valid values are 'blue', 'green', 'multi', etc. + * + * Note: Not compatible with theme prop + * + * @example themeColor={ChartThemeColor.blue} + */ + themeColor?: string; + /** + * Specify width explicitly, in pixels + */ + width?: number; +} +export const PatternflyECharts: React.FunctionComponent = ({ + className, + height, + id, + isLegendTooltip = true, + isSvgRenderer = true, + nodeSelector, + option, + opts, + theme, + themeColor, + width, + ...rest +}: PatternflyEChartsProps) => { + const containerRef = useRef(); + const echart = useRef(); + const [update, forceUpdate] = useReducer((x) => x + 1, 0); + + const getSize = () => ({ + ...(height && { height: `${height}px` }), + ...(width && { width: `${width}px` }) + }); + + const getTooltip = useCallback( + (series: any[], tooltipType: string, isSkeleton: boolean, echart) => { + // Skeleton should not have any interactions + if (isSkeleton) { + return undefined; + } else if (tooltipType === 'sankey') { + return getSankeyTooltip(series, option); + } else if (tooltipType === 'legend') { + return getLegendTooltip(series, option, echart); + } + return option.tooltip; + }, + [option] + ); + + const getSeries = useCallback( + (chartTheme: ThemeDefinition, isSkeleton: boolean) => { + let tooltipType; + const series: any = cloneDeep(option?.series); + const newSeries = []; + + series.map((serie: any) => { + switch (serie.type) { + case 'sankey': + tooltipType = 'sankey'; // Overrides legend tooltip + newSeries.push(getSankeySeries(serie, chartTheme, isSkeleton)); + break; + case 'line': + if (!tooltipType) { + tooltipType = 'legend'; + } + newSeries.push(getLineSeries(serie, chartTheme, isSkeleton)); + break; + default: + newSeries.push(serie); + break; + } + }); + return { series, tooltipType }; + }, + [option?.series] + ); + + React.useEffect(() => { + const isSkeleton = themeColor === ThemeColor.skeleton; + const chartTheme = theme ? theme : getTheme(themeColor); + const renderer = isSvgRenderer ? 'svg' : 'canvas'; + + echart.current = echarts.init( + containerRef.current, + chartTheme, + defaultsDeep(opts, { height, renderer, width }) // height and width are necessary here for unit tests + ); + + const { series, tooltipType } = getSeries(chartTheme, isSkeleton); + echart.current?.setOption({ + ...option, + ...(isLegendTooltip && { tooltip: getTooltip(series, tooltipType, isSkeleton, echart.current) }), + series + }); + + return () => { + echart.current?.dispose(); + }; + }, [ + containerRef, + getSeries, + getTooltip, + height, + isLegendTooltip, + isSvgRenderer, + option, + opts, + theme, + themeColor, + update, + width + ]); + + // Resize observer + React.useEffect(() => { + echart.current?.resize(); + }, [height, width]); + + // Dark theme observer + React.useEffect(() => { + let observer = () => {}; + observer = getMutationObserver(nodeSelector, () => { + forceUpdate(); + }); + return () => { + observer(); + }; + }, [nodeSelector]); + + return
; +}; +PatternflyECharts.displayName = 'PatternflyECharts'; diff --git a/packages/react-charts/src/echarts/components/charts/PatternflyECharts/PatternflyEChartsDoc.tsx b/packages/react-charts/src/echarts/components/charts/PatternflyECharts/PatternflyEChartsDoc.tsx new file mode 100644 index 00000000000..011ba1b3e5a --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/PatternflyECharts/PatternflyEChartsDoc.tsx @@ -0,0 +1,405 @@ +import { EChartsInitOpts } from 'echarts/types/dist/echarts'; +import { EChartsOption } from 'echarts/types/dist/option'; +import { + AngleAxisOption, + AriaOption, + AxisPointerOption, + BrushOption, + CalendarOption, + DatasetOption, + DataZoomComponentOption, + GeoOption, + GraphicComponentLooseOption, + GridOption, + LegendComponentOption, + ParallelCoordinateSystemOption, + PolarOption, + RadarOption, + RadiusAxisOption, + SingleAxisOption, + TimelineOption, + TitleOption, + ToolboxComponentOption, + VisualMapComponentOption, + XAXisOption, + YAXisOption +} from 'echarts/types/dist/shared'; + +// The properties below exist to document properties in the example docs. Some EChart types are not exported and too +// complex to recreate here. Attempting to duplicate each EChart type would be error-prone. For documentation purposes, +// we shall define simple types here, which avoids having to duplicate EChart's complex object types. + +/** + * See https://echarts.apache.org/en/option.html#tooltip + */ +export interface TooltipOptionPropș { + /** + * Whether to show tooltip content all the time -- see https://echarts.apache.org/en/option.html#tooltip.alwaysShowContent + */ + alwaysShowContent?: boolean; + /** + * Which DOM element to append the tooltip to -- see https://echarts.apache.org/en/option.html#tooltip.appendTo + */ + appendTo?: string | HTMLElement | Function; + /** + * Configuration item for axisPointer -- see https://echarts.apache.org/en/option.html#tooltip.axisPointer + */ + axisPointer?: Object; + /** + * The background color of tooltip's floating layer -- see https://echarts.apache.org/en/option.html#tooltip.backgroundColor + */ + backgroundColor?: string; + /** + * The border color of tooltip's floating layer -- see https://echarts.apache.org/en/option.html#tooltip.borderColor + */ + borderColor?: string; + /** + * The border width of tooltip's floating layer -- see https://echarts.apache.org/en/option.html#tooltip.borderWidth + */ + borderWidth?: number; + /** + * Specify the classes for the tooltip root DOM -- see https://echarts.apache.org/en/option.html#tooltip.className + */ + className?: string; + /** + * Whether confine tooltip content in the view rect of chart instance -- see https://echarts.apache.org/en/option.html#tooltip.confine + */ + confine?: boolean; + /** + * The destination label shown in the tooltip -- for Sankey only + */ + destinationLabel?: string; + /** + * Whether mouse is allowed to enter the floating layer of tooltip -- see https://echarts.apache.org/en/option.html#tooltip.enterable + */ + enterable?: boolean; + /** + * Extra CSS style for floating layer -- see https://echarts.apache.org/en/option.html#tooltip.extraCssText + */ + extraCssText?: string; + /** + * The content formatter of tooltip's floating layer -- see https://echarts.apache.org/en/option.html#tooltip.formatter + */ + formatter?: string | Function; + /** + * Delay time for hiding tooltip -- see https://echarts.apache.org/en/option.html#tooltip.hideDelay + */ + hideDelay?: number; + /** + * Tooltip order for multiple series -- see https://echarts.apache.org/en/option.html#tooltip.order + */ + order?: string; + /** + * The floating layer of tooltip space around content -- see https://echarts.apache.org/en/option.html#tooltip.padding + */ + padding?: number; + /** + * The position of the tooltip's floating layer -- see https://echarts.apache.org/en/option.html#tooltip.position + */ + position?: string[]; + /** + * Render mode for tooltip -- see https://echarts.apache.org/en/option.html#tooltip.renderMode + */ + renderMode?: string; + /** + * Whether to show the tooltip component -- see https://echarts.apache.org/en/option.html#tooltip.show + */ + show?: boolean; + /** + * Whether to show the tooltip floating layer -- see https://echarts.apache.org/en/option.html#tooltip.showContent + */ + showContent?: boolean; + /** + * Delay time for showing tooltip -- see https://echarts.apache.org/en/option.html#tooltip.showDelay + */ + showDelay?: number; + /** + * The source label shown in the tooltip -- for Sankey only + */ + sourceLabel?: string; + /** + * The text style of tooltip's floating layer -- see https://echarts.apache.org/en/option.html#tooltip.textStyle + */ + textStyle?: Object; + /** + * The transition duration of tooltip's animation, in seconds -- see https://echarts.apache.org/en/option.html#tooltip.transitionDuration + */ + transitionDuration?: number; + /** + * Type of triggering -- see https://echarts.apache.org/en/option.html#tooltip.trigger + */ + trigger?: string; + /** + * Conditions to trigger tooltip -- see https://echarts.apache.org/en/option.html#tooltip.triggerOn + */ + triggerOn?: 'mousemove' | 'click' | 'mousemove|click' | 'none'; + /** + * Callback function for formatting the value section in tooltip -- see https://echarts.apache.org/en/option.html#tooltip.valueFormatter + */ + valueFormatter?: string; +} + +/** + * See https://echarts.apache.org/en/option.html + */ +export interface EChartsOptionPropș { + /** + * The angle axis in Polar Coordinate -- see https://echarts.apache.org/en/option.html#angleAxis + */ + angleAxis?: AngleAxisOption | AngleAxisOption[]; + /** + * Whether to enable animation -- see https://echarts.apache.org/en/option.html#animation + */ + animation?: boolean; + /** + * Delay before updating the first animation -- see https://echarts.apache.org/en/option.html#animationDelay + */ + animationDelay?: number; + /** + * Delay before updating animation -- see https://echarts.apache.org/en/option.html#animationDelayUpdate + */ + animationDelayUpdate?: number; + /** + * Duration of the first animation -- see https://echarts.apache.org/en/option.html#animationDuration + */ + animationDuration?: number; + /** + * Time for animation to complete -- see https://echarts.apache.org/en/option.html#animationDurationUpdate + */ + animationDurationUpdate?: number; + /** + * Easing method used for the first animation -- see https://echarts.apache.org/en/option.html#animationEasing + */ + animationEasing?: string; + /** + * Easing method used for animation -- see https://echarts.apache.org/en/option.html#animationEasingUpdate + */ + animationEasingUpdate?: string; + /** + * Whether to set graphic number threshold to animation -- see https://echarts.apache.org/en/option.html#animationThreshold + */ + animationThreshold?: number; + /** + * The W3C has developed the WAI-ARIA, the Accessible Rich Internet Applications Suite, which is dedicated to making web content and web applications accessible -- see https://echarts.apache.org/en/option.html#aria + */ + aria?: AriaOption; + /** + * This is the global configurations of axisPointer -- see https://echarts.apache.org/en/option.html#axisPointer + */ + axisPointer?: AxisPointerOption | AxisPointerOption[]; + /** + * Background color - see https://echarts.apache.org/en/option.html#backgroundColor + */ + backgroundColor?: string; + /** + * Sets the type of compositing operation to apply when drawing a new shape -- see https://echarts.apache.org/en/option.html#blendMode + */ + blendMode?: string; + /** + * Brush is an area-selecting component -- see https://echarts.apache.org/en/option.html#brush + */ + brush?: BrushOption | BrushOption[]; + /** + * Calendar coordinates -- see https://echarts.apache.org/en/option.html#calendar + */ + calendar?: CalendarOption | CalendarOption[]; + /** + * The color list of palette -- see https://echarts.apache.org/en/option.html#color + */ + color?: string[]; + /** + * Dataset brings convenience in data management separated with styles and enables data reuse by different series -- see https://echarts.apache.org/en/option.html#dataset + */ + dataset?: DatasetOption | DatasetOption[]; + /** + * Data zoom component is used for zooming a specific area -- see https://echarts.apache.org/en/option.html#dataZoom + */ + dataZoom?: DataZoomComponentOption | DataZoomComponentOption[]; + /** + * ECharts will automatically detect it via backgroundColor by default and adjust the text color accordingly - see https://echarts.apache.org/en/option.html#darkMode + */ + darkMode?: boolean | 'auto'; + /** + * ECharts will automatically detect it via backgroundColor by default and adjust the text color accordingly -- see https://echarts.apache.org/en/option.html#darkMode + */ + /** + * Geographic coordinate system component -- see https://echarts.apache.org/en/option.html#geo + */ + geo?: GeoOption | GeoOption[]; + /** + * Graphic component enables creating graphic elements in ECharts -- see https://echarts.apache.org/en/option.html#graphic + */ + graphic?: GraphicComponentLooseOption | GraphicComponentLooseOption[]; + /** + * Drawing grid in rectangular coordinate -- see https://echarts.apache.org/en/option.html#grid + */ + grid?: GridOption | GridOption[]; + /** + * When the number of element of the whole chart is larger than hoverLayerThreshold, a separate hover layer is used to render hovered elements -- see https://echarts.apache.org/en/option.html#hoverLayerThreshold + */ + hoverLayerThreshold?: number; + /** + * Legend component -- see https://echarts.apache.org/en/option.html#legend + */ + legend?: LegendComponentOption | LegendComponentOption[]; + /** + * See Responsive Mobile-End for details -- see https://echarts.apache.org/en/option.html#media + */ + media?: Object; + /** + * Option array used in timeline -- see https://echarts.apache.org/en/option.html#options + */ + options?: EChartsOption[]; + /** + * Parallel Coordinates is a common way of visualizing high-dimensional geometry and analyzing multivariate data -- see https://echarts.apache.org/en/option.html#parallel + */ + parallel?: ParallelCoordinateSystemOption | ParallelCoordinateSystemOption[]; + /** + * This component is the coordinate axis for parallel coordinate -- see https://echarts.apache.org/en/option.html#parallelAxis + * + * @type ParallelAxisOption | ParallelAxisOption[] + */ + parallelAxis?: Object; + /** + * Polar coordinate can be used in scatter and line chart -- see https://echarts.apache.org/en/option.html#polar + */ + polar?: PolarOption | PolarOption[]; + /** + * Coordinate for radar charts -- see https://echarts.apache.org/en/option.html#radar + */ + radar?: RadarOption | RadarOption[]; + /** + * Radial axis of polar coordinate -- see https://echarts.apache.org/en/option.html#radiusAxis + */ + radiusAxis?: RadiusAxisOption | RadiusAxisOption[]; + /** + * Properties for various chart types -- see https://echarts.apache.org/en/option.html#series + * + * @type SeriesOption | SeriesOption[] + */ + series?: Object; + /** + * An axis with a single dimension -- see https://echarts.apache.org/en/option.html#singleAxis + */ + singleAxis?: SingleAxisOption | SingleAxisOption[]; + /** + * Animation configurations of state switchment -- see https://echarts.apache.org/en/option.html#stateAnimation + */ + stateAnimation?: Object; + /** + * Timeline component -- see https://echarts.apache.org/en/option.html#timeline + * + * @type TimelineOption | SliderTimelineOption + */ + timeline?: TimelineOption | Object; + /** + * Title component, including main title and subtitle -- see https://echarts.apache.org/en/option.html#title + */ + title?: TitleOption | TitleOption[]; + /** + * A group of utility tools -- see https://echarts.apache.org/en/option.html#toolbox + */ + toolbox?: ToolboxComponentOption | ToolboxComponentOption[]; + /** + * Tooltip component -- see https://echarts.apache.org/en/option.html#tooltip + */ + tooltip?: TooltipOptionPropș | TooltipOptionPropș[]; + /** + * Whether to use UTC in display -- see https://echarts.apache.org/en/option.html#useUTC + */ + useUTC?: boolean; + /** + * Visual map is a type of component for visual encoding -- see https://echarts.apache.org/en/option.html#visualMap + */ + visualMap?: VisualMapComponentOption | VisualMapComponentOption[]; + /** + * The x-axis in cartesian(rectangular) coordinate -- see https://echarts.apache.org/en/option.html#xAxis + */ + xAxis?: XAXisOption | XAXisOption[]; + /** + * The y-axis in cartesian(rectangular) coordinate -- see https://echarts.apache.org/en/option.html#yAxis + */ + yAxis?: YAXisOption | YAXisOption[]; +} + +/** + * This component is based on the Apache ECharts chart library. It provides additional functionality, custom + * components, and theming for PatternFly. This provides a collection of React based components you can use to build + * PatternFly patterns with consistent markup, styling, and behavior. + * + * See https://echarts.apache.org/en/api.html#echarts + * @beta + */ +export interface PatternflyEChartș { + /** + * The className prop specifies a class name that will be applied to outermost element + */ + className?: string; + /** + * Specify height explicitly, in pixels + */ + height?: number; + /** + * The id prop specifies an ID that will be applied to outermost element. + */ + id?: string; + /** + * Flag indicating to use the legend tooltip (default). This may be overridden by the `option.tooltip` property. + */ + isLegendTooltip?: boolean; + /** + * Flag indicating to use the SVG renderer (default). This may be overridden by the `opts.renderer` property. + */ + isSvgRenderer?: boolean; + /** + * This creates a Mutation Observer to watch the given DOM selector. + * + * When the pf-v6-theme-dark selector is added or removed, this component will be notified to update its computed + * theme styles. However, if the dark theme is not updated dynamically (e.g., via a toggle), there is no need to add + * this Mutation Observer. + * + * Note: Don't provide ".pf-v6-theme-dark" as the node selector as it won't exist in the page for light theme. + * The underlying querySelectorAll() function needs to find the element the dark theme selector will be added to. + * + * See https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Locating_DOM_elements_using_selectors + * + * @propType string + * @example + * @example + * @example + */ + nodeSelector?: string; + /** + * ECharts uses this object to configure its properties; for example, series, title, and tooltip + * + * See https://echarts.apache.org/en/option.html + */ + option?: EChartsOptionPropș; + /** + * Optional chart configuration + * + * See https://echarts.apache.org/en/api.html#echarts.init + */ + opts?: EChartsInitOpts; + /** + * The theme prop specifies a theme to use for determining styles and layout properties for a component. Any styles or + * props defined in theme may be overwritten by props specified on the component instance. + * + * See https://echarts.apache.org/handbook/en/concepts/style/#theme + * + * @type ThemeDefinition + */ + theme?: any; + /** + * Specifies the theme color. Valid values are 'blue', 'green', 'multi', etc. + * + * Note: Not compatible with theme prop + * + * @example themeColor={ChartThemeColor.blue} + */ + themeColor?: string; + /** + * Specify width explicitly, in pixels + */ + width?: number; +} diff --git a/packages/react-charts/src/echarts/components/charts/PatternflyECharts/index.ts b/packages/react-charts/src/echarts/components/charts/PatternflyECharts/index.ts new file mode 100644 index 00000000000..beb5fc5c3e0 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/PatternflyECharts/index.ts @@ -0,0 +1 @@ +export * from './PatternflyECharts'; diff --git a/packages/react-charts/src/echarts/components/charts/Sankey/Sankey.tsx b/packages/react-charts/src/echarts/components/charts/Sankey/Sankey.tsx new file mode 100644 index 00000000000..a4b38c24597 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Sankey/Sankey.tsx @@ -0,0 +1,32 @@ +import defaultsDeep from 'lodash/defaultsDeep'; + +import { ThemeDefinition } from '../../themes/Theme'; + +/** + * Returns series properties for Sankey chart + * + * @param serie + * @param theme + * @param isSkeleton + * @private + */ +export const getSankeySeries = (serie: any, theme: ThemeDefinition, isSkeleton: boolean) => { + const defaults = { + data: serie.data.map((datum: any, index: number) => ({ + itemStyle: { + color: theme?.color[index % theme?.color.length] + } + })), + ...(isSkeleton ? { draggable: false } : {}), + emphasis: { + ...(isSkeleton ? { disabled: true } : { focus: 'adjacency' }) + }, + layout: 'none', + lineStyle: { + color: 'source', + opacity: 0.6 + }, + type: 'sankey' + }; + return defaultsDeep(serie, defaults); +}; diff --git a/packages/react-charts/src/echarts/components/charts/Sankey/__tests__/Sankey.test.tsx b/packages/react-charts/src/echarts/components/charts/Sankey/__tests__/Sankey.test.tsx new file mode 100644 index 00000000000..000f0eb79c4 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Sankey/__tests__/Sankey.test.tsx @@ -0,0 +1,110 @@ +import React from 'react'; +import { setupJestCanvasMock } from 'jest-canvas-mock'; +import { render, screen } from '@testing-library/react'; +import { PatternflyECharts } from '../../PatternflyECharts'; + +import * as echarts from 'echarts/core'; +import { SankeyChart } from 'echarts/charts'; +import { TitleComponent, TooltipComponent } from 'echarts/components'; +import { SVGRenderer } from 'echarts/renderers'; + +// Register required components +echarts.use([SankeyChart, SVGRenderer, TitleComponent, TooltipComponent]); + +beforeEach(() => { + jest.resetAllMocks(); + jest.mock('echarts'); + setupJestCanvasMock(); +}); + +const data = [ + { + name: 'a' + }, + { + name: 'b' + }, + { + name: 'a1' + }, + { + name: 'a2' + }, + { + name: 'b1' + }, + { + name: 'c' + } +]; + +const links = [ + { + source: 'a', + target: 'a1', + value: 5 + }, + { + source: 'a', + target: 'a2', + value: 3 + }, + { + source: 'b', + target: 'b1', + value: 8 + }, + { + source: 'a', + target: 'b1', + value: 3 + }, + { + source: 'b1', + target: 'a1', + value: 1 + }, + { + source: 'b1', + target: 'c', + value: 2 + } +]; + +const props: any = { + height: 400, + id: 'sankey-chart', + option: { + series: [{ data, links, type: 'sankey' }], + title: { + text: 'This is a Sankey chart' + } + }, + width: 800 +}; + +// Remove dynamic _echarts_instance_ ID +const removeInstanceID = (fragment) => { + fragment.getElementById('sankey-chart').removeAttribute('_echarts_instance_'); + return fragment; +}; + +test('renders component', () => { + const { asFragment } = render(); + expect(removeInstanceID(asFragment())).toMatchSnapshot(); +}); + +test('renders title', async () => { + render(); + + const title = await screen.findByText(props.option.title.text); + expect(title).toMatchSnapshot(); +}); + +test('renders height and width', async () => { + const { asFragment } = render(); + + const svg = asFragment().querySelector('svg'); + expect(svg).toHaveAttribute('height', `${props.height}`); + expect(svg).toHaveAttribute('width', `${props.width}`); +}); diff --git a/packages/react-charts/src/echarts/components/charts/Sankey/__tests__/__snapshots__/Sankey.test.tsx.snap b/packages/react-charts/src/echarts/components/charts/Sankey/__tests__/__snapshots__/Sankey.test.tsx.snap new file mode 100644 index 00000000000..eb1878ee39f --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Sankey/__tests__/__snapshots__/Sankey.test.tsx.snap @@ -0,0 +1,218 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders component 1`] = ` + +
+
+ + + + + + + + + + + + + + + + + + a + + + b + + + a1 + + + a2 + + + b1 + + + c + + + + + This is a Sankey chart + + + + + + + + +
+
+
+ +`; + +exports[`renders title 1`] = ` + + This is a Sankey chart + +`; diff --git a/packages/react-charts/src/echarts/components/charts/Sankey/examples/Basic.tsx b/packages/react-charts/src/echarts/components/charts/Sankey/examples/Basic.tsx new file mode 100644 index 00000000000..932f29a20b2 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Sankey/examples/Basic.tsx @@ -0,0 +1,87 @@ +import React from 'react'; +import { PatternflyECharts } from '@patternfly/react-charts/echarts'; + +import * as echarts from 'echarts/core'; +import { SankeyChart } from 'echarts/charts'; +import { TitleComponent, TooltipComponent } from 'echarts/components'; +import { SVGRenderer } from 'echarts/renderers'; + +// Register required components +echarts.use([SankeyChart, SVGRenderer, TitleComponent, TooltipComponent]); + +export const Basic: React.FunctionComponent = () => { + const data = [ + { + name: 'a' + }, + { + name: 'b' + }, + { + name: 'a1' + }, + { + name: 'a2' + }, + { + name: 'b1' + }, + { + name: 'c' + } + ]; + + const links = [ + { + source: 'a', + target: 'a1', + value: 5 + }, + { + source: 'a', + target: 'a2', + value: 3 + }, + { + source: 'b', + target: 'b1', + value: 8 + }, + { + source: 'a', + target: 'b1', + value: 3 + }, + { + source: 'b1', + target: 'a1', + value: 1 + }, + { + source: 'b1', + target: 'c', + value: 2 + } + ]; + + return ( + `${value} GiB` + } + }} + width={825} + /> + ); +}; diff --git a/packages/react-charts/src/echarts/components/charts/Sankey/examples/Responsive.tsx b/packages/react-charts/src/echarts/components/charts/Sankey/examples/Responsive.tsx new file mode 100644 index 00000000000..91d89f09b30 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Sankey/examples/Responsive.tsx @@ -0,0 +1,108 @@ +import React from 'react'; +import { PatternflyECharts, ThemeColor } from '@patternfly/react-charts/echarts'; +import { getResizeObserver } from '@patternfly/react-core'; + +import * as echarts from 'echarts/core'; +import { SankeyChart } from 'echarts/charts'; +import { TitleComponent, TooltipComponent } from 'echarts/components'; +import { SVGRenderer } from 'echarts/renderers'; + +// Register required components +echarts.use([SankeyChart, SVGRenderer, TitleComponent, TooltipComponent]); + +export const Responsive: React.FunctionComponent = () => { + const data = [ + { + name: 'a' + }, + { + name: 'b' + }, + { + name: 'a1' + }, + { + name: 'a2' + }, + { + name: 'b1' + }, + { + name: 'c' + } + ]; + + const links = [ + { + source: 'a', + target: 'a1', + value: 5 + }, + { + source: 'a', + target: 'a2', + value: 3 + }, + { + source: 'b', + target: 'b1', + value: 8 + }, + { + source: 'a', + target: 'b1', + value: 3 + }, + { + source: 'b1', + target: 'a1', + value: 1 + }, + { + source: 'b1', + target: 'c', + value: 2 + } + ]; + + const containerRef = React.useRef(); + const [width, setWidth] = React.useState(0); + + React.useEffect(() => { + const handleResize = () => { + if (containerRef.current && containerRef.current.clientWidth) { + setWidth(containerRef.current.clientWidth); + } + }; + let observer = () => {}; + observer = getResizeObserver(containerRef.current, handleResize); + + return () => { + observer(); + }; + }, [containerRef, width]); + + return ( +
+ `${value} GiB` + } + }} + themeColor={ThemeColor.multiUnordered} + width={width} + /> +
+ ); +}; diff --git a/packages/react-charts/src/echarts/components/charts/Sankey/examples/Skeleton.tsx b/packages/react-charts/src/echarts/components/charts/Sankey/examples/Skeleton.tsx new file mode 100644 index 00000000000..ca63a2b57e6 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Sankey/examples/Skeleton.tsx @@ -0,0 +1,98 @@ +import React from 'react'; +import { PatternflyECharts, ThemeColor } from '@patternfly/react-charts/echarts'; +import { Switch } from '@patternfly/react-core'; + +import * as echarts from 'echarts/core'; +import { SankeyChart } from 'echarts/charts'; +import { TitleComponent, TooltipComponent } from 'echarts/components'; +import { SVGRenderer } from 'echarts/renderers'; + +// Register required components +echarts.use([SankeyChart, SVGRenderer, TitleComponent, TooltipComponent]); + +export const Skeleton: React.FunctionComponent = () => { + const [isChecked, setIsChecked] = React.useState(true); + + const handleChange = (_event: React.FormEvent, checked: boolean) => { + setIsChecked(checked); + }; + + const data = [ + { + name: 'a' + }, + { + name: 'b' + }, + { + name: 'a1' + }, + { + name: 'a2' + }, + { + name: 'b1' + }, + { + name: 'c' + } + ]; + + const links = [ + { + source: 'a', + target: 'a1', + value: 5 + }, + { + source: 'a', + target: 'a2', + value: 3 + }, + { + source: 'b', + target: 'b1', + value: 8 + }, + { + source: 'a', + target: 'b1', + value: 3 + }, + { + source: 'b1', + target: 'a1', + value: 1 + }, + { + source: 'b1', + target: 'c', + value: 2 + } + ]; + + return ( + <> + + `${value} GiB` + } + }} + themeColor={isChecked ? ThemeColor.skeleton : ThemeColor.green} + width={825} + /> + + ); +}; diff --git a/packages/react-charts/src/echarts/components/charts/Sankey/examples/Theme.tsx b/packages/react-charts/src/echarts/components/charts/Sankey/examples/Theme.tsx new file mode 100644 index 00000000000..f839a3dddf2 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Sankey/examples/Theme.tsx @@ -0,0 +1,105 @@ +/* eslint-disable camelcase */ +import React from 'react'; +import { getComputedStyleValue, getCustomTheme, PatternflyECharts, ThemeColor } from '@patternfly/react-charts/echarts'; + +import * as echarts from 'echarts/core'; +import { SankeyChart } from 'echarts/charts'; +import { TitleComponent, TooltipComponent } from 'echarts/components'; +import { SVGRenderer } from 'echarts/renderers'; + +import chart_color_blue_300 from '@patternfly/react-tokens/dist/esm/chart_color_blue_300'; +import chart_color_green_300 from '@patternfly/react-tokens/dist/esm/chart_color_green_300'; +import chart_color_purple_300 from '@patternfly/react-tokens/dist/esm/chart_color_purple_300'; +import chart_color_teal_300 from '@patternfly/react-tokens/dist/esm/chart_color_teal_300'; +import chart_color_yellow_300 from '@patternfly/react-tokens/dist/esm/chart_color_yellow_300'; + +// Register required components +echarts.use([SankeyChart, SVGRenderer, TitleComponent, TooltipComponent]); + +export const Theme: React.FunctionComponent = () => { + const data = [ + { + name: 'a' + }, + { + name: 'b' + }, + { + name: 'a1' + }, + { + name: 'a2' + }, + { + name: 'b1' + }, + { + name: 'c' + } + ]; + + const links = [ + { + source: 'a', + target: 'a1', + value: 5 + }, + { + source: 'a', + target: 'a2', + value: 3 + }, + { + source: 'b', + target: 'b1', + value: 8 + }, + { + source: 'a', + target: 'b1', + value: 3 + }, + { + source: 'b1', + target: 'a1', + value: 1 + }, + { + source: 'b1', + target: 'c', + value: 2 + } + ]; + + const myCustomTheme = getCustomTheme(ThemeColor.default, { + color: [ + getComputedStyleValue(chart_color_purple_300), + getComputedStyleValue(chart_color_blue_300), + getComputedStyleValue(chart_color_green_300), + getComputedStyleValue(chart_color_teal_300), + getComputedStyleValue(chart_color_yellow_300) + ] + }); + + return ( + `${value} GiB` + } + }} + theme={myCustomTheme} + width={825} + /> + ); +}; diff --git a/packages/react-charts/src/echarts/components/charts/Sankey/examples/Toolbox.tsx b/packages/react-charts/src/echarts/components/charts/Sankey/examples/Toolbox.tsx new file mode 100644 index 00000000000..d279be1c048 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Sankey/examples/Toolbox.tsx @@ -0,0 +1,117 @@ +import React from 'react'; +import { PatternflyECharts, ThemeColor } from '@patternfly/react-charts/echarts'; +import { getResizeObserver } from '@patternfly/react-core'; + +import * as echarts from 'echarts/core'; +import { SankeyChart } from 'echarts/charts'; +import { TitleComponent, ToolboxComponent, TooltipComponent } from 'echarts/components'; +import { SVGRenderer } from 'echarts/renderers'; + +// Register required components +echarts.use([SankeyChart, SVGRenderer, TitleComponent, ToolboxComponent, TooltipComponent]); + +export const Toolbox: React.FunctionComponent = () => { + const data = [ + { + name: 'a' + }, + { + name: 'b' + }, + { + name: 'a1' + }, + { + name: 'a2' + }, + { + name: 'b1' + }, + { + name: 'c' + } + ]; + + const links = [ + { + source: 'a', + target: 'a1', + value: 5 + }, + { + source: 'a', + target: 'a2', + value: 3 + }, + { + source: 'b', + target: 'b1', + value: 8 + }, + { + source: 'a', + target: 'b1', + value: 3 + }, + { + source: 'b1', + target: 'a1', + value: 1 + }, + { + source: 'b1', + target: 'c', + value: 2 + } + ]; + + // let observer = () => {}; + const containerRef = React.useRef(); + const [width, setWidth] = React.useState(0); + + React.useEffect(() => { + const handleResize = () => { + if (containerRef.current && containerRef.current.clientWidth) { + setWidth(containerRef.current.clientWidth); + } + }; + let observer = () => {}; + observer = getResizeObserver(containerRef.current, handleResize); + + return () => { + observer(); + }; + }, [containerRef, width]); + + return ( +
+ `${value} GiB` + } + }} + themeColor={ThemeColor.teal} + width={width} + /> +
+ ); +}; diff --git a/packages/react-charts/src/echarts/components/charts/Sankey/examples/index.md b/packages/react-charts/src/echarts/components/charts/Sankey/examples/index.md new file mode 100644 index 00000000000..efbecd64018 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Sankey/examples/index.md @@ -0,0 +1,61 @@ +--- +id: Sankey +section: charts +propComponents: [ + 'PatternflyEChartș', + 'EChartsOptionPropș', + 'TooltipOptionPropș' +] +beta: true +--- + +import * as echarts from 'echarts'; +import { SankeyChart } from 'echarts/charts'; +import { TitleComponent, ToolboxComponent, TooltipComponent } from 'echarts/components'; +import { SVGRenderer } from 'echarts/renderers'; +import { getComputedStyleValue, getCustomTheme, PatternflyECharts, ThemeColor } from '@patternfly/react-charts/echarts'; + +import chart_color_blue_300 from '@patternfly/react-tokens/dist/esm/chart_color_blue_300'; +import chart_color_green_300 from '@patternfly/react-tokens/dist/esm/chart_color_green_300'; +import chart_color_purple_300 from '@patternfly/react-tokens/dist/esm/chart_color_purple_300'; +import chart_color_teal_300 from '@patternfly/react-tokens/dist/esm/chart_color_teal_300'; +import chart_color_yellow_300 from '@patternfly/react-tokens/dist/esm/chart_color_yellow_300'; + +## Introduction +Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! + +The examples below are based on the [Apache ECharts](https://echarts.apache.org/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. + +## Examples +### Basic + +```ts file="./Basic.tsx" + +``` + +### Multi-color (unordered) with responsive container + +```ts file="./Responsive.tsx" + +``` + +### Teal color with responsive container and toolbox + +This demonstrates how to import `ToolboxComponent` for use with ECharts + +```ts file="./Toolbox.tsx" + +``` + +### Custom theme +This demonstrates how to create a color scale via a custom theme, which may be applied to multiple charts. + +```ts file="./Theme.tsx" + +``` + +### Skeleton + +```ts file="./Skeleton.tsx" + +``` diff --git a/packages/react-charts/src/echarts/components/charts/Sankey/index.ts b/packages/react-charts/src/echarts/components/charts/Sankey/index.ts new file mode 100644 index 00000000000..4bb44aaee6a --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/Sankey/index.ts @@ -0,0 +1 @@ +export * from './Sankey'; diff --git a/packages/react-charts/src/echarts/components/charts/index.ts b/packages/react-charts/src/echarts/components/charts/index.ts new file mode 100644 index 00000000000..beb5fc5c3e0 --- /dev/null +++ b/packages/react-charts/src/echarts/components/charts/index.ts @@ -0,0 +1 @@ +export * from './PatternflyECharts'; diff --git a/packages/react-charts/src/echarts/components/index.ts b/packages/react-charts/src/echarts/components/index.ts new file mode 100644 index 00000000000..5246eb0e1ef --- /dev/null +++ b/packages/react-charts/src/echarts/components/index.ts @@ -0,0 +1,4 @@ +export * from './charts'; +export * from './themes/ThemeColor'; +export { getCustomTheme, getTheme } from './utils/theme'; +export { getComputedStyleValue } from './utils/styles'; diff --git a/packages/react-charts/src/echarts/components/themes/Theme.ts b/packages/react-charts/src/echarts/components/themes/Theme.ts new file mode 100644 index 00000000000..f5d7b82809a --- /dev/null +++ b/packages/react-charts/src/echarts/components/themes/Theme.ts @@ -0,0 +1,14 @@ +import { ThemeOption } from 'echarts/types/src/util/types'; + +/** + * Theme definition interface + * + * @public + */ +export interface ThemeDefinitionInterface extends ThemeOption {} + +/** + * Theme definition type + * @public + */ +export type ThemeDefinition = ThemeDefinitionInterface; diff --git a/packages/react-charts/src/echarts/components/themes/ThemeColor.ts b/packages/react-charts/src/echarts/components/themes/ThemeColor.ts new file mode 100644 index 00000000000..15cb8830f2b --- /dev/null +++ b/packages/react-charts/src/echarts/components/themes/ThemeColor.ts @@ -0,0 +1,55 @@ +interface ThemeColorInterface { + blue: string; + teal: string; + default: string; + yellow: string; + gray: string; + green: string; + multi: string; + multiOrdered: string; + multiUnordered: string; + orange: string; + purple: string; + skeleton: string; +} + +/** + * The color family to be applied to a theme. For example, 'blue' represents an ordered list of colors + * (i.e., a color scale) composed of the blue color family defined by PatternFly core. + * + * For example, the 'blue' color scale looks like: + * + * chart_color_blue_100 + * chart_color_blue_200 + * chart_color_blue_300 + * chart_color_blue_400 + * chart_color_blue_500 + * + * In this case, the chart_color_blue_100 value would be applied to the first data point in a chart. + * The chart_color_blue_200 value would be applied to the second data point in a chart. And so on... + * + * If legend data is provided to a chart, those colors would be synced with the legend as well. + * + * The 'multiOrdered' color family is intended for ordered charts; donut, pie, bar, & stack + * The 'multiUnordered' color family is intended for unordered charts; area & line + * The 'multi' defaults to the 'multiOrdered' color family + * + * Note: These values are not intended to be applied directly as a component's fill style. For example, "multi" would + * not be a valid fill color. Please use chart variables from PatternFly core (e.g., via the react-charts package) + * + * @public + */ +export const ThemeColor: ThemeColorInterface = { + blue: 'blue', + teal: 'teal', + default: 'blue', + yellow: 'yellow', + gray: 'gray', + green: 'green', + multi: 'multi', + multiOrdered: 'multi-ordered', + multiUnordered: 'multi-unordered', + orange: 'orange', + purple: 'purple', + skeleton: 'skeleton' +}; diff --git a/packages/react-charts/src/echarts/components/themes/base-theme.ts b/packages/react-charts/src/echarts/components/themes/base-theme.ts new file mode 100644 index 00000000000..855c1af07d8 --- /dev/null +++ b/packages/react-charts/src/echarts/components/themes/base-theme.ts @@ -0,0 +1,252 @@ +/* eslint-disable camelcase */ +import chart_echarts_bar_item_style_BarBorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_bar_item_style_BarBorderColor'; +import chart_echarts_boxplot_item_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_boxplot_item_style_BorderWidth'; +import chart_echarts_candlestick_item_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_candlestick_item_style_BorderWidth'; +import chart_echarts_datazoom_HandleSize from '@patternfly/react-tokens/dist/esm/chart_echarts_datazoom_HandleSize'; +import chart_echarts_funnel_item_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_funnel_item_style_BorderWidth'; +import chart_echarts_gauge_item_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_gauge_item_style_BorderWidth'; +import chart_echarts_geo_emphasis_item_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_gauge_item_style_BorderWidth'; +import chart_echarts_geo_item_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_gauge_item_style_BorderWidth'; +import chart_echarts_global_axis_BoundaryGap from '@patternfly/react-tokens/dist/esm/chart_echarts_global_axis_BoundaryGap'; +import chart_echarts_global_axis_axis_label_Show from '@patternfly/react-tokens/dist/esm/chart_echarts_global_axis_axis_label_Show'; +import chart_echarts_global_axis_axis_line_Show from '@patternfly/react-tokens/dist/esm/chart_echarts_global_axis_axis_line_Show'; +import chart_echarts_global_axis_axis_tick_Show from '@patternfly/react-tokens/dist/esm/chart_echarts_global_axis_axis_tick_Show'; +import chart_echarts_global_axis_split_area_Show from '@patternfly/react-tokens/dist/esm/chart_echarts_global_axis_split_area_Show'; +import chart_echarts_global_axis_split_line_Show from '@patternfly/react-tokens/dist/esm/chart_echarts_global_axis_split_line_Show'; +import chart_echarts_graph_item_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_graph_item_style_BorderWidth'; +import chart_echarts_graph_line_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_graph_line_style_BorderWidth'; +import chart_echarts_graph_Smooth from '@patternfly/react-tokens/dist/esm/chart_echarts_graph_Smooth'; +import chart_echarts_graph_Symbol from '@patternfly/react-tokens/dist/esm/chart_echarts_graph_Symbol'; +import chart_echarts_graph_SymbolSize from '@patternfly/react-tokens/dist/esm/chart_echarts_graph_SymbolSize'; +import chart_echarts_line_item_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_line_item_style_BorderWidth'; +import chart_echarts_line_line_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_line_line_style_BorderWidth'; +import chart_echarts_line_Smooth from '@patternfly/react-tokens/dist/esm/chart_echarts_line_Smooth'; +import chart_echarts_line_Symbol from '@patternfly/react-tokens/dist/esm/chart_echarts_line_Symbol'; +import chart_echarts_line_SymbolSize from '@patternfly/react-tokens/dist/esm/chart_echarts_line_SymbolSize'; +import chart_echarts_map_emphasis_item_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_map_emphasis_item_style_BorderWidth'; +import chart_echarts_map_item_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_map_item_style_BorderWidth'; +import chart_echarts_parallel_item_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_parallel_item_style_BorderWidth'; +import chart_echarts_pie_item_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_pie_item_style_BorderWidth'; +import chart_echarts_radar_item_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_radar_item_style_BorderWidth'; +import chart_echarts_radar_line_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_radar_line_style_BorderWidth'; +import chart_echarts_radar_Smooth from '@patternfly/react-tokens/dist/esm/chart_echarts_radar_Smooth'; +import chart_echarts_radar_Symbol from '@patternfly/react-tokens/dist/esm/chart_echarts_radar_Symbol'; +import chart_echarts_radar_SymbolSize from '@patternfly/react-tokens/dist/esm/chart_echarts_radar_SymbolSize'; +import chart_echarts_sankey_item_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_sankey_item_style_BorderWidth'; +import chart_echarts_scatter_item_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_scatter_item_style_BorderWidth'; +import chart_echarts_timeline_control_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_timeline_control_style_BorderWidth'; +import chart_echarts_timeline_emphasis_control_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_timeline_emphasis_control_style_BorderWidth'; +import chart_echarts_timeline_item_style_BorderWidth from '@patternfly/react-tokens/dist/esm/chart_echarts_timeline_item_style_BorderWidth'; +import chart_echarts_timeline_line_style_Width from '@patternfly/react-tokens/dist/esm/chart_echarts_timeline_line_style_Width'; +import chart_echarts_tooltip_axis_pointer_cross_style_Width from '@patternfly/react-tokens/dist/esm/chart_echarts_tooltip_axis_pointer_cross_style_Width'; +import chart_echarts_tooltip_axis_pointer_line_style_Width from '@patternfly/react-tokens/dist/esm/chart_echarts_tooltip_axis_pointer_line_style_Width'; +import chart_global_FontFamily from '@patternfly/react-tokens/dist/esm/chart_global_FontFamily'; +import chart_global_FontSize_sm from '@patternfly/react-tokens/dist/esm/chart_global_FontSize_sm'; + +import { ThemeDefinition } from './Theme'; +import { getComputedStyleValue } from '../utils/styles'; + +/** + * Base theme containing EChart properties only + * @private + */ +export const BaseTheme = (): ThemeDefinition => { + const textProps = { + fontFamily: chart_global_FontFamily.var, + fontSize: chart_global_FontSize_sm.value + }; + + const axisProps = { + boundaryGap: getComputedStyleValue(chart_echarts_global_axis_BoundaryGap), + axisLabel: { + ...textProps, + show: getComputedStyleValue(chart_echarts_global_axis_axis_label_Show) + }, + axisLine: { + lineStyle: {}, + show: getComputedStyleValue(chart_echarts_global_axis_axis_line_Show) + }, + axisTick: { + lineStyle: {}, + show: getComputedStyleValue(chart_echarts_global_axis_axis_tick_Show) + }, + splitArea: { + areaStyle: {}, + show: getComputedStyleValue(chart_echarts_global_axis_split_area_Show) + }, + splitLine: { + lineStyle: {}, + show: getComputedStyleValue(chart_echarts_global_axis_split_line_Show) // Grid + } + }; + + return { + bar: { + itemStyle: { + barBorderWidth: getComputedStyleValue(chart_echarts_bar_item_style_BarBorderWidth) + } + }, + boxplot: { + itemStyle: { + borderWidth: getComputedStyleValue(chart_echarts_boxplot_item_style_BorderWidth) + } + }, + candlestick: { + itemStyle: { + borderWidth: getComputedStyleValue(chart_echarts_candlestick_item_style_BorderWidth) + } + }, + categoryAxis: { ...axisProps }, + dataZoom: { + handleSize: getComputedStyleValue(chart_echarts_datazoom_HandleSize), + textStyle: { ...textProps } + }, + funnel: { + itemStyle: { + borderWidth: getComputedStyleValue(chart_echarts_funnel_item_style_BorderWidth) + } + }, + gauge: { + itemStyle: { + borderWidth: getComputedStyleValue(chart_echarts_gauge_item_style_BorderWidth) + } + }, + geo: { + emphasis: { + itemStyle: { + borderWidth: getComputedStyleValue(chart_echarts_geo_emphasis_item_style_BorderWidth) + }, + label: {} + }, + itemStyle: { + borderWidth: getComputedStyleValue(chart_echarts_geo_item_style_BorderWidth) + }, + label: {} + }, + graph: { + itemStyle: { + borderWidth: getComputedStyleValue(chart_echarts_graph_item_style_BorderWidth) + }, + label: {}, + lineStyle: { + width: getComputedStyleValue(chart_echarts_graph_line_style_BorderWidth) + }, + smooth: getComputedStyleValue(chart_echarts_graph_Smooth), + symbolSize: getComputedStyleValue(chart_echarts_graph_SymbolSize), + symbol: getComputedStyleValue(chart_echarts_graph_Symbol) + }, + label: { + ...textProps + }, + legend: { + textStyle: { ...textProps } + }, + line: { + itemStyle: { + borderWidth: getComputedStyleValue(chart_echarts_line_item_style_BorderWidth) + }, + lineStyle: { + width: getComputedStyleValue(chart_echarts_line_line_style_BorderWidth) + }, + smooth: getComputedStyleValue(chart_echarts_line_Smooth), + symbolSize: getComputedStyleValue(chart_echarts_line_SymbolSize), + symbol: getComputedStyleValue(chart_echarts_line_Symbol) + }, + logAxis: { ...axisProps }, + map: { + emphasis: { + itemStyle: { + borderWidth: getComputedStyleValue(chart_echarts_map_emphasis_item_style_BorderWidth) + }, + label: {} + }, + itemStyle: { + borderWidth: getComputedStyleValue(chart_echarts_map_item_style_BorderWidth) + }, + label: { + label: {} + } + }, + markPoint: { + emphasis: { + label: {} + }, + label: {} + }, + parallel: { + itemStyle: { + borderWidth: getComputedStyleValue(chart_echarts_parallel_item_style_BorderWidth) + } + }, + pie: { + itemStyle: { + borderWidth: getComputedStyleValue(chart_echarts_pie_item_style_BorderWidth) + } + }, + radar: { + itemStyle: { + borderWidth: getComputedStyleValue(chart_echarts_radar_item_style_BorderWidth) + }, + lineStyle: { + width: getComputedStyleValue(chart_echarts_radar_line_style_BorderWidth) + }, + smooth: getComputedStyleValue(chart_echarts_radar_Smooth), + symbolSize: getComputedStyleValue(chart_echarts_radar_SymbolSize), + symbol: getComputedStyleValue(chart_echarts_radar_Symbol) + }, + sankey: { + itemStyle: { + borderWidth: getComputedStyleValue(chart_echarts_sankey_item_style_BorderWidth) + } + }, + scatter: { + itemStyle: { + borderWidth: getComputedStyleValue(chart_echarts_scatter_item_style_BorderWidth) + } + }, + textStyle: { ...textProps }, + timeAxis: { ...axisProps }, + timeline: { + emphasis: { + controlStyle: { + borderWidth: getComputedStyleValue(chart_echarts_timeline_emphasis_control_style_BorderWidth) + }, + itemStyle: {}, + label: {} + }, + checkpointStyle: {}, + controlStyle: { + borderWidth: getComputedStyleValue(chart_echarts_timeline_control_style_BorderWidth) + }, + itemStyle: { + borderWidth: getComputedStyleValue(chart_echarts_timeline_item_style_BorderWidth) + }, + label: {}, + lineStyle: { + width: getComputedStyleValue(chart_echarts_timeline_line_style_Width) + } + }, + title: { + subtextStyle: { ...textProps }, + textStyle: { ...textProps } + }, + toolbox: { + emphasis: { + iconStyle: {} + }, + iconStyle: {} + }, + tooltip: { + axisPointer: { + crossStyle: { + width: getComputedStyleValue(chart_echarts_tooltip_axis_pointer_cross_style_Width) + }, + lineStyle: { + width: getComputedStyleValue(chart_echarts_tooltip_axis_pointer_line_style_Width) + } + } + }, + valueAxis: { ...axisProps }, + visualMap: {} + }; +}; diff --git a/packages/react-charts/src/echarts/components/themes/color-theme.ts b/packages/react-charts/src/echarts/components/themes/color-theme.ts new file mode 100644 index 00000000000..b0ce1fca81a --- /dev/null +++ b/packages/react-charts/src/echarts/components/themes/color-theme.ts @@ -0,0 +1,253 @@ +/* eslint-disable camelcase */ +import chart_echarts_BackgroundColor from '@patternfly/react-tokens/dist/esm/chart_echarts_BackgroundColor'; +import chart_echarts_bar_item_style_BarBorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_bar_item_style_BarBorderColor'; +import chart_echarts_boxplot_item_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_boxplot_item_style_BorderColor'; +import chart_echarts_candlestick_item_style_positive_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_candlestick_item_style_positive_BorderColor'; +import chart_echarts_candlestick_item_style_positive_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_candlestick_item_style_positive_Color'; +import chart_echarts_candlestick_item_style_negative_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_candlestick_item_style_negative_Color'; +import chart_echarts_candlestick_item_style_negative_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_candlestick_item_style_negative_BorderColor'; +import chart_echarts_funnel_item_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_funnel_item_style_BorderColor'; +import chart_echarts_gauge_item_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_gauge_item_style_BorderColor'; +import chart_echarts_geo_emphasis_item_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_geo_emphasis_item_style_BorderColor'; +import chart_echarts_geo_item_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_geo_item_style_BorderColor'; +import chart_echarts_global_axis_axis_line_item_style_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_global_axis_axis_line_item_style_Color'; +import chart_echarts_global_axis_axis_tick_item_style_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_global_axis_axis_tick_item_style_Color'; +import chart_echarts_global_axis_split_area_area_style_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_global_axis_split_area_area_style_Color'; +import chart_echarts_global_label_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_global_label_Color'; +import chart_echarts_graph_item_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_graph_item_style_BorderColor'; +import chart_echarts_graph_line_style_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_graph_line_style_Color'; +import chart_echarts_map_emphasis_item_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_map_emphasis_item_style_BorderColor'; +import chart_echarts_map_item_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_map_item_style_BorderColor'; +import chart_echarts_parallel_item_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_parallel_item_style_BorderColor'; +import chart_echarts_pie_item_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_pie_item_style_BorderColor'; +import chart_echarts_sankey_item_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_sankey_item_style_BorderColor'; +import chart_echarts_scatter_item_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_scatter_item_style_BorderColor'; +import chart_echarts_tooltip_axis_pointer_cross_style_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_tooltip_axis_pointer_cross_style_Color'; +import chart_echarts_tooltip_axis_pointer_line_style_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_tooltip_axis_pointer_line_style_Color'; +import chart_echarts_toolbox_emphasis_item_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_toolbox_emphasis_item_style_BorderColor'; +import chart_echarts_toolbox_item_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_toolbox_item_style_BorderColor'; +import chart_echarts_timeline_emphasis_control_style_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_timeline_emphasis_control_style_Color'; +import chart_echarts_timeline_emphasis_item_style_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_timeline_emphasis_item_style_Color'; +import chart_echarts_timeline_emphasis_control_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_timeline_emphasis_control_style_BorderColor'; +import chart_echarts_timeline_checkpoint_style_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_timeline_checkpoint_style_Color'; +import chart_echarts_timeline_checkpoint_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_timeline_checkpoint_style_BorderColor'; +import chart_echarts_timeline_control_style_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_timeline_control_style_Color'; +import chart_echarts_timeline_control_style_BorderColor from '@patternfly/react-tokens/dist/esm/chart_echarts_timeline_control_style_BorderColor'; +import chart_echarts_timeline_item_style_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_timeline_item_style_Color'; +import chart_echarts_timeline_line_style_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_timeline_line_style_Color'; +import chart_echarts_tooltip_backgroundColor from '@patternfly/react-tokens/dist/esm/chart_echarts_tooltip_backgroundColor'; +import chart_echarts_tooltip_text_Style_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_tooltip_text_Style_Color'; + +import { ThemeDefinition } from './Theme'; +import { getComputedStyleValue } from '../utils/styles'; + +interface ColorThemeInterface { + COLOR_SCALE: string[]; +} + +/** + * ECharts color theme + * @private + * @beta + */ +export const ColorTheme = (props: ColorThemeInterface): ThemeDefinition => { + const { COLOR_SCALE } = props; + + const labelProps = { + color: getComputedStyleValue(chart_echarts_global_label_Color) + }; + + const axisProps = { + axisLabel: { ...labelProps }, + axisLine: { + lineStyle: { + color: getComputedStyleValue(chart_echarts_global_axis_axis_line_item_style_Color) + } + }, + axisTick: { + lineStyle: { + color: getComputedStyleValue(chart_echarts_global_axis_axis_tick_item_style_Color) + } + }, + splitArea: { + areaStyle: { + color: getComputedStyleValue(chart_echarts_global_axis_split_area_area_style_Color) + } + }, + splitLine: { + lineStyle: { + color: getComputedStyleValue(chart_echarts_global_axis_axis_tick_item_style_Color) // Grid + } + } + }; + + return { + color: COLOR_SCALE, // See https://echarts.apache.org/en/option.html#color + backgroundColor: getComputedStyleValue(chart_echarts_BackgroundColor), // See https://echarts.apache.org/en/option.html#backgroundColor + bar: { + itemStyle: { + barBorderColor: getComputedStyleValue(chart_echarts_bar_item_style_BarBorderColor) + } + }, + boxplot: { + itemStyle: { + borderColor: getComputedStyleValue(chart_echarts_boxplot_item_style_BorderColor) + } + }, + candlestick: { + itemStyle: { + borderColor: getComputedStyleValue(chart_echarts_candlestick_item_style_negative_BorderColor), + borderColor0: getComputedStyleValue(chart_echarts_candlestick_item_style_positive_BorderColor), + color: getComputedStyleValue(chart_echarts_candlestick_item_style_negative_Color), + color0: getComputedStyleValue(chart_echarts_candlestick_item_style_positive_Color) + } + }, + categoryAxis: { ...axisProps }, + dataZoom: {}, + funnel: { + itemStyle: { + borderColor: getComputedStyleValue(chart_echarts_funnel_item_style_BorderColor) + } + }, + gauge: { + itemStyle: { + borderColor: getComputedStyleValue(chart_echarts_gauge_item_style_BorderColor) + } + }, + geo: { + emphasis: { + itemStyle: { + areaColor: COLOR_SCALE[1], + borderColor: getComputedStyleValue(chart_echarts_geo_emphasis_item_style_BorderColor) + }, + label: { ...labelProps } + }, + itemStyle: { + areaColor: COLOR_SCALE[0], + borderColor: getComputedStyleValue(chart_echarts_geo_item_style_BorderColor) + }, + label: { ...labelProps } + }, + graph: { + color: COLOR_SCALE, + itemStyle: { + borderColor: getComputedStyleValue(chart_echarts_graph_item_style_BorderColor) + }, + label: { ...labelProps }, + lineStyle: { + color: getComputedStyleValue(chart_echarts_graph_line_style_Color) + } + }, + label: { ...labelProps }, + legend: { + textStyle: { + color: getComputedStyleValue(chart_echarts_global_label_Color) + } + }, + line: {}, + logAxis: { ...axisProps }, + map: { + emphasis: { + itemStyle: { + areaColor: COLOR_SCALE[1], + borderColor: getComputedStyleValue(chart_echarts_map_emphasis_item_style_BorderColor) + }, + label: { ...labelProps } + }, + itemStyle: { + areaColor: COLOR_SCALE[0], + borderColor: getComputedStyleValue(chart_echarts_map_item_style_BorderColor) + }, + label: { ...labelProps } + }, + markPoint: { + emphasis: { + label: { ...labelProps } + }, + label: { ...labelProps } + }, + parallel: { + itemStyle: { + borderColor: getComputedStyleValue(chart_echarts_parallel_item_style_BorderColor) + } + }, + pie: { + itemStyle: { + borderColor: getComputedStyleValue(chart_echarts_pie_item_style_BorderColor) + } + }, + radar: {}, + sankey: { + itemStyle: { + borderColor: getComputedStyleValue(chart_echarts_sankey_item_style_BorderColor) + } + }, + scatter: { + itemStyle: { + borderColor: getComputedStyleValue(chart_echarts_scatter_item_style_BorderColor) + } + }, + textStyle: {}, + timeAxis: { ...axisProps }, + timeline: { + emphasis: { + controlStyle: { + color: getComputedStyleValue(chart_echarts_timeline_emphasis_control_style_Color), + borderColor: getComputedStyleValue(chart_echarts_timeline_emphasis_control_style_BorderColor) + }, + itemStyle: { + color: getComputedStyleValue(chart_echarts_timeline_emphasis_item_style_Color) + }, + label: { ...labelProps } + }, + checkpointStyle: { + color: getComputedStyleValue(chart_echarts_timeline_checkpoint_style_Color), + borderColor: getComputedStyleValue(chart_echarts_timeline_checkpoint_style_BorderColor) + }, + // --pf-v6-chart-echarts-timeline--control-style--Color + controlStyle: { + color: getComputedStyleValue(chart_echarts_timeline_control_style_Color), + borderColor: getComputedStyleValue(chart_echarts_timeline_control_style_BorderColor) + }, + itemStyle: { + color: getComputedStyleValue(chart_echarts_timeline_item_style_Color) + }, + label: { ...labelProps }, + lineStyle: { + color: getComputedStyleValue(chart_echarts_timeline_line_style_Color) + } + }, + title: { + subtextStyle: { ...labelProps }, + textStyle: { ...labelProps } + }, + toolbox: { + emphasis: { + iconStyle: { + borderColor: getComputedStyleValue(chart_echarts_toolbox_emphasis_item_style_BorderColor) + } + }, + iconStyle: { + borderColor: getComputedStyleValue(chart_echarts_toolbox_item_style_BorderColor) + } + }, + tooltip: { + backgroundColor: getComputedStyleValue(chart_echarts_tooltip_backgroundColor), + axisPointer: { + crossStyle: { + color: getComputedStyleValue(chart_echarts_tooltip_axis_pointer_cross_style_Color) + }, + lineStyle: { + color: getComputedStyleValue(chart_echarts_tooltip_axis_pointer_line_style_Color) + } + }, + textStyle: { + color: getComputedStyleValue(chart_echarts_tooltip_text_Style_Color) + } + }, + valueAxis: { ...axisProps }, + visualMap: { + color: COLOR_SCALE + } + }; +}; diff --git a/packages/react-charts/src/echarts/components/themes/colors/blue-theme.ts b/packages/react-charts/src/echarts/components/themes/colors/blue-theme.ts new file mode 100644 index 00000000000..69f9cf038b9 --- /dev/null +++ b/packages/react-charts/src/echarts/components/themes/colors/blue-theme.ts @@ -0,0 +1,24 @@ +/* eslint-disable camelcase */ +import chart_theme_blue_ColorScale_100 from '@patternfly/react-tokens/dist/esm/chart_theme_blue_ColorScale_100'; +import chart_theme_blue_ColorScale_200 from '@patternfly/react-tokens/dist/esm/chart_theme_blue_ColorScale_200'; +import chart_theme_blue_ColorScale_300 from '@patternfly/react-tokens/dist/esm/chart_theme_blue_ColorScale_300'; +import chart_theme_blue_ColorScale_400 from '@patternfly/react-tokens/dist/esm/chart_theme_blue_ColorScale_400'; +import chart_theme_blue_ColorScale_500 from '@patternfly/react-tokens/dist/esm/chart_theme_blue_ColorScale_500'; +import { ColorTheme } from '../color-theme'; +import { getComputedStyleValue } from '../../utils/styles'; + +/** + * Blue color theme -- see https://docs.google.com/document/d/1cw10pJFXWruB1SA8TQwituxn5Ss6KpxYPCOYGrH8qAY/edit + * + * @private + */ +export const getBlueColorTheme = () => + ColorTheme({ + COLOR_SCALE: [ + getComputedStyleValue(chart_theme_blue_ColorScale_100), + getComputedStyleValue(chart_theme_blue_ColorScale_200), + getComputedStyleValue(chart_theme_blue_ColorScale_300), + getComputedStyleValue(chart_theme_blue_ColorScale_400), + getComputedStyleValue(chart_theme_blue_ColorScale_500) + ] + }); diff --git a/packages/react-charts/src/echarts/components/themes/colors/gray-theme.ts b/packages/react-charts/src/echarts/components/themes/colors/gray-theme.ts new file mode 100644 index 00000000000..f320b28ddab --- /dev/null +++ b/packages/react-charts/src/echarts/components/themes/colors/gray-theme.ts @@ -0,0 +1,23 @@ +/* eslint-disable camelcase */ +import chart_theme_gray_ColorScale_100 from '@patternfly/react-tokens/dist/esm/chart_theme_gray_ColorScale_100'; +import chart_theme_gray_ColorScale_200 from '@patternfly/react-tokens/dist/esm/chart_theme_gray_ColorScale_200'; +import chart_theme_gray_ColorScale_300 from '@patternfly/react-tokens/dist/esm/chart_theme_gray_ColorScale_300'; +import chart_theme_gray_ColorScale_400 from '@patternfly/react-tokens/dist/esm/chart_theme_gray_ColorScale_400'; +import chart_theme_gray_ColorScale_500 from '@patternfly/react-tokens/dist/esm/chart_theme_gray_ColorScale_500'; +import { ColorTheme } from '../color-theme'; +import { getComputedStyleValue } from '../../utils/styles'; + +/** + * Gray color theme -- see https://docs.google.com/document/d/1cw10pJFXWruB1SA8TQwituxn5Ss6KpxYPCOYGrH8qAY/edit + * @private + */ +export const getGrayColorTheme = () => + ColorTheme({ + COLOR_SCALE: [ + getComputedStyleValue(chart_theme_gray_ColorScale_100), + getComputedStyleValue(chart_theme_gray_ColorScale_200), + getComputedStyleValue(chart_theme_gray_ColorScale_300), + getComputedStyleValue(chart_theme_gray_ColorScale_400), + getComputedStyleValue(chart_theme_gray_ColorScale_500) + ] + }); diff --git a/packages/react-charts/src/echarts/components/themes/colors/green-theme.ts b/packages/react-charts/src/echarts/components/themes/colors/green-theme.ts new file mode 100644 index 00000000000..a2f437f26c8 --- /dev/null +++ b/packages/react-charts/src/echarts/components/themes/colors/green-theme.ts @@ -0,0 +1,23 @@ +/* eslint-disable camelcase */ +import chart_theme_green_ColorScale_100 from '@patternfly/react-tokens/dist/esm/chart_theme_green_ColorScale_100'; +import chart_theme_green_ColorScale_200 from '@patternfly/react-tokens/dist/esm/chart_theme_green_ColorScale_200'; +import chart_theme_green_ColorScale_300 from '@patternfly/react-tokens/dist/esm/chart_theme_green_ColorScale_300'; +import chart_theme_green_ColorScale_400 from '@patternfly/react-tokens/dist/esm/chart_theme_green_ColorScale_400'; +import chart_theme_green_ColorScale_500 from '@patternfly/react-tokens/dist/esm/chart_theme_green_ColorScale_500'; +import { ColorTheme } from '../color-theme'; +import { getComputedStyleValue } from '../../utils/styles'; + +/** + * Green color theme -- see https://docs.google.com/document/d/1cw10pJFXWruB1SA8TQwituxn5Ss6KpxYPCOYGrH8qAY/edit + * @private + */ +export const getGreenColorTheme = () => + ColorTheme({ + COLOR_SCALE: [ + getComputedStyleValue(chart_theme_green_ColorScale_100), + getComputedStyleValue(chart_theme_green_ColorScale_200), + getComputedStyleValue(chart_theme_green_ColorScale_300), + getComputedStyleValue(chart_theme_green_ColorScale_400), + getComputedStyleValue(chart_theme_green_ColorScale_500) + ] + }); diff --git a/packages/react-charts/src/echarts/components/themes/colors/multi-ordered-theme.ts b/packages/react-charts/src/echarts/components/themes/colors/multi-ordered-theme.ts new file mode 100644 index 00000000000..ad04db357fa --- /dev/null +++ b/packages/react-charts/src/echarts/components/themes/colors/multi-ordered-theme.ts @@ -0,0 +1,64 @@ +/* eslint-disable camelcase */ +import chart_theme_multi_color_ordered_ColorScale_100 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_100'; +import chart_theme_multi_color_ordered_ColorScale_200 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_200'; +import chart_theme_multi_color_ordered_ColorScale_300 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_300'; +import chart_theme_multi_color_ordered_ColorScale_400 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_400'; +import chart_theme_multi_color_ordered_ColorScale_500 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_500'; +import chart_theme_multi_color_ordered_ColorScale_600 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_600'; +import chart_theme_multi_color_ordered_ColorScale_700 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_700'; +import chart_theme_multi_color_ordered_ColorScale_800 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_800'; +import chart_theme_multi_color_ordered_ColorScale_900 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_900'; +import chart_theme_multi_color_ordered_ColorScale_1000 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_1000'; +import chart_theme_multi_color_ordered_ColorScale_1100 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_1100'; +import chart_theme_multi_color_ordered_ColorScale_1200 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_1200'; +import chart_theme_multi_color_ordered_ColorScale_1300 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_1300'; +import chart_theme_multi_color_ordered_ColorScale_1400 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_1400'; +import chart_theme_multi_color_ordered_ColorScale_1500 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_1500'; +import chart_theme_multi_color_ordered_ColorScale_1600 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_1600'; +import chart_theme_multi_color_ordered_ColorScale_1700 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_1700'; +import chart_theme_multi_color_ordered_ColorScale_1800 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_1800'; +import chart_theme_multi_color_ordered_ColorScale_1900 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_1900'; +import chart_theme_multi_color_ordered_ColorScale_2000 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_2000'; +import chart_theme_multi_color_ordered_ColorScale_2100 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_2100'; +import chart_theme_multi_color_ordered_ColorScale_2200 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_2200'; +import chart_theme_multi_color_ordered_ColorScale_2300 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_2300'; +import chart_theme_multi_color_ordered_ColorScale_2400 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_2400'; +import chart_theme_multi_color_ordered_ColorScale_2500 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_ordered_ColorScale_2500'; +import { ColorTheme } from '../color-theme'; +import { getComputedStyleValue } from '../../utils/styles'; + +/** + * Multi-color ordered theme -- see https://docs.google.com/document/d/1cw10pJFXWruB1SA8TQwituxn5Ss6KpxYPCOYGrH8qAY/edit + * @private + */ +export const getMultiColorOrderedTheme = () => + ColorTheme({ + // The color order below (minus the purple color family) improves the color contrast in ordered charts; donut, pie, bar, & stack + COLOR_SCALE: [ + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_100), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_200), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_300), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_400), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_500), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_600), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_700), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_800), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_900), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_1000), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_1100), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_1200), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_1300), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_1400), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_1500), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_1600), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_1700), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_1800), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_1900), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_2000), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_2100), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_2200), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_2300), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_2400), + getComputedStyleValue(chart_theme_multi_color_ordered_ColorScale_2500) + ] + }); diff --git a/packages/react-charts/src/echarts/components/themes/colors/multi-unordered-theme.ts b/packages/react-charts/src/echarts/components/themes/colors/multi-unordered-theme.ts new file mode 100644 index 00000000000..adf461571c7 --- /dev/null +++ b/packages/react-charts/src/echarts/components/themes/colors/multi-unordered-theme.ts @@ -0,0 +1,84 @@ +/* eslint-disable camelcase */ +import chart_theme_multi_color_unordered_ColorScale_100 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_100'; +import chart_theme_multi_color_unordered_ColorScale_200 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_200'; +import chart_theme_multi_color_unordered_ColorScale_300 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_300'; +import chart_theme_multi_color_unordered_ColorScale_400 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_400'; +import chart_theme_multi_color_unordered_ColorScale_500 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_500'; +import chart_theme_multi_color_unordered_ColorScale_600 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_600'; +import chart_theme_multi_color_unordered_ColorScale_700 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_700'; +import chart_theme_multi_color_unordered_ColorScale_800 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_800'; +import chart_theme_multi_color_unordered_ColorScale_900 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_900'; +import chart_theme_multi_color_unordered_ColorScale_1000 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_1000'; +import chart_theme_multi_color_unordered_ColorScale_1100 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_1100'; +import chart_theme_multi_color_unordered_ColorScale_1200 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_1200'; +import chart_theme_multi_color_unordered_ColorScale_1300 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_1300'; +import chart_theme_multi_color_unordered_ColorScale_1400 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_1400'; +import chart_theme_multi_color_unordered_ColorScale_1500 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_1500'; +import chart_theme_multi_color_unordered_ColorScale_1600 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_1600'; +import chart_theme_multi_color_unordered_ColorScale_1700 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_1700'; +import chart_theme_multi_color_unordered_ColorScale_1800 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_1800'; +import chart_theme_multi_color_unordered_ColorScale_1900 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_1900'; +import chart_theme_multi_color_unordered_ColorScale_2000 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_2000'; +import chart_theme_multi_color_unordered_ColorScale_2100 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_2100'; +import chart_theme_multi_color_unordered_ColorScale_2200 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_2200'; +import chart_theme_multi_color_unordered_ColorScale_2300 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_2300'; +import chart_theme_multi_color_unordered_ColorScale_2400 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_2400'; +import chart_theme_multi_color_unordered_ColorScale_2500 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_2500'; +import chart_theme_multi_color_unordered_ColorScale_2600 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_2600'; +import chart_theme_multi_color_unordered_ColorScale_2700 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_2700'; +import chart_theme_multi_color_unordered_ColorScale_2800 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_2800'; +import chart_theme_multi_color_unordered_ColorScale_2900 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_2900'; +import chart_theme_multi_color_unordered_ColorScale_3000 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_3000'; +import chart_theme_multi_color_unordered_ColorScale_3100 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_3100'; +import chart_theme_multi_color_unordered_ColorScale_3200 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_3200'; +import chart_theme_multi_color_unordered_ColorScale_3300 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_3300'; +import chart_theme_multi_color_unordered_ColorScale_3400 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_3400'; +import chart_theme_multi_color_unordered_ColorScale_3500 from '@patternfly/react-tokens/dist/esm/chart_theme_multi_color_unordered_ColorScale_3500'; +import { ColorTheme } from '../color-theme'; +import { getComputedStyleValue } from '../../utils/styles'; + +/** + * Multi-color unordered theme -- see https://github.com/patternfly/patternfly-next/issues/1551 + * @private + */ +export const getMultiColorUnorderedTheme = () => + ColorTheme({ + // The color order below improves the color contrast in unordered charts; area & line + COLOR_SCALE: [ + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_100), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_200), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_300), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_400), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_500), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_600), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_700), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_800), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_900), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_1000), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_1100), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_1200), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_1300), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_1400), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_1500), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_1600), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_1700), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_1800), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_1900), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_2000), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_2100), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_2200), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_2300), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_2400), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_2500), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_2600), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_2700), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_2800), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_2900), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_3000), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_3100), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_3200), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_3300), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_3400), + getComputedStyleValue(chart_theme_multi_color_unordered_ColorScale_3500) + ] + }); diff --git a/packages/react-charts/src/echarts/components/themes/colors/orange-theme.ts b/packages/react-charts/src/echarts/components/themes/colors/orange-theme.ts new file mode 100644 index 00000000000..c8266c58e6e --- /dev/null +++ b/packages/react-charts/src/echarts/components/themes/colors/orange-theme.ts @@ -0,0 +1,23 @@ +/* eslint-disable camelcase */ +import chart_theme_orange_ColorScale_100 from '@patternfly/react-tokens/dist/esm/chart_theme_orange_ColorScale_100'; +import chart_theme_orange_ColorScale_200 from '@patternfly/react-tokens/dist/esm/chart_theme_orange_ColorScale_200'; +import chart_theme_orange_ColorScale_300 from '@patternfly/react-tokens/dist/esm/chart_theme_orange_ColorScale_300'; +import chart_theme_orange_ColorScale_400 from '@patternfly/react-tokens/dist/esm/chart_theme_orange_ColorScale_400'; +import chart_theme_orange_ColorScale_500 from '@patternfly/react-tokens/dist/esm/chart_theme_orange_ColorScale_500'; +import { ColorTheme } from '../color-theme'; +import { getComputedStyleValue } from '../../utils/styles'; + +/** + * Orange color theme -- see https://docs.google.com/document/d/1cw10pJFXWruB1SA8TQwituxn5Ss6KpxYPCOYGrH8qAY/edit + * @private + */ +export const getOrangeColorTheme = () => + ColorTheme({ + COLOR_SCALE: [ + getComputedStyleValue(chart_theme_orange_ColorScale_100), + getComputedStyleValue(chart_theme_orange_ColorScale_200), + getComputedStyleValue(chart_theme_orange_ColorScale_300), + getComputedStyleValue(chart_theme_orange_ColorScale_400), + getComputedStyleValue(chart_theme_orange_ColorScale_500) + ] + }); diff --git a/packages/react-charts/src/echarts/components/themes/colors/purple-theme.ts b/packages/react-charts/src/echarts/components/themes/colors/purple-theme.ts new file mode 100644 index 00000000000..b5211d1497c --- /dev/null +++ b/packages/react-charts/src/echarts/components/themes/colors/purple-theme.ts @@ -0,0 +1,23 @@ +/* eslint-disable camelcase */ +import chart_theme_purple_ColorScale_100 from '@patternfly/react-tokens/dist/esm/chart_theme_purple_ColorScale_100'; +import chart_theme_purple_ColorScale_200 from '@patternfly/react-tokens/dist/esm/chart_theme_purple_ColorScale_200'; +import chart_theme_purple_ColorScale_300 from '@patternfly/react-tokens/dist/esm/chart_theme_purple_ColorScale_300'; +import chart_theme_purple_ColorScale_400 from '@patternfly/react-tokens/dist/esm/chart_theme_purple_ColorScale_400'; +import chart_theme_purple_ColorScale_500 from '@patternfly/react-tokens/dist/esm/chart_theme_purple_ColorScale_500'; +import { ColorTheme } from '../color-theme'; +import { getComputedStyleValue } from '../../utils/styles'; + +/** + * Purple ordered theme -- see https://docs.google.com/document/d/1cw10pJFXWruB1SA8TQwituxn5Ss6KpxYPCOYGrH8qAY/edit + * @private + */ +export const getPurpleColorTheme = () => + ColorTheme({ + COLOR_SCALE: [ + getComputedStyleValue(chart_theme_purple_ColorScale_100), + getComputedStyleValue(chart_theme_purple_ColorScale_200), + getComputedStyleValue(chart_theme_purple_ColorScale_300), + getComputedStyleValue(chart_theme_purple_ColorScale_400), + getComputedStyleValue(chart_theme_purple_ColorScale_500) + ] + }); diff --git a/packages/react-charts/src/echarts/components/themes/colors/skeleton-theme.ts b/packages/react-charts/src/echarts/components/themes/colors/skeleton-theme.ts new file mode 100644 index 00000000000..51fa6b9aa94 --- /dev/null +++ b/packages/react-charts/src/echarts/components/themes/colors/skeleton-theme.ts @@ -0,0 +1,23 @@ +/* eslint-disable camelcase */ +import chart_bullet_qualitative_range_ColorScale_100 from '@patternfly/react-tokens/dist/esm/chart_bullet_qualitative_range_ColorScale_100'; +import chart_bullet_qualitative_range_ColorScale_200 from '@patternfly/react-tokens/dist/esm/chart_bullet_qualitative_range_ColorScale_200'; +import chart_bullet_qualitative_range_ColorScale_300 from '@patternfly/react-tokens/dist/esm/chart_bullet_qualitative_range_ColorScale_300'; +import chart_bullet_qualitative_range_ColorScale_400 from '@patternfly/react-tokens/dist/esm/chart_bullet_qualitative_range_ColorScale_400'; +import chart_bullet_qualitative_range_ColorScale_500 from '@patternfly/react-tokens/dist/esm/chart_bullet_qualitative_range_ColorScale_500'; +import { ColorTheme } from '../skeleton-theme'; +import { getComputedStyleValue } from '../../utils/styles'; + +/** + * Skeleton color theme + * @private + */ +export const getSkeletonColorTheme = () => + ColorTheme({ + COLOR_SCALE: [ + getComputedStyleValue(chart_bullet_qualitative_range_ColorScale_100), + getComputedStyleValue(chart_bullet_qualitative_range_ColorScale_200), + getComputedStyleValue(chart_bullet_qualitative_range_ColorScale_300), + getComputedStyleValue(chart_bullet_qualitative_range_ColorScale_400), + getComputedStyleValue(chart_bullet_qualitative_range_ColorScale_500) + ] + }); diff --git a/packages/react-charts/src/echarts/components/themes/colors/teal-theme.ts b/packages/react-charts/src/echarts/components/themes/colors/teal-theme.ts new file mode 100644 index 00000000000..50b226c61e8 --- /dev/null +++ b/packages/react-charts/src/echarts/components/themes/colors/teal-theme.ts @@ -0,0 +1,23 @@ +/* eslint-disable camelcase */ +import chart_theme_teal_ColorScale_100 from '@patternfly/react-tokens/dist/esm/chart_theme_teal_ColorScale_100'; +import chart_theme_teal_ColorScale_200 from '@patternfly/react-tokens/dist/esm/chart_theme_teal_ColorScale_200'; +import chart_theme_teal_ColorScale_300 from '@patternfly/react-tokens/dist/esm/chart_theme_teal_ColorScale_300'; +import chart_theme_teal_ColorScale_400 from '@patternfly/react-tokens/dist/esm/chart_theme_teal_ColorScale_400'; +import chart_theme_teal_ColorScale_500 from '@patternfly/react-tokens/dist/esm/chart_theme_teal_ColorScale_500'; +import { ColorTheme } from '../color-theme'; +import { getComputedStyleValue } from '../../utils/styles'; + +/** + * Teal color theme -- see https://docs.google.com/document/d/1cw10pJFXWruB1SA8TQwituxn5Ss6KpxYPCOYGrH8qAY/edit + * @private + */ +export const getTealColorTheme = () => + ColorTheme({ + COLOR_SCALE: [ + getComputedStyleValue(chart_theme_teal_ColorScale_100), + getComputedStyleValue(chart_theme_teal_ColorScale_200), + getComputedStyleValue(chart_theme_teal_ColorScale_300), + getComputedStyleValue(chart_theme_teal_ColorScale_400), + getComputedStyleValue(chart_theme_teal_ColorScale_500) + ] + }); diff --git a/packages/react-charts/src/echarts/components/themes/colors/yellow-theme.ts b/packages/react-charts/src/echarts/components/themes/colors/yellow-theme.ts new file mode 100644 index 00000000000..b2394b2fa79 --- /dev/null +++ b/packages/react-charts/src/echarts/components/themes/colors/yellow-theme.ts @@ -0,0 +1,23 @@ +/* eslint-disable camelcase */ +import chart_theme_yellow_ColorScale_100 from '@patternfly/react-tokens/dist/esm/chart_theme_yellow_ColorScale_100'; +import chart_theme_yellow_ColorScale_200 from '@patternfly/react-tokens/dist/esm/chart_theme_yellow_ColorScale_200'; +import chart_theme_yellow_ColorScale_300 from '@patternfly/react-tokens/dist/esm/chart_theme_yellow_ColorScale_300'; +import chart_theme_yellow_ColorScale_400 from '@patternfly/react-tokens/dist/esm/chart_theme_yellow_ColorScale_400'; +import chart_theme_yellow_ColorScale_500 from '@patternfly/react-tokens/dist/esm/chart_theme_yellow_ColorScale_500'; +import { ColorTheme } from '../color-theme'; +import { getComputedStyleValue } from '../../utils/styles'; + +/** + * Yellow color theme -- see https://docs.google.com/document/d/1cw10pJFXWruB1SA8TQwituxn5Ss6KpxYPCOYGrH8qAY/edit + * @private + */ +export const getYellowColorTheme = () => + ColorTheme({ + COLOR_SCALE: [ + getComputedStyleValue(chart_theme_yellow_ColorScale_100), + getComputedStyleValue(chart_theme_yellow_ColorScale_200), + getComputedStyleValue(chart_theme_yellow_ColorScale_300), + getComputedStyleValue(chart_theme_yellow_ColorScale_400), + getComputedStyleValue(chart_theme_yellow_ColorScale_500) + ] + }); diff --git a/packages/react-charts/src/echarts/components/themes/skeleton-theme.ts b/packages/react-charts/src/echarts/components/themes/skeleton-theme.ts new file mode 100644 index 00000000000..fa5a814177a --- /dev/null +++ b/packages/react-charts/src/echarts/components/themes/skeleton-theme.ts @@ -0,0 +1,212 @@ +/* eslint-disable camelcase */ +import chart_echarts_BackgroundColor from '@patternfly/react-tokens/dist/esm/chart_echarts_BackgroundColor'; +import chart_echarts_global_axis_axis_line_item_style_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_global_axis_axis_line_item_style_Color'; +import chart_echarts_global_axis_axis_tick_item_style_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_global_axis_axis_tick_item_style_Color'; +import chart_echarts_skeleton_label_Color from '@patternfly/react-tokens/dist/esm/chart_echarts_skeleton_label_Color'; + +import { ThemeDefinition } from '../themes/Theme'; +import { getComputedStyleValue } from '../utils/styles'; + +interface ColorThemeInterface { + COLOR_SCALE: string[]; +} + +/** + * ECharts skeleton color theme + * @private + */ +export const ColorTheme = (props: ColorThemeInterface): ThemeDefinition => { + const { COLOR_SCALE } = props; + + const labelProps = { + backgroundColor: COLOR_SCALE[0], + color: getComputedStyleValue(chart_echarts_skeleton_label_Color) + }; + + const axisProps = { + axisLabel: { ...labelProps }, + axisLine: { + lineStyle: { + color: getComputedStyleValue(chart_echarts_global_axis_axis_line_item_style_Color) + } + }, + axisTick: { + lineStyle: { + color: getComputedStyleValue(chart_echarts_global_axis_axis_tick_item_style_Color) + } + }, + splitArea: { + areaStyle: { + color: COLOR_SCALE + } + }, + splitLine: { + lineStyle: { + color: [COLOR_SCALE[0]] + } + } + }; + + return { + color: COLOR_SCALE, + backgroundColor: getComputedStyleValue(chart_echarts_BackgroundColor), // See https://echarts.apache.org/en/option.html#backgroundColor + bar: { + itemStyle: { + barBorderColor: COLOR_SCALE[0] + } + }, + boxplot: { + itemStyle: { + borderColor: COLOR_SCALE[0] + } + }, + candlestick: { + itemStyle: { + borderColor: COLOR_SCALE[0], + borderColor0: COLOR_SCALE[1], + color: COLOR_SCALE[0], + color0: COLOR_SCALE[1] + } + }, + categoryAxis: { ...axisProps }, + dataZoom: {}, + funnel: { + itemStyle: { + borderColor: COLOR_SCALE[0] + } + }, + gauge: { + itemStyle: { + borderColor: COLOR_SCALE[0] + } + }, + geo: { + emphasis: { + itemStyle: { + areaColor: COLOR_SCALE[0], + borderColor: COLOR_SCALE[0] + }, + label: { ...labelProps } + }, + itemStyle: { + areaColor: COLOR_SCALE[0], + borderColor: COLOR_SCALE[0] + }, + label: { ...labelProps } + }, + graph: { + color: COLOR_SCALE, + itemStyle: { + borderColor: COLOR_SCALE[0] + }, + label: { ...labelProps }, + lineStyle: { + color: COLOR_SCALE[0] + } + }, + label: { ...labelProps }, + legend: { + textStyle: { ...labelProps } + }, + line: {}, + logAxis: { ...axisProps }, + map: { + emphasis: { + itemStyle: { + areaColor: COLOR_SCALE[0], + borderColor: COLOR_SCALE[0] + }, + label: { ...labelProps } + }, + itemStyle: { + areaColor: COLOR_SCALE[0], + borderColor: COLOR_SCALE[0] + }, + label: { ...labelProps } + }, + markPoint: { + emphasis: { + label: { ...labelProps } + }, + label: { ...labelProps } + }, + parallel: { + itemStyle: { + borderColor: COLOR_SCALE[0] + } + }, + pie: { + itemStyle: { + borderColor: COLOR_SCALE[0] + } + }, + radar: {}, + sankey: { + itemStyle: { + borderColor: COLOR_SCALE[0] + } + }, + scatter: { + itemStyle: { + borderColor: COLOR_SCALE[0] + } + }, + textStyle: {}, + timeAxis: { ...axisProps }, + timeline: { + emphasis: { + controlStyle: { + color: COLOR_SCALE[0], + borderColor: COLOR_SCALE[0] + }, + itemStyle: { + color: COLOR_SCALE[0] + }, + label: { ...labelProps } + }, + checkpointStyle: { + color: COLOR_SCALE[0], + borderColor: COLOR_SCALE[0] + }, + controlStyle: { + color: COLOR_SCALE[0], + borderColor: COLOR_SCALE[0] + }, + itemStyle: { + color: COLOR_SCALE[0] + }, + label: { ...labelProps }, + lineStyle: { + color: COLOR_SCALE[0] + } + }, + title: { + subtextStyle: { ...labelProps }, + textStyle: { ...labelProps } + }, + toolbox: { + emphasis: { + iconStyle: { + borderColor: COLOR_SCALE[0] + } + }, + iconStyle: { + borderColor: COLOR_SCALE[0] + } + }, + tooltip: { + axisPointer: { + crossStyle: { + color: COLOR_SCALE[0] + }, + lineStyle: { + color: COLOR_SCALE[0] + } + } + }, + valueAxis: { ...axisProps }, + visualMap: { + color: COLOR_SCALE + } + }; +}; diff --git a/packages/react-charts/src/echarts/components/utils/observe.ts b/packages/react-charts/src/echarts/components/utils/observe.ts new file mode 100644 index 00000000000..a7da279bb88 --- /dev/null +++ b/packages/react-charts/src/echarts/components/utils/observe.ts @@ -0,0 +1,37 @@ +/** + * Mutation Observer Helper function -- see developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe + * + * @param {string} selector The DOM selector to watch + * @param {object} opt MutationObserver options + * @param {function} cb Pass Mutation object to a callback function + * @private + */ +export const observe = (selector: any, opt: any, cb: any) => { + let unobserve: any; + + if (selector) { + const Obs = new MutationObserver((m) => [...m].forEach(cb)); + document.querySelectorAll(selector).forEach((el) => Obs.observe(el, opt)); + unobserve = () => Obs.disconnect(); + } + return () => { + if (unobserve) { + unobserve(); + } + }; +}; + +// See https://stackoverflow.com/questions/17134823/detect-element-style-changes-with-javascript +export const getMutationObserver = (nodeSelector: string, cb: any) => + observe( + nodeSelector, + { + attributesList: ['style'], // Only the "style" attribute + attributeOldValue: true // Report also the oldValue + }, + (m: any) => { + if (cb) { + cb(m); + } + } + ); diff --git a/packages/react-charts/src/echarts/components/utils/styles.ts b/packages/react-charts/src/echarts/components/utils/styles.ts new file mode 100644 index 00000000000..67ac25a5a42 --- /dev/null +++ b/packages/react-charts/src/echarts/components/utils/styles.ts @@ -0,0 +1,48 @@ +/** + * Copied from exenv + * @private + */ +export const canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); + +/** + * Returns the class name that will be applied to the outermost div rendered by the chart's container + * @private + */ +export const getClassName = (className: string) => { + let cleanClassName; + + // Cleanup class name + if (className) { + cleanClassName = className + .replace(/pf-v6-c-chart/g, '') + .replace(/pf-c-chart/g, '') + .replace(/\s+/g, ' ') + .trim(); + } + return cleanClassName?.length ? `pf-v6-c-chart ${cleanClassName}` : 'pf-v6-c-chart'; +}; + +/** + * Get computed style value -- see https://github.com/apache/echarts/issues/19743 + * + * Note that Victory uses the style property to apply CSS variables. However, ECharts' LineChart uses `fill` and + * `stroke` attributes, which doesn't work with CSS variables. In addition, using CSS variables with Sankey + * causes sever flashing during mouse hover. Therefore, we will obtain the CSS computed value from the DOM. + * + * @public + * @beta + */ +export const getComputedStyleValue = (token: { name: string; value: string | number; var: string }) => { + let result: any; + + if (canUseDOM) { + result = window.getComputedStyle(document.body)?.getPropertyValue(token.name); + + if (result === '') { + result = undefined; + } else if (!isNaN(result) || result === 'true' || result === 'false') { + result = JSON.parse(result); + } + } + return result !== undefined ? result : token.value; +}; diff --git a/packages/react-charts/src/echarts/components/utils/symbol.tsx b/packages/react-charts/src/echarts/components/utils/symbol.tsx new file mode 100644 index 00000000000..81b2b47fe73 --- /dev/null +++ b/packages/react-charts/src/echarts/components/utils/symbol.tsx @@ -0,0 +1,166 @@ +import { getComputedStyleValue } from './styles'; + +// eslint-disable-next-line camelcase +import chart_echarts_BackgroundColor from '@patternfly/react-tokens/dist/esm/chart_echarts_BackgroundColor'; + +const enum SymbolType { + arrow = 'arrow', + circle = 'circle', + diamond = 'diamond', + emptyArrow = 'emptyArrow', + emptyCircle = 'emptyCircle', + emptyDiamond = 'emptyDiamond', + emptyPin = 'emptyPin', + emptyRect = 'emptyRect', + emptyRoundRect = 'emptyRoundRect', + emptySquare = 'emptySquare', + emptyTriangle = 'emptyTriangle', + pin = 'pin', + rect = 'rect', + roundRect = 'roundRect', + square = 'square', + triangle = 'triangle' +} + +// ECharts icon types -- see https://svg-path.com/ +const symbols = { + arrow: 'M12.5 7L19.9667 18.2L12.5 15.4L5.0333 18.2L12.5 7Z', + circle: 'M18.1 7A5.6 5.6 0 1 1 18.1 6.9994Z', + diamond: 'M12.5 1.4L18.1 7L12.5 12.6L6.9 7Z', + emptyArrow: 'M12.5 7L19.9667 18.2L12.5 15.4L5.0333 18.2L12.5 7Z', + emptyCircle: 'M18.1 7A5.6 5.6 0 1 1 18.1 6.9994Z', + emptyDiamond: 'M12.5 1.4L18.1 7L12.5 12.6L6.9 7Z', + emptyPin: + 'M9.4642 2.04A3.36 3.36 0 1 1 15.5358 2.04C14.6718 3.8615 12.5 4.648 12.5 7C12.5 4.648 10.3282 3.8615 9.4642 2.04Z', + emptyRect: 'M6.9,1.4 l14.2,0 l0,11.2 l-14.2,0 Z', + emptyRoundRect: + 'M9.7,1.4 L18.3,1.4 A2.8,2.8,0,0,1,21.1,4.2 L21.1,9.8 A2.8,2.8,0,0,1,18.3,12.6 L9.7,12.6 A2.8,2.8,0,0,1,6.9,9.8 L6.9,4.2 A2.8,2.8,0,0,1,9.7,1.4 Z', + emptySquare: 'M6.9 1.4l11.2 0l0 11.2l-11.2 0Z', + emptyTriangle: 'M12.5 1.4L18.1 12.5L12.5 12.5L6.9 12.5Z', + pin: 'M9.4642 2.04A3.36 3.36 0 1 1 15.5358 2.04C14.6718 3.8615 12.5 4.648 12.5 7C12.5 4.648 10.3282 3.8615 9.4642 2.04Z', + rect: 'M6.9,1.4 l18.2,0 l0,11.2 l-18.2,0 Z', + roundRect: + 'M9.7,1.4 L22.3,1.4 A2.8,2.8,0,0,1,25.1,4.2 L25.1,9.8 A2.8,2.8,0,0,1,22.3,12.6 L9.7,12.6 A2.8,2.8,0,0,1,6.9,9.8 L6.9,4.2 A2.8,2.8,0,0,1,9.7,1.4 Z', + square: 'M6.9 1.4l11.2 0l0 11.2l-11.2 0Z', + triangle: 'M12.5 1.4L18.1 12.5L12.5 12.5L6.9 12.5Z' +}; + +/** + * Returns marker -- see https://github.com/apache/echarts/issues/19826 + * + * @param serie + * @param symbol + * @param color + * @private + */ +export const getMarker = (serie: any, symbol: string, color: string = '') => { + const size = 18; + let path; + let pathStyle = `fill:${color};`; + const svgStyle = 'vertical-align: middle;'; + + let transform; + + // Set marker type + switch (symbol) { + case SymbolType.arrow: + case SymbolType.circle: + case SymbolType.diamond: + case SymbolType.emptyArrow: + case SymbolType.emptyCircle: + case SymbolType.emptyDiamond: + case SymbolType.emptyPin: + case SymbolType.emptyRect: + case SymbolType.emptyRoundRect: + case SymbolType.emptySquare: + case SymbolType.emptyTriangle: + case SymbolType.pin: + case SymbolType.rect: + case SymbolType.roundRect: + case SymbolType.square: + case SymbolType.triangle: + path = symbols[symbol]; + break; + default: + path = symbols.square; + break; + } + + // Set path style for EChart symbols + switch (symbol) { + case SymbolType.emptyArrow: + case SymbolType.emptyCircle: + case SymbolType.emptyDiamond: + case SymbolType.emptyPin: + case SymbolType.emptyRect: + case SymbolType.emptyRoundRect: + case SymbolType.emptySquare: + case SymbolType.emptyTriangle: + pathStyle = `fill:${getComputedStyleValue(chart_echarts_BackgroundColor)}; stroke:${color}; stroke-width:2`; + break; + default: + pathStyle = `fill:${color}; margin-left:-50px;`; + } + + // Set SVG style for EChart symbols + switch (symbol) { + case SymbolType.arrow: + case SymbolType.emptyArrow: + transform = `translate(-5 -5)`; + break; + case SymbolType.emptyDiamond: + transform = `translate(-5 5)`; + break; + case SymbolType.emptyRect: + case SymbolType.emptyRoundRect: + transform = `translate(-5 0)`; + break; + case SymbolType.pin: + transform = `translate(-5 5)`; + break; + case SymbolType.rect: + transform = `translate(-7 0)`; + break; + case SymbolType.roundRect: + transform = `translate(-7 0)`; + break; + default: + transform = `translate(-5 0)`; + break; + } + + const marker = ``; + const svg = `${marker}`; + + return svg; +}; + +/** + * Returns default symbol + * + * @param series + * @param seriesIndex + * @param echart + * @private + */ +export const getSymbol = (series: any, seriesIndex: number, echart: any) => { + const ase = echart?.getModel().findComponents({ mainType: 'series' }); + const data = ase[seriesIndex].getData(); + const symbol = data?.getVisual('symbol')?.replace(/"/g, ''); + + if (!symbol) { + const serie = series[seriesIndex]; + if (serie?.symbol) { + return serie?.symbol; + } + switch (serie?.type) { + case 'bar': + return SymbolType.rect; + case 'line': + return SymbolType.square; + default: + break; + } + } + return symbol; +}; diff --git a/packages/react-charts/src/echarts/components/utils/theme.ts b/packages/react-charts/src/echarts/components/utils/theme.ts new file mode 100644 index 00000000000..f234c1f0632 --- /dev/null +++ b/packages/react-charts/src/echarts/components/utils/theme.ts @@ -0,0 +1,68 @@ +import cloneDeep from 'lodash/cloneDeep'; +import merge from 'lodash/merge'; +import { ThemeColor } from '../themes/ThemeColor'; +import { ThemeDefinition } from '../themes/Theme'; +import { BaseTheme } from '../themes/base-theme'; +import { getBlueColorTheme } from '../themes/colors/blue-theme'; +import { getTealColorTheme } from '../themes/colors/teal-theme'; +import { getYellowColorTheme } from '../themes/colors/yellow-theme'; +import { getGrayColorTheme } from '../themes/colors/gray-theme'; +import { getGreenColorTheme } from '../themes/colors/green-theme'; +import { getSkeletonColorTheme } from '../themes/colors/skeleton-theme'; +import { getMultiColorOrderedTheme } from '../themes/colors/multi-ordered-theme'; +import { getMultiColorUnorderedTheme } from '../themes/colors/multi-unordered-theme'; +import { getOrangeColorTheme } from '../themes/colors/orange-theme'; +import { getPurpleColorTheme } from '../themes/colors/purple-theme'; + +/** + * Apply custom properties to base and color themes + * + * @param themeColor The theme color to merge with custom theme + * @param customTheme The custom theme to merge + * @public + * @beta + */ +export const getCustomTheme = (themeColor: string, customTheme: ThemeDefinition): ThemeDefinition => + merge(getTheme(themeColor), customTheme); + +/** + * Returns base theme for given color + * @public + * @beta + */ +export const getTheme = (themeColor: string): ThemeDefinition => { + const baseTheme = cloneDeep(BaseTheme()); + return merge(baseTheme, getThemeColors(themeColor)); +}; + +/** + * Returns computed theme colors + * @private + */ +const getThemeColors = (themeColor: string) => { + switch (themeColor) { + case ThemeColor.blue: + return getBlueColorTheme(); + case ThemeColor.teal: + return getTealColorTheme(); + case ThemeColor.yellow: + return getYellowColorTheme(); + case ThemeColor.gray: + return getGrayColorTheme(); + case ThemeColor.green: + return getGreenColorTheme(); + case ThemeColor.multi: + case ThemeColor.multiOrdered: + return getMultiColorOrderedTheme(); + case ThemeColor.multiUnordered: + return getMultiColorUnorderedTheme(); + case ThemeColor.orange: + return getOrangeColorTheme(); + case ThemeColor.purple: + return getPurpleColorTheme(); + case ThemeColor.skeleton: + return getSkeletonColorTheme(); + default: + return getBlueColorTheme(); + } +}; diff --git a/packages/react-charts/src/echarts/components/utils/tooltip.tsx b/packages/react-charts/src/echarts/components/utils/tooltip.tsx new file mode 100644 index 00000000000..ea131a015f0 --- /dev/null +++ b/packages/react-charts/src/echarts/components/utils/tooltip.tsx @@ -0,0 +1,100 @@ +import defaultsDeep from 'lodash/defaultsDeep'; + +import { EChartsOptionProps } from '../charts/PatternflyECharts'; +import { getMarker, getSymbol } from './symbol'; + +/** + * Returns a custom legend tooltip for Line charts + * + * @param series + * @param option + * @param echart + * @private + */ +export const getLegendTooltip = (series: any[], option: EChartsOptionProps, echart: any) => { + const tooltip = option?.tooltip as any; + const valueFormatter = tooltip?.valueFormatter ? tooltip.valueFormatter : (value: number | string) => value; + + const defaults = { + confine: true, + formatter: (params: any) => { + let result = ''; + params?.map((param, index) => { + if (index === 0) { + result += `

${param.name}

`; + } + const symbol = getSymbol(series, param.seriesIndex, echart); + const marker = getMarker(series[param.seriesIndex], symbol, param.color); + const formattedValue = valueFormatter(param.value, param.dataIndex); + const seriesName = `${param.seriesName}`; + const value = `${formattedValue}`; + + result += `

${marker}${seriesName}${value}

`; + }); + return result; + }, + trigger: 'axis' + }; + return defaultsDeep(tooltip, defaults); +}; + +/** + * Returns source and target colors from given series + * + * @param series + * @param formatterParams + * @private + */ +const getItemColor = (series: any[], formatterParams: any) => { + const serie = series[formatterParams.seriesIndex]; + const sourceData = serie?.data.find((datum: any) => datum.name === formatterParams.data?.source); + const targetData = serie?.data.find((datum: any) => datum.name === formatterParams.data?.target); + const sourceColor = sourceData?.itemStyle?.color; + const targetColor = targetData?.itemStyle?.color; + return { sourceColor, targetColor }; +}; + +/** + * Returns a custom legend tooltip for Sankey chart + * + * @param series + * @param option + * @private + */ +export const getSankeyTooltip = (series: any[], option: EChartsOptionProps) => { + const symbolSize = '10px'; + const tooltip = option?.tooltip as any; + const sourceLabel = tooltip?.sourceLabel ? tooltip.sourceLabel : ''; + const destinationLabel = tooltip?.destinationLabel ? tooltip.destinationLabel : ''; + const valueFormatter = tooltip?.valueFormatter ? tooltip.valueFormatter : (value: number | string) => value; + + const defaults = { + confine: true, + formatter: (params: any) => { + const result = ` +
+ ${params.name} ${params.value} + `; + if (params?.data?.source && params?.data?.target) { + const { sourceColor, targetColor } = getItemColor(series, params); + return ` +

${sourceLabel}

+
+ ${params.data.source} +

${destinationLabel}

+

+

+ ${params.data.target} + + ${valueFormatter(params.value, params.dataIndex)} + +

+ `; + } + return result.replace(/\s\s+/g, ' '); + }, + trigger: 'item', + triggerOn: 'mousemove' + }; + return defaultsDeep(tooltip, defaults); +}; diff --git a/packages/react-charts/src/echarts/index.ts b/packages/react-charts/src/echarts/index.ts new file mode 100644 index 00000000000..07635cbbc8e --- /dev/null +++ b/packages/react-charts/src/echarts/index.ts @@ -0,0 +1 @@ +export * from './components'; diff --git a/packages/react-charts/src/echarts/typings/echarts.d.ts b/packages/react-charts/src/echarts/typings/echarts.d.ts new file mode 100644 index 00000000000..497834cab88 --- /dev/null +++ b/packages/react-charts/src/echarts/typings/echarts.d.ts @@ -0,0 +1,7 @@ +import * as echarts from 'echarts/types/dist/core'; + +declare module 'echarts' { + export const registerTheme: echarts.registerTheme; + export const init: echarts.init; + export type ECharts = any; +} diff --git a/packages/react-charts/src/victory/components/ChartArea/examples/ChartArea.md b/packages/react-charts/src/victory/components/ChartArea/examples/ChartArea.md index ca653b02301..e9fcd80c76d 100644 --- a/packages/react-charts/src/victory/components/ChartArea/examples/ChartArea.md +++ b/packages/react-charts/src/victory/components/ChartArea/examples/ChartArea.md @@ -18,7 +18,7 @@ import { getResizeObserver } from '@patternfly/react-core'; ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Examples ### Basic with right aligned legend diff --git a/packages/react-charts/src/victory/components/ChartBar/examples/ChartBar.md b/packages/react-charts/src/victory/components/ChartBar/examples/ChartBar.md index 6466d22dbc7..d4442266c76 100644 --- a/packages/react-charts/src/victory/components/ChartBar/examples/ChartBar.md +++ b/packages/react-charts/src/victory/components/ChartBar/examples/ChartBar.md @@ -15,7 +15,7 @@ import t_global_color_status_warning_100 from '@patternfly/react-tokens/dist/esm Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Examples diff --git a/packages/react-charts/src/victory/components/ChartBoxPlot/examples/ChartBoxPlot.md b/packages/react-charts/src/victory/components/ChartBoxPlot/examples/ChartBoxPlot.md index ee8e3822fca..806c93d2d83 100644 --- a/packages/react-charts/src/victory/components/ChartBoxPlot/examples/ChartBoxPlot.md +++ b/packages/react-charts/src/victory/components/ChartBoxPlot/examples/ChartBoxPlot.md @@ -19,7 +19,7 @@ import chart_color_orange_300 from '@patternfly/react-tokens/dist/esm/chart_colo ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Examples diff --git a/packages/react-charts/src/victory/components/ChartBullet/examples/ChartBullet.md b/packages/react-charts/src/victory/components/ChartBullet/examples/ChartBullet.md index 821add11443..56b02c2f1cf 100644 --- a/packages/react-charts/src/victory/components/ChartBullet/examples/ChartBullet.md +++ b/packages/react-charts/src/victory/components/ChartBullet/examples/ChartBullet.md @@ -15,7 +15,7 @@ import { getResizeObserver } from '@patternfly/react-core'; ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Examples ### Basic diff --git a/packages/react-charts/src/victory/components/ChartDonut/examples/ChartDonut.md b/packages/react-charts/src/victory/components/ChartDonut/examples/ChartDonut.md index 63e2917cad9..bf298017581 100644 --- a/packages/react-charts/src/victory/components/ChartDonut/examples/ChartDonut.md +++ b/packages/react-charts/src/victory/components/ChartDonut/examples/ChartDonut.md @@ -12,7 +12,7 @@ import { ChartDonut, ChartThemeColor } from '@patternfly/react-charts/victory'; ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Examples ### Basic diff --git a/packages/react-charts/src/victory/components/ChartDonutUtilization/examples/ChartDonutUtilization.md b/packages/react-charts/src/victory/components/ChartDonutUtilization/examples/ChartDonutUtilization.md index c92e0521a57..064888410d7 100644 --- a/packages/react-charts/src/victory/components/ChartDonutUtilization/examples/ChartDonutUtilization.md +++ b/packages/react-charts/src/victory/components/ChartDonutUtilization/examples/ChartDonutUtilization.md @@ -13,7 +13,7 @@ import { ChartDonutThreshold, ChartDonutUtilization, ChartThemeColor } from '@pa ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Donut utilization examples ### Basic diff --git a/packages/react-charts/src/victory/components/ChartLegend/examples/ChartLegend.md b/packages/react-charts/src/victory/components/ChartLegend/examples/ChartLegend.md index 5d824d7f6e0..c3992935eec 100644 --- a/packages/react-charts/src/victory/components/ChartLegend/examples/ChartLegend.md +++ b/packages/react-charts/src/victory/components/ChartLegend/examples/ChartLegend.md @@ -48,7 +48,7 @@ import '@patternfly/patternfly/patternfly-charts.css'; ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Examples ### Basic with right aligned legend diff --git a/packages/react-charts/src/victory/components/ChartLine/examples/ChartLine.md b/packages/react-charts/src/victory/components/ChartLine/examples/ChartLine.md index c4f4294940d..182f0644cde 100644 --- a/packages/react-charts/src/victory/components/ChartLine/examples/ChartLine.md +++ b/packages/react-charts/src/victory/components/ChartLine/examples/ChartLine.md @@ -18,7 +18,7 @@ import { VictoryZoomContainer } from 'victory-zoom-container'; ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Examples ### Basic with right aligned legend diff --git a/packages/react-charts/src/victory/components/ChartPie/examples/ChartPie.md b/packages/react-charts/src/victory/components/ChartPie/examples/ChartPie.md index 41fb26fd255..a5f59c8e3be 100644 --- a/packages/react-charts/src/victory/components/ChartPie/examples/ChartPie.md +++ b/packages/react-charts/src/victory/components/ChartPie/examples/ChartPie.md @@ -13,7 +13,7 @@ import chart_theme_orange_ColorScale_300 from '@patternfly/react-tokens/dist/esm ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Examples ### Basic with right aligned legend diff --git a/packages/react-charts/src/victory/components/ChartScatter/examples/ChartScatter.md b/packages/react-charts/src/victory/components/ChartScatter/examples/ChartScatter.md index 6feb3210e7c..7f5bbca7de6 100644 --- a/packages/react-charts/src/victory/components/ChartScatter/examples/ChartScatter.md +++ b/packages/react-charts/src/victory/components/ChartScatter/examples/ChartScatter.md @@ -28,7 +28,7 @@ import { getResizeObserver } from '@patternfly/react-core'; ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Examples ### Basic diff --git a/packages/react-charts/src/victory/components/ChartStack/examples/ChartStack.md b/packages/react-charts/src/victory/components/ChartStack/examples/ChartStack.md index 20340f2ef4d..1fced64b98a 100644 --- a/packages/react-charts/src/victory/components/ChartStack/examples/ChartStack.md +++ b/packages/react-charts/src/victory/components/ChartStack/examples/ChartStack.md @@ -28,7 +28,7 @@ import { getResizeObserver } from '@patternfly/react-core'; ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Examples ### Basic with right aligned legend diff --git a/packages/react-charts/src/victory/components/ChartTheme/examples/ChartTheme.md b/packages/react-charts/src/victory/components/ChartTheme/examples/ChartTheme.md index 9d7458c9f6f..c298d6ec955 100644 --- a/packages/react-charts/src/victory/components/ChartTheme/examples/ChartTheme.md +++ b/packages/react-charts/src/victory/components/ChartTheme/examples/ChartTheme.md @@ -29,7 +29,7 @@ import chart_color_purple_300 from '@patternfly/react-tokens/dist/esm/chart_colo ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Examples ### Green diff --git a/packages/react-charts/src/victory/components/ChartThreshold/examples/ChartThreshold.md b/packages/react-charts/src/victory/components/ChartThreshold/examples/ChartThreshold.md index b76b8781ca7..c25e3da2778 100644 --- a/packages/react-charts/src/victory/components/ChartThreshold/examples/ChartThreshold.md +++ b/packages/react-charts/src/victory/components/ChartThreshold/examples/ChartThreshold.md @@ -29,7 +29,7 @@ import chart_color_orange_300 from '@patternfly/react-tokens/dist/esm/chart_colo ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Examples diff --git a/packages/react-charts/src/victory/components/ChartTooltip/examples/ChartTooltip.md b/packages/react-charts/src/victory/components/ChartTooltip/examples/ChartTooltip.md index 9e82556c344..4dba43b5b94 100644 --- a/packages/react-charts/src/victory/components/ChartTooltip/examples/ChartTooltip.md +++ b/packages/react-charts/src/victory/components/ChartTooltip/examples/ChartTooltip.md @@ -40,7 +40,7 @@ import './chart-tooltip.css'; ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Examples ### Voronoi container diff --git a/packages/react-charts/src/victory/components/ChartUtils/chart-container.tsx b/packages/react-charts/src/victory/components/ChartUtils/chart-container.tsx index bc9b310b418..5ed723c8064 100644 --- a/packages/react-charts/src/victory/components/ChartUtils/chart-container.tsx +++ b/packages/react-charts/src/victory/components/ChartUtils/chart-container.tsx @@ -1,5 +1,7 @@ /* eslint-disable camelcase */ import chart_container_cursor_line_Fill from '@patternfly/react-tokens/dist/esm/chart_container_cursor_line_Fill'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import React from 'react'; import { ContainerType, createContainer as victoryCreateContainer } from 'victory-create-container'; import { ChartCursorTooltip } from '../ChartCursorTooltip/ChartCursorTooltip'; import { ChartLabel } from '../ChartLabel/ChartLabel'; diff --git a/packages/react-charts/src/victory/components/ChartUtils/chart-patterns.tsx b/packages/react-charts/src/victory/components/ChartUtils/chart-patterns.tsx index 4eb229483b1..678f118125e 100644 --- a/packages/react-charts/src/victory/components/ChartUtils/chart-patterns.tsx +++ b/packages/react-charts/src/victory/components/ChartUtils/chart-patterns.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import uniqueId from 'lodash/uniqueId'; +import cloneDeep from 'lodash/cloneDeep'; interface PatternPropsInterface { children?: any; @@ -330,7 +331,7 @@ export const useDefaultPatternProps = ({ themeColorScale }: PatternPropsInterface) => { const defaultColorScale = getDefaultColorScale(colorScale, themeColorScale); - let defaultPatternScale = patternScale; + let defaultPatternScale = cloneDeep(patternScale); let isPatternDefs = !patternScale && hasPatterns !== undefined; const patternId = React.useMemo(() => (isPatternDefs ? getPatternId() : undefined), [isPatternDefs]); diff --git a/packages/react-charts/src/victory/components/Patterns/examples/patterns.md b/packages/react-charts/src/victory/components/Patterns/examples/patterns.md index 22b8200dd75..e174783f7ed 100644 --- a/packages/react-charts/src/victory/components/Patterns/examples/patterns.md +++ b/packages/react-charts/src/victory/components/Patterns/examples/patterns.md @@ -51,7 +51,7 @@ import '@patternfly/patternfly/patternfly-charts.css'; ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Examples ### Basic pie chart diff --git a/packages/react-charts/src/victory/components/ResizeObserver/examples/resizeObserver.md b/packages/react-charts/src/victory/components/ResizeObserver/examples/resizeObserver.md index 2c260a5b053..9ae89bd3f7f 100644 --- a/packages/react-charts/src/victory/components/ResizeObserver/examples/resizeObserver.md +++ b/packages/react-charts/src/victory/components/ResizeObserver/examples/resizeObserver.md @@ -39,7 +39,7 @@ import '@patternfly/patternfly/patternfly-charts.css'; ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. Charts scale within the parent container by default, so the `width` and `height` props do not actually determine the width and height of the chart in number of pixels, but instead define an aspect ratio for the chart. The exact number diff --git a/packages/react-charts/src/victory/components/Skeletons/examples/skeletons.md b/packages/react-charts/src/victory/components/Skeletons/examples/skeletons.md index f76f1c9f409..4e8d6126fe6 100644 --- a/packages/react-charts/src/victory/components/Skeletons/examples/skeletons.md +++ b/packages/react-charts/src/victory/components/Skeletons/examples/skeletons.md @@ -21,7 +21,6 @@ propComponents: [ 'ChartVoronoiContainer' ] hideDarkMode: true -beta: true --- import { Chart, ChartArea, ChartAxis, ChartBar, ChartBoxPlot, ChartBullet, ChartDonut, ChartDonutThreshold, ChartDonutUtilization, ChartLegend, ChartLine, ChartGroup, ChartPie, ChartScatter, ChartStack, ChartThemeColor, ChartThreshold, ChartVoronoiContainer } from '@patternfly/react-charts/victory'; @@ -31,7 +30,7 @@ import chart_color_blue_300 from '@patternfly/react-tokens/dist/esm/chart_color_ ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Examples ### Area chart diff --git a/packages/react-charts/src/victory/components/Sparkline/examples/sparkline.md b/packages/react-charts/src/victory/components/Sparkline/examples/sparkline.md index a80b59b68c5..5b4bc50bc97 100644 --- a/packages/react-charts/src/victory/components/Sparkline/examples/sparkline.md +++ b/packages/react-charts/src/victory/components/Sparkline/examples/sparkline.md @@ -20,7 +20,7 @@ import './sparkline.css'; ## Introduction Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)! -PatternFly React charts are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. +The examples below are based on the [Victory](https://formidable.com/open-source/victory/docs/victory-chart/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior. ## Examples ### Basic diff --git a/packages/react-charts/subpaths.config.json b/packages/react-charts/subpaths.config.json index 5c5e5d1baff..706c0581100 100644 --- a/packages/react-charts/subpaths.config.json +++ b/packages/react-charts/subpaths.config.json @@ -1,4 +1,4 @@ { "packageName": "@patternfly/react-charts", - "paths": ["victory"] + "paths": ["echarts", "victory"] } diff --git a/packages/react-charts/tsconfig.json b/packages/react-charts/tsconfig.json index 2b83373e153..f2ea47fc857 100644 --- a/packages/react-charts/tsconfig.json +++ b/packages/react-charts/tsconfig.json @@ -1,10 +1,15 @@ { "extends": "../tsconfig.base.json", "compilerOptions": { + "jsx": "react", "rootDir": "./src", "outDir": "./dist/esm", "tsBuildInfoFile": "dist/esm.tsbuildinfo", "noImplicitAny": false, + "baseUrl": ".", + "paths": { + "./next": ["./src/next"] + } }, "include": [ "./src/*", diff --git a/packages/react-core/package.json b/packages/react-core/package.json index f9279e2c7fc..ceb8dc8a9dd 100644 --- a/packages/react-core/package.json +++ b/packages/react-core/package.json @@ -54,7 +54,7 @@ "tslib": "^2.8.1" }, "devDependencies": { - "@patternfly/patternfly": "6.2.0-prerelease.14", + "@patternfly/patternfly": "6.2.0-prerelease.15", "case-anything": "^3.1.2", "css": "^3.0.0", "fs-extra": "^11.3.0" diff --git a/packages/react-docs/package.json b/packages/react-docs/package.json index 4092870e473..20feb18b162 100644 --- a/packages/react-docs/package.json +++ b/packages/react-docs/package.json @@ -23,7 +23,7 @@ "test:a11y": "patternfly-a11y --config patternfly-a11y.config" }, "dependencies": { - "@patternfly/patternfly": "6.2.0-prerelease.14", + "@patternfly/patternfly": "6.2.0-prerelease.15", "@patternfly/react-charts": "workspace:^", "@patternfly/react-code-editor": "workspace:^", "@patternfly/react-core": "workspace:^", @@ -33,6 +33,7 @@ "@patternfly/react-table": "workspace:^", "@patternfly/react-templates": "workspace:^", "@patternfly/react-tokens": "workspace:^", + "echarts": "^5.6.0", "victory": "^37.3.6" }, "devDependencies": { diff --git a/packages/react-docs/patternfly-docs/patternfly-docs.source.js b/packages/react-docs/patternfly-docs/patternfly-docs.source.js index 4d5914b5a5f..22ae04d245b 100644 --- a/packages/react-docs/patternfly-docs/patternfly-docs.source.js +++ b/packages/react-docs/patternfly-docs/patternfly-docs.source.js @@ -41,9 +41,10 @@ module.exports = (baseSourceMD, sourceProps) => { // Charts MD sourceMD(path.join(reactChartsPath, '/echarts/components/**/examples/*.md'), 'react'); - sourceMD(path.join(reactChartsPath, '/next/echarts/components/**/examples/*.md'), 'react-next'); - sourceMD(path.join(reactChartsPath, '/next/victory/components/**/examples/*.md'), 'react-next'); + sourceMD(path.join(reactChartsPath, '/echarts/components/**/examples/next/*.md'), 'react-next'); + sourceMD(path.join(reactChartsPath, '/echarts/next/components/**/examples/*.md'), 'react-next'); sourceMD(path.join(reactChartsPath, '/victory/components/**/examples/*.md'), 'react'); + sourceMD(path.join(reactChartsPath, '/victory/next/components/**/examples/*.md'), 'react-next'); // Code Editor MD sourceMD(path.join(reactCodeEditorPath, '/**/examples/*.md'), 'react'); diff --git a/packages/react-icons/package.json b/packages/react-icons/package.json index 2c35edbd577..2cd9567cf01 100644 --- a/packages/react-icons/package.json +++ b/packages/react-icons/package.json @@ -33,7 +33,7 @@ "@fortawesome/free-brands-svg-icons": "^5.15.4", "@fortawesome/free-regular-svg-icons": "^5.15.4", "@fortawesome/free-solid-svg-icons": "^5.15.4", - "@patternfly/patternfly": "6.2.0-prerelease.14", + "@patternfly/patternfly": "6.2.0-prerelease.15", "fs-extra": "^11.3.0", "tslib": "^2.8.1" }, diff --git a/packages/react-styles/package.json b/packages/react-styles/package.json index cb1d940921e..565ac450317 100644 --- a/packages/react-styles/package.json +++ b/packages/react-styles/package.json @@ -19,7 +19,7 @@ "clean": "rimraf dist css" }, "devDependencies": { - "@patternfly/patternfly": "6.2.0-prerelease.14", + "@patternfly/patternfly": "6.2.0-prerelease.15", "change-case": "^5.4.4", "fs-extra": "^11.3.0" }, diff --git a/packages/react-tokens/package.json b/packages/react-tokens/package.json index 9472f759da3..fa158d65b4d 100644 --- a/packages/react-tokens/package.json +++ b/packages/react-tokens/package.json @@ -29,7 +29,7 @@ "clean": "rimraf dist" }, "devDependencies": { - "@patternfly/patternfly": "6.2.0-prerelease.14", + "@patternfly/patternfly": "6.2.0-prerelease.15", "css": "^3.0.0", "fs-extra": "^11.3.0" } diff --git a/packages/testSetup.ts b/packages/testSetup.ts index 52b79e9723a..0c5fc63a84e 100644 --- a/packages/testSetup.ts +++ b/packages/testSetup.ts @@ -1,2 +1,3 @@ // Add custom jest matchers from jest-dom import '@testing-library/jest-dom'; +import 'jest-canvas-mock'; diff --git a/yarn.lock b/yarn.lock index caac0c17507..755dc8373d9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3625,10 +3625,10 @@ __metadata: languageName: node linkType: hard -"@patternfly/patternfly@npm:6.2.0-prerelease.14": - version: 6.2.0-prerelease.14 - resolution: "@patternfly/patternfly@npm:6.2.0-prerelease.14" - checksum: 10c0/4425e32e97f98c95b27c19041dca1f1d70348bf5e061585c0c0124e0583270a8854e955731759b0c535091a2f13409521403fa47b378dabd90e3d517f98ea4f7 +"@patternfly/patternfly@npm:6.2.0-prerelease.15": + version: 6.2.0-prerelease.15 + resolution: "@patternfly/patternfly@npm:6.2.0-prerelease.15" + checksum: 10c0/5668e4a233974158f6cc0a5c100446368176fafc26a389797109d15c80d068ecf8056eba879f4ca3c6931cfc389818022276c9efdc0cd4823a7ff1401699e5e8 languageName: node linkType: hard @@ -3641,9 +3641,11 @@ __metadata: "@types/lodash": "npm:^4.17.16" fs-extra: "npm:^11.3.0" hoist-non-react-statics: "npm:^3.3.2" + jest-canvas-mock: "npm:^2.5.2" lodash: "npm:^4.17.21" tslib: "npm:^2.8.1" peerDependencies: + echarts: ^5.6.0 react: ^17 || ^18 react-dom: ^17 || ^18 victory-area: ^37.3.6 @@ -3664,6 +3666,8 @@ __metadata: victory-voronoi-container: ^37.3.6 victory-zoom-container: ^37.3.6 peerDependenciesMeta: + echarts: + optional: true victory-area: optional: true victory-axis: @@ -3722,7 +3726,7 @@ __metadata: version: 0.0.0-use.local resolution: "@patternfly/react-core@workspace:packages/react-core" dependencies: - "@patternfly/patternfly": "npm:6.2.0-prerelease.14" + "@patternfly/patternfly": "npm:6.2.0-prerelease.15" "@patternfly/react-icons": "workspace:^" "@patternfly/react-styles": "workspace:^" "@patternfly/react-tokens": "workspace:^" @@ -3743,7 +3747,7 @@ __metadata: resolution: "@patternfly/react-docs@workspace:packages/react-docs" dependencies: "@patternfly/documentation-framework": "npm:^6.5.15" - "@patternfly/patternfly": "npm:6.2.0-prerelease.14" + "@patternfly/patternfly": "npm:6.2.0-prerelease.15" "@patternfly/patternfly-a11y": "npm:5.1.0" "@patternfly/react-charts": "workspace:^" "@patternfly/react-code-editor": "workspace:^" @@ -3754,6 +3758,7 @@ __metadata: "@patternfly/react-table": "workspace:^" "@patternfly/react-templates": "workspace:^" "@patternfly/react-tokens": "workspace:^" + echarts: "npm:^5.6.0" victory: "npm:^37.3.6" languageName: unknown linkType: soft @@ -3782,7 +3787,7 @@ __metadata: "@fortawesome/free-brands-svg-icons": "npm:^5.15.4" "@fortawesome/free-regular-svg-icons": "npm:^5.15.4" "@fortawesome/free-solid-svg-icons": "npm:^5.15.4" - "@patternfly/patternfly": "npm:6.2.0-prerelease.14" + "@patternfly/patternfly": "npm:6.2.0-prerelease.15" fs-extra: "npm:^11.3.0" tslib: "npm:^2.8.1" peerDependencies: @@ -3866,7 +3871,7 @@ __metadata: version: 0.0.0-use.local resolution: "@patternfly/react-styles@workspace:packages/react-styles" dependencies: - "@patternfly/patternfly": "npm:6.2.0-prerelease.14" + "@patternfly/patternfly": "npm:6.2.0-prerelease.15" change-case: "npm:^5.4.4" fs-extra: "npm:^11.3.0" languageName: unknown @@ -3907,7 +3912,7 @@ __metadata: version: 0.0.0-use.local resolution: "@patternfly/react-tokens@workspace:packages/react-tokens" dependencies: - "@patternfly/patternfly": "npm:6.2.0-prerelease.14" + "@patternfly/patternfly": "npm:6.2.0-prerelease.15" css: "npm:^3.0.0" fs-extra: "npm:^11.3.0" languageName: unknown @@ -7693,7 +7698,7 @@ __metadata: languageName: node linkType: hard -"color-name@npm:^1.0.0, color-name@npm:~1.1.4": +"color-name@npm:^1.0.0, color-name@npm:^1.1.4, color-name@npm:~1.1.4": version: 1.1.4 resolution: "color-name@npm:1.1.4" checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95 @@ -8358,6 +8363,13 @@ __metadata: languageName: node linkType: hard +"cssfontparser@npm:^1.2.1": + version: 1.2.1 + resolution: "cssfontparser@npm:1.2.1" + checksum: 10c0/ceb9b2976d503dbff3ac2aff0229b263affb4fb221a6947b357682cd8a952f6995253646ca5f820020d2fe05b5e29b56dbdd2343388c32203e8dd0ed15bdc1ca + languageName: node + linkType: hard + "cssom@npm:^0.5.0": version: 0.5.0 resolution: "cssom@npm:0.5.0" @@ -9292,6 +9304,16 @@ __metadata: languageName: node linkType: hard +"echarts@npm:^5.6.0": + version: 5.6.0 + resolution: "echarts@npm:5.6.0" + dependencies: + tslib: "npm:2.3.0" + zrender: "npm:5.6.1" + checksum: 10c0/6d6a2ee88534d1ff0433e935c542237b9896de1c94959f47ebc7e0e9da26f59bf11c91ed6fc135b62ad2786c779ee12bc536fa481e60532dad5b6a2f5167e9ea + languageName: node + linkType: hard + "editions@npm:^2.2.0": version: 2.3.1 resolution: "editions@npm:2.3.1" @@ -13720,6 +13742,16 @@ __metadata: languageName: node linkType: hard +"jest-canvas-mock@npm:^2.5.2": + version: 2.5.2 + resolution: "jest-canvas-mock@npm:2.5.2" + dependencies: + cssfontparser: "npm:^1.2.1" + moo-color: "npm:^1.0.2" + checksum: 10c0/6a4190354b1e9aedcb3045273f13f6f1d2d1efb00cfe6458707fae538a8f91f6afdf72b9e201b653666863054edc783428bdc0c1a2c71d66d9ac364b4893f6d6 + languageName: node + linkType: hard + "jest-changed-files@npm:^29.7.0": version: 29.7.0 resolution: "jest-changed-files@npm:29.7.0" @@ -15798,6 +15830,15 @@ __metadata: languageName: node linkType: hard +"moo-color@npm:^1.0.2": + version: 1.0.3 + resolution: "moo-color@npm:1.0.3" + dependencies: + color-name: "npm:^1.1.4" + checksum: 10c0/778c82f67f638c03a1d0fa78dcd6ea376a9f17b5e78e349c7e34a290b496dbdb43fd0b1c38070e2062d5e784bcf08e57f499015fcbcf52b3a1887d7825ebb80d + languageName: node + linkType: hard + "move-concurrently@npm:^1.0.1": version: 1.0.1 resolution: "move-concurrently@npm:1.0.1" @@ -21139,6 +21180,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:2.3.0": + version: 2.3.0 + resolution: "tslib@npm:2.3.0" + checksum: 10c0/a845aed84e7e7dbb4c774582da60d7030ea39d67307250442d35c4c5dd77e4b44007098c37dd079e100029c76055f2a362734b8442ba828f8cc934f15ed9be61 + languageName: node + linkType: hard + "tslib@npm:^1.8.1, tslib@npm:^1.9.0": version: 1.14.1 resolution: "tslib@npm:1.14.1" @@ -23382,3 +23430,12 @@ __metadata: checksum: 10c0/8f14c87d6b1b53c944c25ce7a28616896319d95bc46a9660fe441adc0ed0a81253b02b5abdaeffedbeb23bdd25a0bf1c29d2c12dd919aef6447652dd295e3e69 languageName: node linkType: hard + +"zrender@npm:5.6.1": + version: 5.6.1 + resolution: "zrender@npm:5.6.1" + dependencies: + tslib: "npm:2.3.0" + checksum: 10c0/dc1cc570054640cbd8fbb7b92e6252f225319522bfe3e8dc8bf02cc02d414e00a4c8d0a6f89bfc9d96e5e9511fdca94dd3d06bf53690df2b2f12b0fc560ac307 + languageName: node + linkType: hard