From b631eb9a84ee7b2846ccf25599a2015013f7252c Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 8 Feb 2024 15:19:33 +0100 Subject: [PATCH 01/20] [charts] Add Gauge component --- packages/x-charts/src/ChartsSurface.tsx | 6 +- packages/x-charts/src/Gauge/Gauge.tsx | 35 ++++ .../x-charts/src/Gauge/GaugeContainer.tsx | 118 +++++++++++ packages/x-charts/src/Gauge/GaugeProvider.tsx | 190 ++++++++++++++++++ .../x-charts/src/Gauge/GaugeReferenceArc.tsx | 31 +++ packages/x-charts/src/Gauge/GaugeValueArc.tsx | 48 +++++ packages/x-charts/src/Gauge/gaugeClasses.ts | 25 +++ packages/x-charts/src/Gauge/index.ts | 4 + packages/x-charts/src/Gauge/utils.ts | 88 ++++++++ .../ResponsiveChartContainer.tsx | 90 +-------- .../useChartContainerDimensions.ts | 88 ++++++++ packages/x-charts/src/index.ts | 1 + scripts/x-charts.exports.json | 6 + 13 files changed, 640 insertions(+), 90 deletions(-) create mode 100644 packages/x-charts/src/Gauge/Gauge.tsx create mode 100644 packages/x-charts/src/Gauge/GaugeContainer.tsx create mode 100644 packages/x-charts/src/Gauge/GaugeProvider.tsx create mode 100644 packages/x-charts/src/Gauge/GaugeReferenceArc.tsx create mode 100644 packages/x-charts/src/Gauge/GaugeValueArc.tsx create mode 100644 packages/x-charts/src/Gauge/gaugeClasses.ts create mode 100644 packages/x-charts/src/Gauge/index.ts create mode 100644 packages/x-charts/src/Gauge/utils.ts create mode 100644 packages/x-charts/src/ResponsiveChartContainer/useChartContainerDimensions.ts diff --git a/packages/x-charts/src/ChartsSurface.tsx b/packages/x-charts/src/ChartsSurface.tsx index eb25424fed833..3cbcac24ebf00 100644 --- a/packages/x-charts/src/ChartsSurface.tsx +++ b/packages/x-charts/src/ChartsSurface.tsx @@ -48,6 +48,8 @@ const ChartsSurface = React.forwardRef(functi viewBox, disableAxisListener = false, className, + title, + desc, ...other } = props; const svgView = { width, height, x: 0, y: 0, ...viewBox }; @@ -62,8 +64,8 @@ const ChartsSurface = React.forwardRef(functi ref={ref} {...other} > - {props.title} - {props.desc} + {title} + {desc} {children} ); diff --git a/packages/x-charts/src/Gauge/Gauge.tsx b/packages/x-charts/src/Gauge/Gauge.tsx new file mode 100644 index 0000000000000..ff41cdeca4ffa --- /dev/null +++ b/packages/x-charts/src/Gauge/Gauge.tsx @@ -0,0 +1,35 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import composeClasses from '@mui/utils/composeClasses'; +import { GaugeContainer, GaugeContainerProps } from './GaugeContainer'; +import { GaugeValueArc } from './GaugeValueArc'; +import { GaugeReferenceArc } from './GaugeReferenceArc'; +import { GaugeClasses, getGaugeUtilityClass } from './gaugeClasses'; + +export interface GaugeProps extends GaugeContainerProps { + classes?: Partial; +} + +const useUtilityClasses = (props: GaugeProps) => { + const { classes } = props; + + const slots = { + root: ['root'], + valueArc: ['valueArc'], + referenceArc: ['referenceArc'], + }; + + return composeClasses(slots, getGaugeUtilityClass, classes); +}; + +function Gauge(props: GaugeProps) { + const classes = useUtilityClasses(props); + return ( + + + + + ); +} + +export { Gauge }; diff --git a/packages/x-charts/src/Gauge/GaugeContainer.tsx b/packages/x-charts/src/Gauge/GaugeContainer.tsx new file mode 100644 index 0000000000000..2a519832d7818 --- /dev/null +++ b/packages/x-charts/src/Gauge/GaugeContainer.tsx @@ -0,0 +1,118 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import useForkRef from '@mui/utils/useForkRef'; +import { styled } from '@mui/material/styles'; +import { useChartContainerDimensions } from '../ResponsiveChartContainer/useChartContainerDimensions'; +import { ChartsSurface, ChartsSurfaceProps } from '../ChartsSurface'; +import { DrawingProvider, DrawingProviderProps } from '../context/DrawingProvider'; +import { GaugeProvider, GaugeProviderProps } from './GaugeProvider'; + +export interface GaugeContainerProps + extends Omit, + Omit, + Omit { + /** + * The width of the chart in px. If not defined, it takes the width of the parent element. + * @default undefined + */ + width?: number; + /** + * The height of the chart in px. If not defined, it takes the height of the parent element. + * @default undefined + */ + height?: number; + children?: React.ReactNode; +} + +const ResizableContainer = styled('div', { + name: 'MuiGauge', + slot: 'Container', +})<{ ownerState: Pick }>(({ ownerState }) => ({ + width: ownerState.width ?? '100%', + height: ownerState.height ?? '100%', + display: 'flex', + position: 'relative', + flexGrow: 1, + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + overflow: 'hidden', + '&>svg': { + width: '100%', + height: '100%', + }, +})); + +const GaugeContainer = React.forwardRef(function GaugeContainer(props: GaugeContainerProps, ref) { + const { + width: inWidth, + height: inHeight, + margin, + title, + desc, + value, + valueMin = 0, + valueMax = 100, + startAngle, + endAngle, + outerRadius, + innerRadius, + cornerRadius, + cx, + cy, + children, + ...other + } = props; + const [containerRef, width, height] = useChartContainerDimensions(inWidth, inHeight); + + const svgRef = React.useRef(null); + const handleRef = useForkRef(ref, svgRef); + + return ( + + {width && height ? ( + + + + + + ) : null} + + ); +}); + +export { GaugeContainer }; diff --git a/packages/x-charts/src/Gauge/GaugeProvider.tsx b/packages/x-charts/src/Gauge/GaugeProvider.tsx new file mode 100644 index 0000000000000..98b7c8a5c5442 --- /dev/null +++ b/packages/x-charts/src/Gauge/GaugeProvider.tsx @@ -0,0 +1,190 @@ +// @ignore - do not document. +import * as React from 'react'; +import { DrawingContext } from '../context/DrawingProvider'; +import { getPercentageValue } from '../internals/utils'; +import { getArcRatios, getAvailableRadius } from './utils'; + +interface CircularConfig { + /** + * The start angle (deg). + * @default 0 + */ + startAngle?: number; + /** + * The end angle (deg). + * @default 360 + */ + endAngle?: number; + /** + * The radius between circle center and the begining of the arc. + * Can be a number (in px) or a string with a percentage such as '50%'. + * The '100%' is the maximal radius that fit into the drawing area. + * @default '80%' + */ + innerRadius?: number | string; + /** + * The radius between circle center and the end of the arc. + * Can be a number (in px) or a string with a percentage such as '50%'. + * The '100%' is the maximal radius that fit into the drawing area. + * @default '100%' + */ + outerRadius?: number | string; + /** + * The radius applied to arc corners (similar to border radius). + * @default '50%' + */ + cornerRadius?: number; + /** + * The x coordinate of the pie center. + * Can be a number (in px) or a string with a percentage such as '50%'. + * The '100%' is the width the drawing area. + */ + cx?: number | string; + /** + * The y coordinate of the pie center. + * Can be a number (in px) or a string with a percentage such as '50%'. + * The '100%' is the height the drawing area. + */ + cy?: number | string; +} + +interface ProcessedCircularConfig { + /** + * The start angle (rad). + */ + startAngle: number; + /** + * The end angle (rad). + */ + endAngle: number; + /** + * The radius between circle center and the begining of the arc. + */ + innerRadius: number; + /** + * The radius between circle center and the end of the arc. + */ + outerRadius: number; + /** + * The radius applied to arc corners (similar to border radius). + */ + cornerRadius: number; + /** + * The x coordinate of the pie center. + */ + cx: number; + /** + * The y coordinate of the pie center. + */ + cy: number; +} + +interface GaugeConfig { + /** + * The value of the gauge. + * Set to `null` if no value to display. + */ + value?: number | null; + /** + * The minimal value of the gauge. + * @default 0 + */ + valueMin?: number; + /** + * The maximal value of the gauge. + * @default 100 + */ + valueMax?: number; +} + +export const GaugeContext = React.createContext & ProcessedCircularConfig>({ + value: null, + valueMin: 0, + valueMax: 0, + startAngle: 0, + endAngle: 0, + innerRadius: 0, + outerRadius: 0, + cornerRadius: 0, + cx: 0, + cy: 0, +}); + +export interface GaugeProviderProps extends GaugeConfig, CircularConfig { + children: React.ReactNode; +} + +export function GaugeProvider(props: GaugeProviderProps) { + const { + value = null, + valueMin = 0, + valueMax = 100, + startAngle = 0, + endAngle = 360, + outerRadius: outerRadiusParam, + innerRadius: innerRadiusParam, + cornerRadius: cornerRadiusParam, + cx: cxParam, + cy: cyParam, + children, + } = props; + + const { width, height, top, left } = React.useContext(DrawingContext); + + const ratios = getArcRatios(startAngle, endAngle); + + const innerCx = cxParam ? getPercentageValue(cxParam, width) : ratios.cx * width; + const innerCy = cyParam ? getPercentageValue(cyParam, height) : ratios.cy * height; + + let cx = left + innerCx; + let cy = top + innerCy; + + const availableRadius = getAvailableRadius(innerCx, innerCy, width, height, ratios); + + // If the center is not defined, after computation of the available radius, udpate the center to use the remaining space. + if (cxParam === undefined) { + const usedWidth = availableRadius * (ratios.maxX - ratios.minX); + cx = left + (width - usedWidth) / 2 + ratios.cx * usedWidth; + } + if (cyParam === undefined) { + const usedHeight = availableRadius * (ratios.maxY - ratios.minY); + cy = top + (height - usedHeight) / 2 + ratios.cy * usedHeight; + } + + const outerRadius = getPercentageValue(outerRadiusParam ?? availableRadius, availableRadius); + const innerRadius = getPercentageValue(innerRadiusParam ?? '80%', availableRadius); + const cornerRadius = getPercentageValue(cornerRadiusParam ?? '50%', outerRadius - innerRadius); + + const contextValue = React.useMemo( + () => ({ + value, + valueMin, + valueMax, + startAngle: (Math.PI * startAngle) / 180, + endAngle: (Math.PI * endAngle) / 180, + outerRadius, + innerRadius, + cornerRadius, + cx, + cy, + }), + [ + value, + valueMin, + valueMax, + startAngle, + endAngle, + outerRadius, + innerRadius, + cornerRadius, + cx, + cy, + ], + ); + + return {children}; +} + +export function useGaugeState() { + return React.useContext(GaugeContext); +} diff --git a/packages/x-charts/src/Gauge/GaugeReferenceArc.tsx b/packages/x-charts/src/Gauge/GaugeReferenceArc.tsx new file mode 100644 index 0000000000000..65bd8ebb4d306 --- /dev/null +++ b/packages/x-charts/src/Gauge/GaugeReferenceArc.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; +import { arc as d3Arc } from 'd3-shape'; +import styled from '@mui/system/styled'; +import { useGaugeState } from './GaugeProvider'; + +const StyledPath = styled('path', { + name: 'MuiGauge', + slot: 'ReferenceArc', + overridesResolver: (props, styles) => styles.referenceArc, +})(({ theme }) => ({ + fill: theme.palette.divider, +})); + +export function GaugeReferenceArc(props: React.ComponentProps<'path'>) { + const { startAngle, endAngle, outerRadius, innerRadius, cornerRadius, cx, cy } = useGaugeState(); + + return ( + + ); +} diff --git a/packages/x-charts/src/Gauge/GaugeValueArc.tsx b/packages/x-charts/src/Gauge/GaugeValueArc.tsx new file mode 100644 index 0000000000000..ff64647789894 --- /dev/null +++ b/packages/x-charts/src/Gauge/GaugeValueArc.tsx @@ -0,0 +1,48 @@ +import * as React from 'react'; +import { arc as d3Arc } from 'd3-shape'; +import styled from '@mui/system/styled'; +import { useGaugeState } from './GaugeProvider'; + +const StyledPath = styled('path', { + name: 'MuiGauge', + slot: 'ReferenceArc', + overridesResolver: (props, styles) => styles.referenceArc, +})(({ theme }) => ({ + fill: theme.palette.primary.main, +})); + +export function GaugeValueArc(props: React.ComponentProps<'path'>) { + const { + value, + valueMin, + valueMax, + startAngle, + endAngle, + outerRadius, + innerRadius, + cornerRadius, + cx, + cy, + } = useGaugeState(); + + if (value === null) { + return null; + } + const valueAngle = + startAngle + ((value - valueMin) / (valueMax - valueMin)) * (endAngle - startAngle); + + return ( + + ); +} diff --git a/packages/x-charts/src/Gauge/gaugeClasses.ts b/packages/x-charts/src/Gauge/gaugeClasses.ts new file mode 100644 index 0000000000000..759dc90a86995 --- /dev/null +++ b/packages/x-charts/src/Gauge/gaugeClasses.ts @@ -0,0 +1,25 @@ +import generateUtilityClasses from '@mui/utils/generateUtilityClasses'; +import generateUtilityClass from '@mui/utils/generateUtilityClass'; + +export interface GaugeClasses { + /** Styles applied to the root element. */ + root: string; + /** Styles applied to the arc diplaying the value. */ + valueArc: string; + /** Styles applied to the arc diplaying the range of available values. */ + referenceArc: string; +} + +export type GaugeClassKey = keyof GaugeClasses; + +export function getGaugeUtilityClass(slot: string): string { + return generateUtilityClass('MuiGauge', slot); +} + +const gaugeClasses: GaugeClasses = generateUtilityClasses('MuiGauge', [ + 'root', + 'valueArc', + 'referenceArc', +]); + +export default gaugeClasses; diff --git a/packages/x-charts/src/Gauge/index.ts b/packages/x-charts/src/Gauge/index.ts new file mode 100644 index 0000000000000..794b7af69a651 --- /dev/null +++ b/packages/x-charts/src/Gauge/index.ts @@ -0,0 +1,4 @@ +export * from './Gauge'; +export * from './GaugeContainer'; +export * from './GaugeValueArc'; +export * from './GaugeReferenceArc'; diff --git a/packages/x-charts/src/Gauge/utils.ts b/packages/x-charts/src/Gauge/utils.ts new file mode 100644 index 0000000000000..b78e37cd30349 --- /dev/null +++ b/packages/x-charts/src/Gauge/utils.ts @@ -0,0 +1,88 @@ +function deg2rad(angle: number) { + return (Math.PI * angle) / 180; +} +function getPoint(angle: number): [number, number] { + const radAngle = deg2rad(angle); + return [Math.sin(radAngle), -Math.cos(radAngle)]; +} + +/** + * Retruns the ratio of the arc bounding box and its center. + * @param startAngle The start angle (in deg) + * @param endAngle The end angle (in deg) + */ +export function getArcRatios(startAngle: number, endAngle: number) { + // Set the start, end and center point. + const points = [[0, 0], getPoint(startAngle), getPoint(endAngle)]; + + // Add cardinals points included in the arc + const minAngle = Math.min(startAngle, endAngle); + const maxAngle = Math.max(startAngle, endAngle); + + const initialAngle = Math.floor(minAngle / 90) * 90; + + for (let step = 1; step <= 4; step += 1) { + const cartinalAngle = initialAngle + step * 90; + if (cartinalAngle < maxAngle) { + points.push(getPoint(cartinalAngle)); + } + } + + const minX = Math.min(...points.map(([x]) => x)); + const maxX = Math.max(...points.map(([x]) => x)); + const minY = Math.min(...points.map(([, y]) => y)); + const maxY = Math.max(...points.map(([, y]) => y)); + + return { + cx: -minX / (maxX - minX), + cy: -minY / (maxY - minY), + minX, + maxX, + minY, + maxY, + }; +} + +export function getAvailableRadius( + cx: number, + cy: number, + width: number, + height: number, + { + minX, + maxX, + minY, + maxY, + }: { + minX: number; + maxX: number; + minY: number; + maxY: number; + }, +) { + return Math.min( + ...[ + { + ratio: Math.abs(minX), + space: cx, + }, + { + ratio: Math.abs(maxX), + space: width - cx, + }, + { + ratio: Math.abs(minY), + space: cy, + }, + { + ratio: Math.abs(maxY), + space: height - cy, + }, + ].map(({ ratio, space }) => { + if (ratio < 0.00001) { + return Infinity; + } + return space / ratio; + }), + ); +} diff --git a/packages/x-charts/src/ResponsiveChartContainer/ResponsiveChartContainer.tsx b/packages/x-charts/src/ResponsiveChartContainer/ResponsiveChartContainer.tsx index a3928044c04ea..3059e7f0ac8b0 100644 --- a/packages/x-charts/src/ResponsiveChartContainer/ResponsiveChartContainer.tsx +++ b/packages/x-charts/src/ResponsiveChartContainer/ResponsiveChartContainer.tsx @@ -1,94 +1,8 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import useEnhancedEffect from '@mui/utils/useEnhancedEffect'; -import ownerWindow from '@mui/utils/ownerWindow'; import { styled } from '@mui/material/styles'; import { ChartContainer, ChartContainerProps } from '../ChartContainer'; - -const useChartDimensions = ( - inWidth?: number, - inHeight?: number, -): [React.RefObject, number, number] => { - const rootRef = React.useRef(null); - const displayError = React.useRef(false); - - const [width, setWidth] = React.useState(0); - const [height, setHeight] = React.useState(0); - - // Adaptation of the `computeSizeAndPublishResizeEvent` from the grid. - const computeSize = React.useCallback(() => { - const mainEl = rootRef?.current; - - if (!mainEl) { - return; - } - - const win = ownerWindow(mainEl); - const computedStyle = win.getComputedStyle(mainEl); - - const newHeight = Math.floor(parseFloat(computedStyle.height)) || 0; - const newWidth = Math.floor(parseFloat(computedStyle.width)) || 0; - - setWidth(newWidth); - setHeight(newHeight); - }, []); - - React.useEffect(() => { - // Ensure the error detection occurs after the first rendering. - displayError.current = true; - }, []); - - useEnhancedEffect(() => { - if (inWidth !== undefined && inHeight !== undefined) { - return () => {}; - } - computeSize(); - - const elementToObserve = rootRef.current; - if (typeof ResizeObserver === 'undefined') { - return () => {}; - } - - let animationFrame: number; - const observer = new ResizeObserver(() => { - // See https://github.com/mui/mui-x/issues/8733 - animationFrame = requestAnimationFrame(() => { - computeSize(); - }); - }); - - if (elementToObserve) { - observer.observe(elementToObserve); - } - - return () => { - if (animationFrame) { - window.cancelAnimationFrame(animationFrame); - } - - if (elementToObserve) { - observer.unobserve(elementToObserve); - } - }; - }, [computeSize, inHeight, inWidth]); - - if (process.env.NODE_ENV !== 'production') { - if (displayError.current && inWidth === undefined && width === 0) { - console.error( - `MUI X Charts: ChartContainer does not have \`width\` prop, and its container has no \`width\` defined.`, - ); - displayError.current = false; - } - if (displayError.current && inHeight === undefined && height === 0) { - console.error( - `MUI X Charts: ChartContainer does not have \`height\` prop, and its container has no \`height\` defined.`, - ); - displayError.current = false; - } - } - - return [rootRef, inWidth ?? width, inHeight ?? height]; -}; +import { useChartContainerDimensions } from './useChartContainerDimensions'; export interface ResponsiveChartContainerProps extends Omit { @@ -128,7 +42,7 @@ const ResponsiveChartContainer = React.forwardRef(function ResponsiveChartContai ref, ) { const { width: inWidth, height: inHeight, ...other } = props; - const [containerRef, width, height] = useChartDimensions(inWidth, inHeight); + const [containerRef, width, height] = useChartContainerDimensions(inWidth, inHeight); return ( diff --git a/packages/x-charts/src/ResponsiveChartContainer/useChartContainerDimensions.ts b/packages/x-charts/src/ResponsiveChartContainer/useChartContainerDimensions.ts new file mode 100644 index 0000000000000..4e82a43889af0 --- /dev/null +++ b/packages/x-charts/src/ResponsiveChartContainer/useChartContainerDimensions.ts @@ -0,0 +1,88 @@ +import * as React from 'react'; +import useEnhancedEffect from '@mui/utils/useEnhancedEffect'; +import ownerWindow from '@mui/utils/ownerWindow'; + +export const useChartContainerDimensions = ( + inWidth?: number, + inHeight?: number, +): [React.RefObject, number, number] => { + const rootRef = React.useRef(null); + const displayError = React.useRef(false); + + const [width, setWidth] = React.useState(0); + const [height, setHeight] = React.useState(0); + + // Adaptation of the `computeSizeAndPublishResizeEvent` from the grid. + const computeSize = React.useCallback(() => { + const mainEl = rootRef?.current; + + if (!mainEl) { + return; + } + + const win = ownerWindow(mainEl); + const computedStyle = win.getComputedStyle(mainEl); + + const newHeight = Math.floor(parseFloat(computedStyle.height)) || 0; + const newWidth = Math.floor(parseFloat(computedStyle.width)) || 0; + + setWidth(newWidth); + setHeight(newHeight); + }, []); + + React.useEffect(() => { + // Ensure the error detection occurs after the first rendering. + displayError.current = true; + }, []); + + useEnhancedEffect(() => { + if (inWidth !== undefined && inHeight !== undefined) { + return () => {}; + } + computeSize(); + + const elementToObserve = rootRef.current; + if (typeof ResizeObserver === 'undefined') { + return () => {}; + } + + let animationFrame: number; + const observer = new ResizeObserver(() => { + // See https://github.com/mui/mui-x/issues/8733 + animationFrame = requestAnimationFrame(() => { + computeSize(); + }); + }); + + if (elementToObserve) { + observer.observe(elementToObserve); + } + + return () => { + if (animationFrame) { + window.cancelAnimationFrame(animationFrame); + } + + if (elementToObserve) { + observer.unobserve(elementToObserve); + } + }; + }, [computeSize, inHeight, inWidth]); + + if (process.env.NODE_ENV !== 'production') { + if (displayError.current && inWidth === undefined && width === 0) { + console.error( + `MUI X Charts: ChartContainer does not have \`width\` prop, and its container has no \`width\` defined.`, + ); + displayError.current = false; + } + if (displayError.current && inHeight === undefined && height === 0) { + console.error( + `MUI X Charts: ChartContainer does not have \`height\` prop, and its container has no \`height\` defined.`, + ); + displayError.current = false; + } + } + + return [rootRef, inWidth ?? width, inHeight ?? height]; +}; diff --git a/packages/x-charts/src/index.ts b/packages/x-charts/src/index.ts index 750a9107003e6..fd9e33edda749 100644 --- a/packages/x-charts/src/index.ts +++ b/packages/x-charts/src/index.ts @@ -19,6 +19,7 @@ export * from './LineChart'; export * from './PieChart'; export * from './ScatterChart'; export * from './SparkLineChart'; +export * from './Gauge'; export * from './ChartContainer'; export * from './ChartsSurface'; export * from './ResponsiveChartContainer'; diff --git a/scripts/x-charts.exports.json b/scripts/x-charts.exports.json index f89d9267c0540..96e471acb2f31 100644 --- a/scripts/x-charts.exports.json +++ b/scripts/x-charts.exports.json @@ -121,6 +121,12 @@ { "name": "Direction", "kind": "TypeAlias" }, { "name": "DrawingProvider", "kind": "Function" }, { "name": "FadeOptions", "kind": "TypeAlias" }, + { "name": "Gauge", "kind": "Function" }, + { "name": "GaugeContainer", "kind": "Variable" }, + { "name": "GaugeContainerProps", "kind": "Interface" }, + { "name": "GaugeProps", "kind": "Interface" }, + { "name": "GaugeReferenceArc", "kind": "Function" }, + { "name": "GaugeValueArc", "kind": "Function" }, { "name": "getAreaElementUtilityClass", "kind": "Function" }, { "name": "getAxisHighlightUtilityClass", "kind": "Function" }, { "name": "getAxisUtilityClass", "kind": "Function" }, From 821beba3253c71f0d351a0141c4ba6ac3aef0f75 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 8 Feb 2024 15:20:08 +0100 Subject: [PATCH 02/20] Run scripts --- docs/data/charts-component-api-pages.ts | 8 ++ docs/pages/x/api/charts/gauge-container.js | 23 ++++ docs/pages/x/api/charts/gauge-container.json | 41 +++++++ docs/pages/x/api/charts/gauge.js | 23 ++++ docs/pages/x/api/charts/gauge.json | 60 ++++++++++ .../gauge-container/gauge-container.json | 40 +++++++ .../api-docs/charts/gauge/gauge.json | 50 ++++++++ packages/x-charts/src/Gauge/Gauge.tsx | 107 ++++++++++++++++++ .../x-charts/src/Gauge/GaugeContainer.tsx | 106 +++++++++++++++++ scripts/buildApiDocs/chartsSettings/index.ts | 8 +- 10 files changed, 465 insertions(+), 1 deletion(-) create mode 100644 docs/pages/x/api/charts/gauge-container.js create mode 100644 docs/pages/x/api/charts/gauge-container.json create mode 100644 docs/pages/x/api/charts/gauge.js create mode 100644 docs/pages/x/api/charts/gauge.json create mode 100644 docs/translations/api-docs/charts/gauge-container/gauge-container.json create mode 100644 docs/translations/api-docs/charts/gauge/gauge.json diff --git a/docs/data/charts-component-api-pages.ts b/docs/data/charts-component-api-pages.ts index 76bc2512caa06..e352d14101a64 100644 --- a/docs/data/charts-component-api-pages.ts +++ b/docs/data/charts-component-api-pages.ts @@ -93,6 +93,14 @@ const apiPages: MuiPage[] = [ pathname: '/x/api/charts/default-charts-legend', title: 'DefaultChartsLegend', }, + { + pathname: '/x/api/charts/gauge', + title: 'Gauge', + }, + { + pathname: '/x/api/charts/gauge-container', + title: 'GaugeContainer', + }, { pathname: '/x/api/charts/line-chart', title: 'LineChart', diff --git a/docs/pages/x/api/charts/gauge-container.js b/docs/pages/x/api/charts/gauge-container.js new file mode 100644 index 0000000000000..7b2fc51b7afc3 --- /dev/null +++ b/docs/pages/x/api/charts/gauge-container.js @@ -0,0 +1,23 @@ +import * as React from 'react'; +import ApiPage from 'docs/src/modules/components/ApiPage'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './gauge-container.json'; + +export default function Page(props) { + const { descriptions, pageContent } = props; + return ; +} + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/charts/gauge-container', + false, + /\.\/gauge-container.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/charts/gauge-container.json b/docs/pages/x/api/charts/gauge-container.json new file mode 100644 index 0000000000000..80d1aff0376c7 --- /dev/null +++ b/docs/pages/x/api/charts/gauge-container.json @@ -0,0 +1,41 @@ +{ + "props": { + "cornerRadius": { "type": { "name": "number" }, "default": "'50%'" }, + "cx": { "type": { "name": "union", "description": "number
| string" } }, + "cy": { "type": { "name": "union", "description": "number
| string" } }, + "disableAxisListener": { "type": { "name": "bool" }, "default": "false" }, + "endAngle": { "type": { "name": "number" }, "default": "360" }, + "height": { "type": { "name": "number" }, "default": "undefined" }, + "innerRadius": { + "type": { "name": "union", "description": "number
| string" }, + "default": "'80%'" + }, + "margin": { + "type": { + "name": "shape", + "description": "{ bottom?: number, left?: number, right?: number, top?: number }" + }, + "default": "object Depends on the charts type." + }, + "outerRadius": { + "type": { "name": "union", "description": "number
| string" }, + "default": "'100%'" + }, + "startAngle": { "type": { "name": "number" }, "default": "0" }, + "value": { "type": { "name": "number" } }, + "valueMax": { "type": { "name": "number" }, "default": "100" }, + "valueMin": { "type": { "name": "number" }, "default": "0" }, + "width": { "type": { "name": "number" }, "default": "undefined" } + }, + "name": "GaugeContainer", + "imports": [ + "import { GaugeContainer } from '@mui/x-charts/Gauge';", + "import { GaugeContainer } from '@mui/x-charts';" + ], + "classes": [], + "muiName": "MuiGaugeContainer", + "filename": "/packages/x-charts/src/Gauge/GaugeContainer.tsx", + "inheritance": null, + "demos": "", + "cssComponent": false +} diff --git a/docs/pages/x/api/charts/gauge.js b/docs/pages/x/api/charts/gauge.js new file mode 100644 index 0000000000000..4b4dfa2025075 --- /dev/null +++ b/docs/pages/x/api/charts/gauge.js @@ -0,0 +1,23 @@ +import * as React from 'react'; +import ApiPage from 'docs/src/modules/components/ApiPage'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './gauge.json'; + +export default function Page(props) { + const { descriptions, pageContent } = props; + return ; +} + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/charts/gauge', + false, + /\.\/gauge.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/charts/gauge.json b/docs/pages/x/api/charts/gauge.json new file mode 100644 index 0000000000000..c1284e25f1151 --- /dev/null +++ b/docs/pages/x/api/charts/gauge.json @@ -0,0 +1,60 @@ +{ + "props": { + "cornerRadius": { "type": { "name": "number" }, "default": "'50%'" }, + "cx": { "type": { "name": "union", "description": "number
| string" } }, + "cy": { "type": { "name": "union", "description": "number
| string" } }, + "disableAxisListener": { "type": { "name": "bool" }, "default": "false" }, + "endAngle": { "type": { "name": "number" }, "default": "360" }, + "height": { "type": { "name": "number" }, "default": "undefined" }, + "innerRadius": { + "type": { "name": "union", "description": "number
| string" }, + "default": "'80%'" + }, + "margin": { + "type": { + "name": "shape", + "description": "{ bottom?: number, left?: number, right?: number, top?: number }" + }, + "default": "object Depends on the charts type." + }, + "outerRadius": { + "type": { "name": "union", "description": "number
| string" }, + "default": "'100%'" + }, + "startAngle": { "type": { "name": "number" }, "default": "0" }, + "value": { "type": { "name": "number" } }, + "valueMax": { "type": { "name": "number" }, "default": "100" }, + "valueMin": { "type": { "name": "number" }, "default": "0" }, + "width": { "type": { "name": "number" }, "default": "undefined" } + }, + "name": "Gauge", + "imports": [ + "import { Gauge } from '@mui/x-charts/Gauge';", + "import { Gauge } from '@mui/x-charts';" + ], + "classes": [ + { + "key": "referenceArc", + "className": "MuiGauge-referenceArc", + "description": "Styles applied to the arc diplaying the range of available values.", + "isGlobal": false + }, + { + "key": "root", + "className": "MuiGauge-root", + "description": "Styles applied to the root element.", + "isGlobal": false + }, + { + "key": "valueArc", + "className": "MuiGauge-valueArc", + "description": "Styles applied to the arc diplaying the value.", + "isGlobal": false + } + ], + "muiName": "MuiGauge", + "filename": "/packages/x-charts/src/Gauge/Gauge.tsx", + "inheritance": null, + "demos": "", + "cssComponent": false +} diff --git a/docs/translations/api-docs/charts/gauge-container/gauge-container.json b/docs/translations/api-docs/charts/gauge-container/gauge-container.json new file mode 100644 index 0000000000000..6c230d3a76104 --- /dev/null +++ b/docs/translations/api-docs/charts/gauge-container/gauge-container.json @@ -0,0 +1,40 @@ +{ + "componentDescription": "", + "propDescriptions": { + "cornerRadius": { + "description": "The radius applied to arc corners (similar to border radius)." + }, + "cx": { + "description": "The x coordinate of the pie center. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the width the drawing area." + }, + "cy": { + "description": "The y coordinate of the pie center. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the height the drawing area." + }, + "disableAxisListener": { + "description": "If true, the charts will not listen to the mouse move event. It might break interactive features, but will improve performance." + }, + "endAngle": { "description": "The end angle (deg)." }, + "height": { + "description": "The height of the chart in px. If not defined, it takes the height of the parent element." + }, + "innerRadius": { + "description": "The radius between circle center and the begining of the arc. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the maximal radius that fit into the drawing area." + }, + "margin": { + "description": "The margin between the SVG and the drawing area. It's used for leaving some space for extra information such as the x- and y-axis or legend. Accepts an object with the optional properties: top, bottom, left, and right." + }, + "outerRadius": { + "description": "The radius between circle center and the end of the arc. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the maximal radius that fit into the drawing area." + }, + "startAngle": { "description": "The start angle (deg)." }, + "value": { + "description": "The value of the gauge. Set to null if no value to display." + }, + "valueMax": { "description": "The maximal value of the gauge." }, + "valueMin": { "description": "The minimal value of the gauge." }, + "width": { + "description": "The width of the chart in px. If not defined, it takes the width of the parent element." + } + }, + "classDescriptions": {} +} diff --git a/docs/translations/api-docs/charts/gauge/gauge.json b/docs/translations/api-docs/charts/gauge/gauge.json new file mode 100644 index 0000000000000..a6c6633d90457 --- /dev/null +++ b/docs/translations/api-docs/charts/gauge/gauge.json @@ -0,0 +1,50 @@ +{ + "componentDescription": "", + "propDescriptions": { + "cornerRadius": { + "description": "The radius applied to arc corners (similar to border radius)." + }, + "cx": { + "description": "The x coordinate of the pie center. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the width the drawing area." + }, + "cy": { + "description": "The y coordinate of the pie center. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the height the drawing area." + }, + "disableAxisListener": { + "description": "If true, the charts will not listen to the mouse move event. It might break interactive features, but will improve performance." + }, + "endAngle": { "description": "The end angle (deg)." }, + "height": { + "description": "The height of the chart in px. If not defined, it takes the height of the parent element." + }, + "innerRadius": { + "description": "The radius between circle center and the begining of the arc. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the maximal radius that fit into the drawing area." + }, + "margin": { + "description": "The margin between the SVG and the drawing area. It's used for leaving some space for extra information such as the x- and y-axis or legend. Accepts an object with the optional properties: top, bottom, left, and right." + }, + "outerRadius": { + "description": "The radius between circle center and the end of the arc. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the maximal radius that fit into the drawing area." + }, + "startAngle": { "description": "The start angle (deg)." }, + "value": { + "description": "The value of the gauge. Set to null if no value to display." + }, + "valueMax": { "description": "The maximal value of the gauge." }, + "valueMin": { "description": "The minimal value of the gauge." }, + "width": { + "description": "The width of the chart in px. If not defined, it takes the width of the parent element." + } + }, + "classDescriptions": { + "referenceArc": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the arc diplaying the range of available values" + }, + "root": { "description": "Styles applied to the root element." }, + "valueArc": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the arc diplaying the value" + } + } +} diff --git a/packages/x-charts/src/Gauge/Gauge.tsx b/packages/x-charts/src/Gauge/Gauge.tsx index ff41cdeca4ffa..b85ce819f4fd7 100644 --- a/packages/x-charts/src/Gauge/Gauge.tsx +++ b/packages/x-charts/src/Gauge/Gauge.tsx @@ -32,4 +32,111 @@ function Gauge(props: GaugeProps) { ); } +Gauge.propTypes = { + // ----------------------------- Warning -------------------------------- + // | These PropTypes are generated from the TypeScript type definitions | + // | To update them edit the TypeScript types and run "yarn proptypes" | + // ---------------------------------------------------------------------- + children: PropTypes.node, + classes: PropTypes.object, + className: PropTypes.string, + /** + * The radius applied to arc corners (similar to border radius). + * @default '50%' + */ + cornerRadius: PropTypes.number, + /** + * The x coordinate of the pie center. + * Can be a number (in px) or a string with a percentage such as '50%'. + * The '100%' is the width the drawing area. + */ + cx: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + /** + * The y coordinate of the pie center. + * Can be a number (in px) or a string with a percentage such as '50%'. + * The '100%' is the height the drawing area. + */ + cy: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + desc: PropTypes.string, + /** + * If `true`, the charts will not listen to the mouse move event. + * It might break interactive features, but will improve performance. + * @default false + */ + disableAxisListener: PropTypes.bool, + /** + * The end angle (deg). + * @default 360 + */ + endAngle: PropTypes.number, + /** + * The height of the chart in px. If not defined, it takes the height of the parent element. + * @default undefined + */ + height: PropTypes.number, + /** + * The radius between circle center and the begining of the arc. + * Can be a number (in px) or a string with a percentage such as '50%'. + * The '100%' is the maximal radius that fit into the drawing area. + * @default '80%' + */ + innerRadius: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + /** + * The margin between the SVG and the drawing area. + * It's used for leaving some space for extra information such as the x- and y-axis or legend. + * Accepts an object with the optional properties: `top`, `bottom`, `left`, and `right`. + * @default object Depends on the charts type. + */ + margin: PropTypes.shape({ + bottom: PropTypes.number, + left: PropTypes.number, + right: PropTypes.number, + top: PropTypes.number, + }), + /** + * The radius between circle center and the end of the arc. + * Can be a number (in px) or a string with a percentage such as '50%'. + * The '100%' is the maximal radius that fit into the drawing area. + * @default '100%' + */ + outerRadius: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + /** + * The start angle (deg). + * @default 0 + */ + startAngle: PropTypes.number, + sx: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), + PropTypes.func, + PropTypes.object, + ]), + title: PropTypes.string, + /** + * The value of the gauge. + * Set to `null` if no value to display. + */ + value: PropTypes.number, + /** + * The maximal value of the gauge. + * @default 100 + */ + valueMax: PropTypes.number, + /** + * The minimal value of the gauge. + * @default 0 + */ + valueMin: PropTypes.number, + viewBox: PropTypes.shape({ + height: PropTypes.number, + width: PropTypes.number, + x: PropTypes.number, + y: PropTypes.number, + }), + /** + * The width of the chart in px. If not defined, it takes the width of the parent element. + * @default undefined + */ + width: PropTypes.number, +} as any; + export { Gauge }; diff --git a/packages/x-charts/src/Gauge/GaugeContainer.tsx b/packages/x-charts/src/Gauge/GaugeContainer.tsx index 2a519832d7818..e3f21da1e459a 100644 --- a/packages/x-charts/src/Gauge/GaugeContainer.tsx +++ b/packages/x-charts/src/Gauge/GaugeContainer.tsx @@ -115,4 +115,110 @@ const GaugeContainer = React.forwardRef(function GaugeContainer(props: GaugeCont ); }); +GaugeContainer.propTypes = { + // ----------------------------- Warning -------------------------------- + // | These PropTypes are generated from the TypeScript type definitions | + // | To update them edit the TypeScript types and run "yarn proptypes" | + // ---------------------------------------------------------------------- + children: PropTypes.node, + className: PropTypes.string, + /** + * The radius applied to arc corners (similar to border radius). + * @default '50%' + */ + cornerRadius: PropTypes.number, + /** + * The x coordinate of the pie center. + * Can be a number (in px) or a string with a percentage such as '50%'. + * The '100%' is the width the drawing area. + */ + cx: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + /** + * The y coordinate of the pie center. + * Can be a number (in px) or a string with a percentage such as '50%'. + * The '100%' is the height the drawing area. + */ + cy: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + desc: PropTypes.string, + /** + * If `true`, the charts will not listen to the mouse move event. + * It might break interactive features, but will improve performance. + * @default false + */ + disableAxisListener: PropTypes.bool, + /** + * The end angle (deg). + * @default 360 + */ + endAngle: PropTypes.number, + /** + * The height of the chart in px. If not defined, it takes the height of the parent element. + * @default undefined + */ + height: PropTypes.number, + /** + * The radius between circle center and the begining of the arc. + * Can be a number (in px) or a string with a percentage such as '50%'. + * The '100%' is the maximal radius that fit into the drawing area. + * @default '80%' + */ + innerRadius: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + /** + * The margin between the SVG and the drawing area. + * It's used for leaving some space for extra information such as the x- and y-axis or legend. + * Accepts an object with the optional properties: `top`, `bottom`, `left`, and `right`. + * @default object Depends on the charts type. + */ + margin: PropTypes.shape({ + bottom: PropTypes.number, + left: PropTypes.number, + right: PropTypes.number, + top: PropTypes.number, + }), + /** + * The radius between circle center and the end of the arc. + * Can be a number (in px) or a string with a percentage such as '50%'. + * The '100%' is the maximal radius that fit into the drawing area. + * @default '100%' + */ + outerRadius: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + /** + * The start angle (deg). + * @default 0 + */ + startAngle: PropTypes.number, + sx: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), + PropTypes.func, + PropTypes.object, + ]), + title: PropTypes.string, + /** + * The value of the gauge. + * Set to `null` if no value to display. + */ + value: PropTypes.number, + /** + * The maximal value of the gauge. + * @default 100 + */ + valueMax: PropTypes.number, + /** + * The minimal value of the gauge. + * @default 0 + */ + valueMin: PropTypes.number, + viewBox: PropTypes.shape({ + height: PropTypes.number, + width: PropTypes.number, + x: PropTypes.number, + y: PropTypes.number, + }), + /** + * The width of the chart in px. If not defined, it takes the width of the parent element. + * @default undefined + */ + width: PropTypes.number, +} as any; + export { GaugeContainer }; diff --git a/scripts/buildApiDocs/chartsSettings/index.ts b/scripts/buildApiDocs/chartsSettings/index.ts index 768c036cf3c72..6119628c7ea9d 100644 --- a/scripts/buildApiDocs/chartsSettings/index.ts +++ b/scripts/buildApiDocs/chartsSettings/index.ts @@ -58,7 +58,13 @@ export default apiPages; getComponentInfo, translationLanguages: LANGUAGES, skipComponent(filename) { - return filename.includes('/context/'); + if (filename.includes('/context/')) { + return true; + } + return [ + 'x-charts/src/Gauge/GaugeReferenceArc.tsx', + 'x-charts/src/Gauge/GaugeValueArc.tsx', + ].some((invalidPath) => filename.endsWith(invalidPath)); }, skipAnnotatingComponentDefinition: true, translationPagesDirectory: 'docs/translations/api-docs/charts', From b8c38c6466d1e20d57eee857682688a6244e83d0 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 8 Feb 2024 15:20:14 +0100 Subject: [PATCH 03/20] docs --- docs/data/charts/gauge/BasicGauges.js | 11 +++ docs/data/charts/gauge/BasicGauges.tsx | 11 +++ .../data/charts/gauge/BasicGauges.tsx.preview | 4 + .../charts/gauge/GaugeValueRangeNoSnap.js | 11 +++ .../charts/gauge/GaugeValueRangeNoSnap.tsx | 11 +++ .../gauge/GaugeValueRangeNoSnap.tsx.preview | 4 + docs/data/charts/gauge/PlaygroundNoSnap.js | 85 +++++++++++++++++++ docs/data/charts/gauge/gauge.md | 64 ++++++++++++-- 8 files changed, 196 insertions(+), 5 deletions(-) create mode 100644 docs/data/charts/gauge/BasicGauges.js create mode 100644 docs/data/charts/gauge/BasicGauges.tsx create mode 100644 docs/data/charts/gauge/BasicGauges.tsx.preview create mode 100644 docs/data/charts/gauge/GaugeValueRangeNoSnap.js create mode 100644 docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx create mode 100644 docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx.preview create mode 100644 docs/data/charts/gauge/PlaygroundNoSnap.js diff --git a/docs/data/charts/gauge/BasicGauges.js b/docs/data/charts/gauge/BasicGauges.js new file mode 100644 index 0000000000000..d5eb57bbf55b5 --- /dev/null +++ b/docs/data/charts/gauge/BasicGauges.js @@ -0,0 +1,11 @@ +import * as React from 'react'; +import { Gauge } from '@mui/x-charts/Gauge'; + +export default function BasicGauges() { + return ( + + + + + ); +} diff --git a/docs/data/charts/gauge/BasicGauges.tsx b/docs/data/charts/gauge/BasicGauges.tsx new file mode 100644 index 0000000000000..d5eb57bbf55b5 --- /dev/null +++ b/docs/data/charts/gauge/BasicGauges.tsx @@ -0,0 +1,11 @@ +import * as React from 'react'; +import { Gauge } from '@mui/x-charts/Gauge'; + +export default function BasicGauges() { + return ( + + + + + ); +} diff --git a/docs/data/charts/gauge/BasicGauges.tsx.preview b/docs/data/charts/gauge/BasicGauges.tsx.preview new file mode 100644 index 0000000000000..c1c453a709833 --- /dev/null +++ b/docs/data/charts/gauge/BasicGauges.tsx.preview @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/docs/data/charts/gauge/GaugeValueRangeNoSnap.js b/docs/data/charts/gauge/GaugeValueRangeNoSnap.js new file mode 100644 index 0000000000000..bd1bf64864b5b --- /dev/null +++ b/docs/data/charts/gauge/GaugeValueRangeNoSnap.js @@ -0,0 +1,11 @@ +import * as React from 'react'; +import { Gauge } from '@mui/x-charts/Gauge'; + +export default function GaugeValueRangeNoSnap() { + return ( + + + + + ); +} diff --git a/docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx b/docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx new file mode 100644 index 0000000000000..bd1bf64864b5b --- /dev/null +++ b/docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx @@ -0,0 +1,11 @@ +import * as React from 'react'; +import { Gauge } from '@mui/x-charts/Gauge'; + +export default function GaugeValueRangeNoSnap() { + return ( + + + + + ); +} diff --git a/docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx.preview b/docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx.preview new file mode 100644 index 0000000000000..bbe7d47d9345b --- /dev/null +++ b/docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx.preview @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/docs/data/charts/gauge/PlaygroundNoSnap.js b/docs/data/charts/gauge/PlaygroundNoSnap.js new file mode 100644 index 0000000000000..6dbfaa251eb4e --- /dev/null +++ b/docs/data/charts/gauge/PlaygroundNoSnap.js @@ -0,0 +1,85 @@ +import * as React from 'react'; +import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo'; +import Paper from '@mui/material/Paper'; +import { Gauge } from '@mui/x-charts/Gauge'; + +export default function PlaygroundNoSnap() { + return ( + ( + + + + )} + getCode={({ props }) => { + const { innerRadius, outerRadius, ...numberProps } = props; + return [ + `import { Gauge } from '@mui/x-charts/Gauge';`, + '', + ` ` ${name}={${value}}`, + ), + ...Object.entries({ innerRadius, outerRadius }).map( + ([name, value]) => ` ${name}="${value}%"`, + ), + '/>', + ].join('\n'); + }} + /> + ); +} diff --git a/docs/data/charts/gauge/gauge.md b/docs/data/charts/gauge/gauge.md index ffa248998cafe..1b25806aa50d9 100644 --- a/docs/data/charts/gauge/gauge.md +++ b/docs/data/charts/gauge/gauge.md @@ -1,15 +1,69 @@ --- title: React Gauge chart productId: x-charts +components: Gauge, GaugeContainer +waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/meter/ --- -# Charts - Gauge 🚧 +# Charts - Gauge

Gauge charts let the user evaluate metrics.

-:::warning -The Gauge Chart component isn't available yet, but you can upvote [**this GitHub issue**](https://github.com/mui/mui-x/issues/2903) to see it arrive sooner. +## Basic gauge -Don't hesitate to leave a comment there to influence what gets built. -Especially if you already have a use case for this component, or if you're facing a pain point with your current solution. +The Gauge display a numeric value that varies within a defined range. + +{{"demo": "BasicGauges.js"}} + +## Value range + +The value of the Gauge is provided by props `value`. + +By default it's assumed to be between 0 and 100. +You can modify this range with props `valueMin` and `valueMax`. + +{{"demo": "GaugeValueRangeNoSnap.js"}} + +## Arcs configuration + +You can modify the arc shape with the following props: + +- `startAngle`, `endAngle`: Angle range provided in degrees +- `innerRadius`, `outerRadius`: Radius of the arc. It can be a number for fix number of px. Or a percentage string which will be a percent of the maximal available radius. +- `cornerRadius`: It can be a number for fix number of px. Or a percentage string which will be a percent of distance between inner and outer radius. + +{{"demo": "PlaygroundNoSnap.js"}} + +:::info +Notice that the arc position is computed to let the Gauge take as much space as possible in the drawing area. + +Provide props `cx` and/or `cy` to fix the coordinate of the arc center. ::: + +## Accessibility + +(WAI-ARIA: [https://www.w3.org/WAI/ARIA/apg/patterns/meter/](https://www.w3.org/WAI/ARIA/apg/patterns/meter/)) + +### Label + +If a visible label is available, reference it by adding `aria-labelledby` attribute. +Otherwise, the label can be provided by `aria-label`. + +### Presentation + +Assistive technologies often present the value as a percentage. +This can be modified by providing `aria-valuetext` attribute. + +For example a battery level indicator is better with a duration in hours. + +```jsx +

+ Battery level +

+ +``` From d4710a94f5bcb7c1e5c9a15338a9767fc295b434 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 8 Feb 2024 15:30:29 +0100 Subject: [PATCH 04/20] Remove fix size --- docs/data/charts/gauge/BasicGauges.js | 9 +++++---- docs/data/charts/gauge/BasicGauges.tsx | 9 +++++---- docs/data/charts/gauge/BasicGauges.tsx.preview | 6 ++---- docs/data/charts/gauge/GaugeValueRangeNoSnap.js | 9 +++++---- docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx | 9 +++++---- docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx.preview | 6 ++---- docs/data/charts/gauge/PlaygroundNoSnap.js | 1 + packages/x-charts/src/Gauge/Gauge.tsx | 2 +- 8 files changed, 26 insertions(+), 25 deletions(-) diff --git a/docs/data/charts/gauge/BasicGauges.js b/docs/data/charts/gauge/BasicGauges.js index d5eb57bbf55b5..ce8503b6ca111 100644 --- a/docs/data/charts/gauge/BasicGauges.js +++ b/docs/data/charts/gauge/BasicGauges.js @@ -1,11 +1,12 @@ import * as React from 'react'; +import Stack from '@mui/material/Stack'; import { Gauge } from '@mui/x-charts/Gauge'; export default function BasicGauges() { return ( - - - - + + + + ); } diff --git a/docs/data/charts/gauge/BasicGauges.tsx b/docs/data/charts/gauge/BasicGauges.tsx index d5eb57bbf55b5..ce8503b6ca111 100644 --- a/docs/data/charts/gauge/BasicGauges.tsx +++ b/docs/data/charts/gauge/BasicGauges.tsx @@ -1,11 +1,12 @@ import * as React from 'react'; +import Stack from '@mui/material/Stack'; import { Gauge } from '@mui/x-charts/Gauge'; export default function BasicGauges() { return ( - - - - + + + + ); } diff --git a/docs/data/charts/gauge/BasicGauges.tsx.preview b/docs/data/charts/gauge/BasicGauges.tsx.preview index c1c453a709833..7edb64600ff68 100644 --- a/docs/data/charts/gauge/BasicGauges.tsx.preview +++ b/docs/data/charts/gauge/BasicGauges.tsx.preview @@ -1,4 +1,2 @@ - - - - \ No newline at end of file + + \ No newline at end of file diff --git a/docs/data/charts/gauge/GaugeValueRangeNoSnap.js b/docs/data/charts/gauge/GaugeValueRangeNoSnap.js index bd1bf64864b5b..d6be879022e9b 100644 --- a/docs/data/charts/gauge/GaugeValueRangeNoSnap.js +++ b/docs/data/charts/gauge/GaugeValueRangeNoSnap.js @@ -1,11 +1,12 @@ import * as React from 'react'; +import Stack from '@mui/material/Stack'; import { Gauge } from '@mui/x-charts/Gauge'; export default function GaugeValueRangeNoSnap() { return ( - - - - + + + + ); } diff --git a/docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx b/docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx index bd1bf64864b5b..d6be879022e9b 100644 --- a/docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx +++ b/docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx @@ -1,11 +1,12 @@ import * as React from 'react'; +import Stack from '@mui/material/Stack'; import { Gauge } from '@mui/x-charts/Gauge'; export default function GaugeValueRangeNoSnap() { return ( - - - - + + + + ); } diff --git a/docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx.preview b/docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx.preview index bbe7d47d9345b..bd671b68b19b2 100644 --- a/docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx.preview +++ b/docs/data/charts/gauge/GaugeValueRangeNoSnap.tsx.preview @@ -1,4 +1,2 @@ - - - - \ No newline at end of file + + \ No newline at end of file diff --git a/docs/data/charts/gauge/PlaygroundNoSnap.js b/docs/data/charts/gauge/PlaygroundNoSnap.js index 6dbfaa251eb4e..5777f66f0554b 100644 --- a/docs/data/charts/gauge/PlaygroundNoSnap.js +++ b/docs/data/charts/gauge/PlaygroundNoSnap.js @@ -54,6 +54,7 @@ export default function PlaygroundNoSnap() { sx={{ width: 200, height: 200, + margin: 'auto', }} > { function Gauge(props: GaugeProps) { const classes = useUtilityClasses(props); return ( - + From 3a5304e4e416550f1f075a826dc63a390e196cd1 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 8 Feb 2024 18:16:56 +0100 Subject: [PATCH 05/20] support joy palette --- packages/x-charts/src/Gauge/GaugeReferenceArc.tsx | 4 ++-- packages/x-charts/src/Gauge/GaugeValueArc.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/x-charts/src/Gauge/GaugeReferenceArc.tsx b/packages/x-charts/src/Gauge/GaugeReferenceArc.tsx index 65bd8ebb4d306..55a0308362ccd 100644 --- a/packages/x-charts/src/Gauge/GaugeReferenceArc.tsx +++ b/packages/x-charts/src/Gauge/GaugeReferenceArc.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { arc as d3Arc } from 'd3-shape'; -import styled from '@mui/system/styled'; +import { styled } from '@mui/material/styles'; import { useGaugeState } from './GaugeProvider'; const StyledPath = styled('path', { @@ -8,7 +8,7 @@ const StyledPath = styled('path', { slot: 'ReferenceArc', overridesResolver: (props, styles) => styles.referenceArc, })(({ theme }) => ({ - fill: theme.palette.divider, + fill: (theme.vars || theme).palette.divider, })); export function GaugeReferenceArc(props: React.ComponentProps<'path'>) { diff --git a/packages/x-charts/src/Gauge/GaugeValueArc.tsx b/packages/x-charts/src/Gauge/GaugeValueArc.tsx index ff64647789894..3c8bb81a5c6f7 100644 --- a/packages/x-charts/src/Gauge/GaugeValueArc.tsx +++ b/packages/x-charts/src/Gauge/GaugeValueArc.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { arc as d3Arc } from 'd3-shape'; -import styled from '@mui/system/styled'; +import { styled } from '@mui/material/styles'; import { useGaugeState } from './GaugeProvider'; const StyledPath = styled('path', { @@ -8,7 +8,7 @@ const StyledPath = styled('path', { slot: 'ReferenceArc', overridesResolver: (props, styles) => styles.referenceArc, })(({ theme }) => ({ - fill: theme.palette.primary.main, + fill: (theme.vars || theme).palette.primary.main, })); export function GaugeValueArc(props: React.ComponentProps<'path'>) { From 57b8f6bf7cfaed656e0bcb6a4608587dae359602 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 8 Feb 2024 18:50:51 +0100 Subject: [PATCH 06/20] export classes --- packages/x-charts/src/Gauge/gaugeClasses.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/x-charts/src/Gauge/gaugeClasses.ts b/packages/x-charts/src/Gauge/gaugeClasses.ts index 759dc90a86995..7d097f3bfe1a4 100644 --- a/packages/x-charts/src/Gauge/gaugeClasses.ts +++ b/packages/x-charts/src/Gauge/gaugeClasses.ts @@ -16,7 +16,7 @@ export function getGaugeUtilityClass(slot: string): string { return generateUtilityClass('MuiGauge', slot); } -const gaugeClasses: GaugeClasses = generateUtilityClasses('MuiGauge', [ +export const gaugeClasses: GaugeClasses = generateUtilityClasses('MuiGauge', [ 'root', 'valueArc', 'referenceArc', From 38c5906b6bfdf5aa0786f43a7f85c4cd3a2a8c9e Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 8 Feb 2024 18:50:57 +0100 Subject: [PATCH 07/20] Add text support --- ...groundNoSnap.js => ArcPlaygroundNoSnap.js} | 10 ++- .../data/charts/gauge/TextPlaygroundNoSnap.js | 90 +++++++++++++++++++ docs/data/charts/gauge/gauge.md | 14 ++- packages/x-charts/src/Gauge/Gauge.tsx | 8 +- .../x-charts/src/Gauge/GaugeContainer.tsx | 5 +- .../x-charts/src/Gauge/GaugeValueText.tsx | 40 +++++++++ packages/x-charts/src/Gauge/gaugeClasses.ts | 3 + packages/x-charts/src/Gauge/index.ts | 2 + 8 files changed, 165 insertions(+), 7 deletions(-) rename docs/data/charts/gauge/{PlaygroundNoSnap.js => ArcPlaygroundNoSnap.js} (89%) create mode 100644 docs/data/charts/gauge/TextPlaygroundNoSnap.js create mode 100644 packages/x-charts/src/Gauge/GaugeValueText.tsx diff --git a/docs/data/charts/gauge/PlaygroundNoSnap.js b/docs/data/charts/gauge/ArcPlaygroundNoSnap.js similarity index 89% rename from docs/data/charts/gauge/PlaygroundNoSnap.js rename to docs/data/charts/gauge/ArcPlaygroundNoSnap.js index 5777f66f0554b..5ab80a7592067 100644 --- a/docs/data/charts/gauge/PlaygroundNoSnap.js +++ b/docs/data/charts/gauge/ArcPlaygroundNoSnap.js @@ -1,9 +1,9 @@ import * as React from 'react'; import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo'; import Paper from '@mui/material/Paper'; -import { Gauge } from '@mui/x-charts/Gauge'; +import { Gauge, gaugeClasses } from '@mui/x-charts/Gauge'; -export default function PlaygroundNoSnap() { +export default function ArcPlaygroundNoSnap() { return ( ( + + `${value} / ${valueMax}`} + /> + + )} + getCode={({ props }) => { + return [ + `import { Gauge, gaugeClasses } from '@mui/x-charts/Gauge';`, + '', + ` `${value} / ${valueMax}`', + ' }', + '/>', + ].join('\n'); + }} + /> + ); +} diff --git a/docs/data/charts/gauge/gauge.md b/docs/data/charts/gauge/gauge.md index 1b25806aa50d9..26a67c30f4707 100644 --- a/docs/data/charts/gauge/gauge.md +++ b/docs/data/charts/gauge/gauge.md @@ -32,7 +32,7 @@ You can modify the arc shape with the following props: - `innerRadius`, `outerRadius`: Radius of the arc. It can be a number for fix number of px. Or a percentage string which will be a percent of the maximal available radius. - `cornerRadius`: It can be a number for fix number of px. Or a percentage string which will be a percent of distance between inner and outer radius. -{{"demo": "PlaygroundNoSnap.js"}} +{{"demo": "ArcPlaygroundNoSnap.js"}} :::info Notice that the arc position is computed to let the Gauge take as much space as possible in the drawing area. @@ -40,6 +40,18 @@ Notice that the arc position is computed to let the Gauge take as much space as Provide props `cx` and/or `cy` to fix the coordinate of the arc center. ::: +## Text configuration + +By default, the Gauge displays the value in the center of the arc. +To modify it, use the `text` prop. + +This prop can be a string, or a formatter. +In the second case, the formatter argument contains the `value`, `valueMin` and `valueMax`. + +To modify the layout of the text, use the class name `gaugeClasses.valueText`. + +{{"demo": "TextPlaygroundNoSnap.js"}} + ## Accessibility (WAI-ARIA: [https://www.w3.org/WAI/ARIA/apg/patterns/meter/](https://www.w3.org/WAI/ARIA/apg/patterns/meter/)) diff --git a/packages/x-charts/src/Gauge/Gauge.tsx b/packages/x-charts/src/Gauge/Gauge.tsx index 33d22e0ea6b85..fcbca83117aba 100644 --- a/packages/x-charts/src/Gauge/Gauge.tsx +++ b/packages/x-charts/src/Gauge/Gauge.tsx @@ -5,8 +5,9 @@ import { GaugeContainer, GaugeContainerProps } from './GaugeContainer'; import { GaugeValueArc } from './GaugeValueArc'; import { GaugeReferenceArc } from './GaugeReferenceArc'; import { GaugeClasses, getGaugeUtilityClass } from './gaugeClasses'; +import { GaugeValueText, GaugeValueTextProps } from './GaugeValueText'; -export interface GaugeProps extends GaugeContainerProps { +export interface GaugeProps extends GaugeContainerProps, Pick { classes?: Partial; } @@ -17,17 +18,20 @@ const useUtilityClasses = (props: GaugeProps) => { root: ['root'], valueArc: ['valueArc'], referenceArc: ['referenceArc'], + valueText: ['valueText'], }; return composeClasses(slots, getGaugeUtilityClass, classes); }; function Gauge(props: GaugeProps) { + const { text, ...other } = props; const classes = useUtilityClasses(props); return ( - + + ); } diff --git a/packages/x-charts/src/Gauge/GaugeContainer.tsx b/packages/x-charts/src/Gauge/GaugeContainer.tsx index e3f21da1e459a..aa6c10d399ffd 100644 --- a/packages/x-charts/src/Gauge/GaugeContainer.tsx +++ b/packages/x-charts/src/Gauge/GaugeContainer.tsx @@ -27,7 +27,7 @@ export interface GaugeContainerProps const ResizableContainer = styled('div', { name: 'MuiGauge', slot: 'Container', -})<{ ownerState: Pick }>(({ ownerState }) => ({ +})<{ ownerState: Pick }>(({ ownerState, theme }) => ({ width: ownerState.width ?? '100%', height: ownerState.height ?? '100%', display: 'flex', @@ -41,6 +41,9 @@ const ResizableContainer = styled('div', { width: '100%', height: '100%', }, + '& text': { + fill: (theme.vars || theme).palette.text.primary, + }, })); const GaugeContainer = React.forwardRef(function GaugeContainer(props: GaugeContainerProps, ref) { diff --git a/packages/x-charts/src/Gauge/GaugeValueText.tsx b/packages/x-charts/src/Gauge/GaugeValueText.tsx new file mode 100644 index 0000000000000..c60c7fc6ac3cd --- /dev/null +++ b/packages/x-charts/src/Gauge/GaugeValueText.tsx @@ -0,0 +1,40 @@ +import * as React from 'react'; +import { useGaugeState } from './GaugeProvider'; +import { ChartsText, ChartsTextProps } from '../ChartsText'; + +export interface GaugeFormatterParams { + value: number | null; + valueMin: number; + valueMax: number; +} + +export interface GaugeValueTextProps extends Omit { + text?: string | ((params: GaugeFormatterParams) => string | null); +} + +function defaultFormatter({ value }: GaugeFormatterParams) { + return value === null ? 'NaN' : value.toLocaleString(); +} +export function GaugeValueText(props: GaugeValueTextProps) { + const { text = defaultFormatter, className, ...other } = props; + + const { value, valueMin, valueMax, cx, cy } = useGaugeState(); + + const formattedText = typeof text === 'function' ? text({ value, valueMin, valueMax }) : text; + + if (formattedText === null) { + return null; + } + + return ( + + + + ); +} diff --git a/packages/x-charts/src/Gauge/gaugeClasses.ts b/packages/x-charts/src/Gauge/gaugeClasses.ts index 7d097f3bfe1a4..1fdca8354d355 100644 --- a/packages/x-charts/src/Gauge/gaugeClasses.ts +++ b/packages/x-charts/src/Gauge/gaugeClasses.ts @@ -8,6 +8,8 @@ export interface GaugeClasses { valueArc: string; /** Styles applied to the arc diplaying the range of available values. */ referenceArc: string; + /** Styles applied to the value text. */ + valueText: string; } export type GaugeClassKey = keyof GaugeClasses; @@ -20,6 +22,7 @@ export const gaugeClasses: GaugeClasses = generateUtilityClasses('MuiGauge', [ 'root', 'valueArc', 'referenceArc', + 'valueText', ]); export default gaugeClasses; diff --git a/packages/x-charts/src/Gauge/index.ts b/packages/x-charts/src/Gauge/index.ts index 794b7af69a651..30ce6d63f97a3 100644 --- a/packages/x-charts/src/Gauge/index.ts +++ b/packages/x-charts/src/Gauge/index.ts @@ -1,4 +1,6 @@ export * from './Gauge'; export * from './GaugeContainer'; +export * from './GaugeValueText'; export * from './GaugeValueArc'; export * from './GaugeReferenceArc'; +export * from './gaugeClasses'; From 78d9bc86dcf7cb1f8f4cba1c823811d408cca954 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 8 Feb 2024 18:53:39 +0100 Subject: [PATCH 08/20] scripts --- docs/pages/x/api/charts/gauge.json | 6 +++++ .../api-docs/charts/gauge/gauge.json | 3 ++- packages/x-charts/src/Gauge/Gauge.tsx | 1 + .../x-charts/src/Gauge/GaugeValueText.tsx | 27 ++++++++++++++++++- scripts/buildApiDocs/chartsSettings/index.ts | 1 + scripts/x-charts.exports.json | 7 +++++ 6 files changed, 43 insertions(+), 2 deletions(-) diff --git a/docs/pages/x/api/charts/gauge.json b/docs/pages/x/api/charts/gauge.json index c1284e25f1151..a5bafe86b40e4 100644 --- a/docs/pages/x/api/charts/gauge.json +++ b/docs/pages/x/api/charts/gauge.json @@ -50,6 +50,12 @@ "className": "MuiGauge-valueArc", "description": "Styles applied to the arc diplaying the value.", "isGlobal": false + }, + { + "key": "valueText", + "className": "MuiGauge-valueText", + "description": "Styles applied to the value text.", + "isGlobal": false } ], "muiName": "MuiGauge", diff --git a/docs/translations/api-docs/charts/gauge/gauge.json b/docs/translations/api-docs/charts/gauge/gauge.json index a6c6633d90457..0bb21d98477eb 100644 --- a/docs/translations/api-docs/charts/gauge/gauge.json +++ b/docs/translations/api-docs/charts/gauge/gauge.json @@ -45,6 +45,7 @@ "valueArc": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the arc diplaying the value" - } + }, + "valueText": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the value text" } } } diff --git a/packages/x-charts/src/Gauge/Gauge.tsx b/packages/x-charts/src/Gauge/Gauge.tsx index fcbca83117aba..40da729822aaa 100644 --- a/packages/x-charts/src/Gauge/Gauge.tsx +++ b/packages/x-charts/src/Gauge/Gauge.tsx @@ -114,6 +114,7 @@ Gauge.propTypes = { PropTypes.func, PropTypes.object, ]), + text: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), title: PropTypes.string, /** * The value of the gauge. diff --git a/packages/x-charts/src/Gauge/GaugeValueText.tsx b/packages/x-charts/src/Gauge/GaugeValueText.tsx index c60c7fc6ac3cd..ace6f96073444 100644 --- a/packages/x-charts/src/Gauge/GaugeValueText.tsx +++ b/packages/x-charts/src/Gauge/GaugeValueText.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import PropTypes from 'prop-types'; import { useGaugeState } from './GaugeProvider'; import { ChartsText, ChartsTextProps } from '../ChartsText'; @@ -15,7 +16,7 @@ export interface GaugeValueTextProps extends Omit { function defaultFormatter({ value }: GaugeFormatterParams) { return value === null ? 'NaN' : value.toLocaleString(); } -export function GaugeValueText(props: GaugeValueTextProps) { +function GaugeValueText(props: GaugeValueTextProps) { const { text = defaultFormatter, className, ...other } = props; const { value, valueMin, valueMax, cx, cy } = useGaugeState(); @@ -38,3 +39,27 @@ export function GaugeValueText(props: GaugeValueTextProps) { ); } + +GaugeValueText.propTypes = { + // ----------------------------- Warning -------------------------------- + // | These PropTypes are generated from the TypeScript type definitions | + // | To update them edit the TypeScript types and run "yarn proptypes" | + // ---------------------------------------------------------------------- + /** + * Height of a text line (in `em`). + */ + lineHeight: PropTypes.number, + /** + * If `true`, the line width is computed. + * @default false + */ + needsComputation: PropTypes.bool, + ownerState: PropTypes.any, + /** + * Style applied to text elements. + */ + style: PropTypes.object, + text: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), +} as any; + +export { GaugeValueText }; diff --git a/scripts/buildApiDocs/chartsSettings/index.ts b/scripts/buildApiDocs/chartsSettings/index.ts index 6119628c7ea9d..bf83efd12a609 100644 --- a/scripts/buildApiDocs/chartsSettings/index.ts +++ b/scripts/buildApiDocs/chartsSettings/index.ts @@ -64,6 +64,7 @@ export default apiPages; return [ 'x-charts/src/Gauge/GaugeReferenceArc.tsx', 'x-charts/src/Gauge/GaugeValueArc.tsx', + 'x-charts/src/Gauge/GaugeValueText.tsx', ].some((invalidPath) => filename.endsWith(invalidPath)); }, skipAnnotatingComponentDefinition: true, diff --git a/scripts/x-charts.exports.json b/scripts/x-charts.exports.json index 96e471acb2f31..af30bf2893f00 100644 --- a/scripts/x-charts.exports.json +++ b/scripts/x-charts.exports.json @@ -122,16 +122,23 @@ { "name": "DrawingProvider", "kind": "Function" }, { "name": "FadeOptions", "kind": "TypeAlias" }, { "name": "Gauge", "kind": "Function" }, + { "name": "gaugeClasses", "kind": "Variable" }, + { "name": "GaugeClasses", "kind": "Interface" }, + { "name": "GaugeClassKey", "kind": "TypeAlias" }, { "name": "GaugeContainer", "kind": "Variable" }, { "name": "GaugeContainerProps", "kind": "Interface" }, + { "name": "GaugeFormatterParams", "kind": "Interface" }, { "name": "GaugeProps", "kind": "Interface" }, { "name": "GaugeReferenceArc", "kind": "Function" }, { "name": "GaugeValueArc", "kind": "Function" }, + { "name": "GaugeValueText", "kind": "Function" }, + { "name": "GaugeValueTextProps", "kind": "Interface" }, { "name": "getAreaElementUtilityClass", "kind": "Function" }, { "name": "getAxisHighlightUtilityClass", "kind": "Function" }, { "name": "getAxisUtilityClass", "kind": "Function" }, { "name": "getBarElementUtilityClass", "kind": "Function" }, { "name": "getChartsTooltipUtilityClass", "kind": "Function" }, + { "name": "getGaugeUtilityClass", "kind": "Function" }, { "name": "getHighlightElementUtilityClass", "kind": "Function" }, { "name": "getLegendUtilityClass", "kind": "Function" }, { "name": "getLineElementUtilityClass", "kind": "Function" }, From 4d6fd72f58d11a59fab42407869b82376bed624f Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 12 Feb 2024 11:31:55 +0100 Subject: [PATCH 09/20] modify default --- packages/x-charts/src/Gauge/GaugeProvider.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/x-charts/src/Gauge/GaugeProvider.tsx b/packages/x-charts/src/Gauge/GaugeProvider.tsx index 98b7c8a5c5442..4907d96228614 100644 --- a/packages/x-charts/src/Gauge/GaugeProvider.tsx +++ b/packages/x-charts/src/Gauge/GaugeProvider.tsx @@ -31,7 +31,8 @@ interface CircularConfig { outerRadius?: number | string; /** * The radius applied to arc corners (similar to border radius). - * @default '50%' + * Set it to '50%' to get rounded arc. + * @default 0 */ cornerRadius?: number; /** @@ -153,7 +154,7 @@ export function GaugeProvider(props: GaugeProviderProps) { const outerRadius = getPercentageValue(outerRadiusParam ?? availableRadius, availableRadius); const innerRadius = getPercentageValue(innerRadiusParam ?? '80%', availableRadius); - const cornerRadius = getPercentageValue(cornerRadiusParam ?? '50%', outerRadius - innerRadius); + const cornerRadius = getPercentageValue(cornerRadiusParam ?? 0, outerRadius - innerRadius); const contextValue = React.useMemo( () => ({ From fbdb7a74e63207a35d37b6040b2ccde5b74cd495 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 12 Feb 2024 11:32:28 +0100 Subject: [PATCH 10/20] provide the maxRadius (usefull for custom component) --- packages/x-charts/src/Gauge/GaugeProvider.tsx | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/x-charts/src/Gauge/GaugeProvider.tsx b/packages/x-charts/src/Gauge/GaugeProvider.tsx index 4907d96228614..16dcaf2bcb032 100644 --- a/packages/x-charts/src/Gauge/GaugeProvider.tsx +++ b/packages/x-charts/src/Gauge/GaugeProvider.tsx @@ -98,7 +98,15 @@ interface GaugeConfig { valueMax?: number; } -export const GaugeContext = React.createContext & ProcessedCircularConfig>({ +export const GaugeContext = React.createContext< + Required & + ProcessedCircularConfig & { + /** + * The maximal radius from (cx, cy) that fit that arc in the drawing area. + */ + maxRadius: number; + } +>({ value: null, valueMin: 0, valueMax: 0, @@ -109,6 +117,7 @@ export const GaugeContext = React.createContext & Processe cornerRadius: 0, cx: 0, cy: 0, + maxRadius: 0, }); export interface GaugeProviderProps extends GaugeConfig, CircularConfig { @@ -140,20 +149,20 @@ export function GaugeProvider(props: GaugeProviderProps) { let cx = left + innerCx; let cy = top + innerCy; - const availableRadius = getAvailableRadius(innerCx, innerCy, width, height, ratios); + const maxRadius = getAvailableRadius(innerCx, innerCy, width, height, ratios); // If the center is not defined, after computation of the available radius, udpate the center to use the remaining space. if (cxParam === undefined) { - const usedWidth = availableRadius * (ratios.maxX - ratios.minX); + const usedWidth = maxRadius * (ratios.maxX - ratios.minX); cx = left + (width - usedWidth) / 2 + ratios.cx * usedWidth; } if (cyParam === undefined) { - const usedHeight = availableRadius * (ratios.maxY - ratios.minY); + const usedHeight = maxRadius * (ratios.maxY - ratios.minY); cy = top + (height - usedHeight) / 2 + ratios.cy * usedHeight; } - const outerRadius = getPercentageValue(outerRadiusParam ?? availableRadius, availableRadius); - const innerRadius = getPercentageValue(innerRadiusParam ?? '80%', availableRadius); + const outerRadius = getPercentageValue(outerRadiusParam ?? maxRadius, maxRadius); + const innerRadius = getPercentageValue(innerRadiusParam ?? '80%', maxRadius); const cornerRadius = getPercentageValue(cornerRadiusParam ?? 0, outerRadius - innerRadius); const contextValue = React.useMemo( @@ -168,6 +177,7 @@ export function GaugeProvider(props: GaugeProviderProps) { cornerRadius, cx, cy, + maxRadius, }), [ value, @@ -180,6 +190,7 @@ export function GaugeProvider(props: GaugeProviderProps) { cornerRadius, cx, cy, + maxRadius, ], ); From 8b1d937cafc80e3436344e52506711c113648d08 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 12 Feb 2024 12:01:48 +0100 Subject: [PATCH 11/20] Docs customization --- docs/data/charts/gauge/ArcDesign.js | 30 +++++++++++++++++++ docs/data/charts/gauge/ArcDesign.tsx | 30 +++++++++++++++++++ docs/data/charts/gauge/ArcDesign.tsx.preview | 15 ++++++++++ docs/data/charts/gauge/gauge.md | 8 +++++ packages/x-charts/src/Gauge/GaugeProvider.tsx | 2 +- 5 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 docs/data/charts/gauge/ArcDesign.js create mode 100644 docs/data/charts/gauge/ArcDesign.tsx create mode 100644 docs/data/charts/gauge/ArcDesign.tsx.preview diff --git a/docs/data/charts/gauge/ArcDesign.js b/docs/data/charts/gauge/ArcDesign.js new file mode 100644 index 0000000000000..874749534b99c --- /dev/null +++ b/docs/data/charts/gauge/ArcDesign.js @@ -0,0 +1,30 @@ +import * as React from 'react'; +import Stack from '@mui/material/Stack'; +import { Gauge, gaugeClasses } from '@mui/x-charts/Gauge'; + +const settings = { + width: 200, + height: 200, + value: 60, +}; +export default function ArcDesign() { + return ( + + ({ + [`& .${gaugeClasses.valueText}`]: { + fontSize: 40, + }, + [`& .${gaugeClasses.valueArc}`]: { + fill: '#52b202', + }, + [`& .${gaugeClasses.referenceArc}`]: { + fill: theme.palette.text.disabled, + }, + })} + /> + + ); +} diff --git a/docs/data/charts/gauge/ArcDesign.tsx b/docs/data/charts/gauge/ArcDesign.tsx new file mode 100644 index 0000000000000..874749534b99c --- /dev/null +++ b/docs/data/charts/gauge/ArcDesign.tsx @@ -0,0 +1,30 @@ +import * as React from 'react'; +import Stack from '@mui/material/Stack'; +import { Gauge, gaugeClasses } from '@mui/x-charts/Gauge'; + +const settings = { + width: 200, + height: 200, + value: 60, +}; +export default function ArcDesign() { + return ( + + ({ + [`& .${gaugeClasses.valueText}`]: { + fontSize: 40, + }, + [`& .${gaugeClasses.valueArc}`]: { + fill: '#52b202', + }, + [`& .${gaugeClasses.referenceArc}`]: { + fill: theme.palette.text.disabled, + }, + })} + /> + + ); +} diff --git a/docs/data/charts/gauge/ArcDesign.tsx.preview b/docs/data/charts/gauge/ArcDesign.tsx.preview new file mode 100644 index 0000000000000..281808d62fc78 --- /dev/null +++ b/docs/data/charts/gauge/ArcDesign.tsx.preview @@ -0,0 +1,15 @@ + ({ + [`& .${gaugeClasses.valueText}`]: { + fontSize: 40, + }, + [`& .${gaugeClasses.valueArc}`]: { + fill: '#52b202', + }, + [`& .${gaugeClasses.referenceArc}`]: { + fill: theme.palette.text.disabled, + }, + })} +/> \ No newline at end of file diff --git a/docs/data/charts/gauge/gauge.md b/docs/data/charts/gauge/gauge.md index 26a67c30f4707..c3d096dad4ddf 100644 --- a/docs/data/charts/gauge/gauge.md +++ b/docs/data/charts/gauge/gauge.md @@ -52,6 +52,14 @@ To modify the layout of the text, use the class name `gaugeClasses.valueText`. {{"demo": "TextPlaygroundNoSnap.js"}} +## Arc design + +You can customize the Gauge style with usual selectors. +The `gaugeClasses` provides class names to select parts of the component, such as `valueText`, `valueArc`, and `referenceArc`. + +{{"demo": "ArcDesign.js"}} + + ## Accessibility (WAI-ARIA: [https://www.w3.org/WAI/ARIA/apg/patterns/meter/](https://www.w3.org/WAI/ARIA/apg/patterns/meter/)) diff --git a/packages/x-charts/src/Gauge/GaugeProvider.tsx b/packages/x-charts/src/Gauge/GaugeProvider.tsx index 16dcaf2bcb032..443c34413e9e2 100644 --- a/packages/x-charts/src/Gauge/GaugeProvider.tsx +++ b/packages/x-charts/src/Gauge/GaugeProvider.tsx @@ -34,7 +34,7 @@ interface CircularConfig { * Set it to '50%' to get rounded arc. * @default 0 */ - cornerRadius?: number; + cornerRadius?: number | string; /** * The x coordinate of the pie center. * Can be a number (in px) or a string with a percentage such as '50%'. From 3dcebaeeb046beddefe08f2eca5b0c52a47a5ffb Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 12 Feb 2024 14:25:32 +0100 Subject: [PATCH 12/20] Remove useless stack --- docs/data/charts/gauge/ArcDesign.js | 34 +++++++++++++--------------- docs/data/charts/gauge/ArcDesign.tsx | 34 +++++++++++++--------------- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/docs/data/charts/gauge/ArcDesign.js b/docs/data/charts/gauge/ArcDesign.js index 874749534b99c..48a4633df62e0 100644 --- a/docs/data/charts/gauge/ArcDesign.js +++ b/docs/data/charts/gauge/ArcDesign.js @@ -1,5 +1,4 @@ import * as React from 'react'; -import Stack from '@mui/material/Stack'; import { Gauge, gaugeClasses } from '@mui/x-charts/Gauge'; const settings = { @@ -7,24 +6,23 @@ const settings = { height: 200, value: 60, }; + export default function ArcDesign() { return ( - - ({ - [`& .${gaugeClasses.valueText}`]: { - fontSize: 40, - }, - [`& .${gaugeClasses.valueArc}`]: { - fill: '#52b202', - }, - [`& .${gaugeClasses.referenceArc}`]: { - fill: theme.palette.text.disabled, - }, - })} - /> - + ({ + [`& .${gaugeClasses.valueText}`]: { + fontSize: 40, + }, + [`& .${gaugeClasses.valueArc}`]: { + fill: '#52b202', + }, + [`& .${gaugeClasses.referenceArc}`]: { + fill: theme.palette.text.disabled, + }, + })} + /> ); } diff --git a/docs/data/charts/gauge/ArcDesign.tsx b/docs/data/charts/gauge/ArcDesign.tsx index 874749534b99c..48a4633df62e0 100644 --- a/docs/data/charts/gauge/ArcDesign.tsx +++ b/docs/data/charts/gauge/ArcDesign.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import Stack from '@mui/material/Stack'; import { Gauge, gaugeClasses } from '@mui/x-charts/Gauge'; const settings = { @@ -7,24 +6,23 @@ const settings = { height: 200, value: 60, }; + export default function ArcDesign() { return ( - - ({ - [`& .${gaugeClasses.valueText}`]: { - fontSize: 40, - }, - [`& .${gaugeClasses.valueArc}`]: { - fill: '#52b202', - }, - [`& .${gaugeClasses.referenceArc}`]: { - fill: theme.palette.text.disabled, - }, - })} - /> - + ({ + [`& .${gaugeClasses.valueText}`]: { + fontSize: 40, + }, + [`& .${gaugeClasses.valueArc}`]: { + fill: '#52b202', + }, + [`& .${gaugeClasses.referenceArc}`]: { + fill: theme.palette.text.disabled, + }, + })} + /> ); } From a94d904c8e4904d811b49ee593bc916a6c18ad9d Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 12 Feb 2024 14:25:41 +0100 Subject: [PATCH 13/20] Add composition docs --- docs/data/charts/gauge/CompositionExample.js | 47 ++++++++++++++++++ docs/data/charts/gauge/CompositionExample.tsx | 47 ++++++++++++++++++ .../gauge/CompositionExample.tsx.preview | 11 +++++ docs/data/charts/gauge/gauge.md | 45 +++++++++++++++++ packages/x-charts/src/Gauge/Gauge.tsx | 4 +- packages/x-charts/src/Gauge/GaugeProvider.tsx | 49 ++++++++++++------- packages/x-charts/src/Gauge/index.ts | 1 + 7 files changed, 184 insertions(+), 20 deletions(-) create mode 100644 docs/data/charts/gauge/CompositionExample.js create mode 100644 docs/data/charts/gauge/CompositionExample.tsx create mode 100644 docs/data/charts/gauge/CompositionExample.tsx.preview diff --git a/docs/data/charts/gauge/CompositionExample.js b/docs/data/charts/gauge/CompositionExample.js new file mode 100644 index 0000000000000..764a6cf60b46c --- /dev/null +++ b/docs/data/charts/gauge/CompositionExample.js @@ -0,0 +1,47 @@ +import * as React from 'react'; +import { + GaugeContainer, + GaugeValueArc, + GaugeReferenceArc, + useGaugeState, +} from '@mui/x-charts/Gauge'; + +function GaugePointer() { + const { valueAngle, outerRadius, cx, cy } = useGaugeState(); + + if (valueAngle === null) { + // No value to display + return null; + } + + const target = { + x: cx + outerRadius * Math.sin(valueAngle), + y: cy - outerRadius * Math.cos(valueAngle), + }; + return ( + + + + + ); +} + +export default function CompositionExample() { + return ( + + + + + + ); +} diff --git a/docs/data/charts/gauge/CompositionExample.tsx b/docs/data/charts/gauge/CompositionExample.tsx new file mode 100644 index 0000000000000..764a6cf60b46c --- /dev/null +++ b/docs/data/charts/gauge/CompositionExample.tsx @@ -0,0 +1,47 @@ +import * as React from 'react'; +import { + GaugeContainer, + GaugeValueArc, + GaugeReferenceArc, + useGaugeState, +} from '@mui/x-charts/Gauge'; + +function GaugePointer() { + const { valueAngle, outerRadius, cx, cy } = useGaugeState(); + + if (valueAngle === null) { + // No value to display + return null; + } + + const target = { + x: cx + outerRadius * Math.sin(valueAngle), + y: cy - outerRadius * Math.cos(valueAngle), + }; + return ( + + + + + ); +} + +export default function CompositionExample() { + return ( + + + + + + ); +} diff --git a/docs/data/charts/gauge/CompositionExample.tsx.preview b/docs/data/charts/gauge/CompositionExample.tsx.preview new file mode 100644 index 0000000000000..2675af81dc021 --- /dev/null +++ b/docs/data/charts/gauge/CompositionExample.tsx.preview @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/docs/data/charts/gauge/gauge.md b/docs/data/charts/gauge/gauge.md index c3d096dad4ddf..2b7436299af45 100644 --- a/docs/data/charts/gauge/gauge.md +++ b/docs/data/charts/gauge/gauge.md @@ -59,6 +59,51 @@ The `gaugeClasses` provides class names to select parts of the component, such a {{"demo": "ArcDesign.js"}} +## Adding elements + +### Using the default Gauge + +If the default Gauge does not contain all the visual elements you're looking for, you can add them. +THe first solution is to add your component as children. +They will be stacked on top of the default rendering. + +```tsx +import { Gauge } from '@mui/x-charts/Gauge' + + + + +``` + +### Using the Gauge container + +The second solution is to start from scratch with our components: + +- GaugeReferenceArc +- GaugeValueArc +- GaugeValueText + +```tsx +import { GaugeContainer, Gauge , GaugeReferenceArc, GaugeValueArc } from '@mui/x-charts/Gauge' + + + + + + +``` + +### Creating your components + +To create your own components, use `useGaugeState` hook which provides all you need about the gauge configuration: + +- Information about the value: `value`, `valueMin`, `valueMax` +- Information to plot the arc: `startAngle`, `endAngle`, `outerRadius`, `innerRadius`, `cornerRadius`, `cx`, and `cy` +- Computed values: + - `maxRadius` the maximal radius that can fit in the drawing area. + - `valueAngle` the angle associated to the current value. + +{{"demo": "CompositionExample.js"}} ## Accessibility diff --git a/packages/x-charts/src/Gauge/Gauge.tsx b/packages/x-charts/src/Gauge/Gauge.tsx index 40da729822aaa..0df69d8d240af 100644 --- a/packages/x-charts/src/Gauge/Gauge.tsx +++ b/packages/x-charts/src/Gauge/Gauge.tsx @@ -9,6 +9,7 @@ import { GaugeValueText, GaugeValueTextProps } from './GaugeValueText'; export interface GaugeProps extends GaugeContainerProps, Pick { classes?: Partial; + children?: React.ReactNode; } const useUtilityClasses = (props: GaugeProps) => { @@ -25,13 +26,14 @@ const useUtilityClasses = (props: GaugeProps) => { }; function Gauge(props: GaugeProps) { - const { text, ...other } = props; + const { text, children, ...other } = props; const classes = useUtilityClasses(props); return ( + {children} ); } diff --git a/packages/x-charts/src/Gauge/GaugeProvider.tsx b/packages/x-charts/src/Gauge/GaugeProvider.tsx index 443c34413e9e2..28fe4d8a14bc9 100644 --- a/packages/x-charts/src/Gauge/GaugeProvider.tsx +++ b/packages/x-charts/src/Gauge/GaugeProvider.tsx @@ -105,6 +105,10 @@ export const GaugeContext = React.createContext< * The maximal radius from (cx, cy) that fit that arc in the drawing area. */ maxRadius: number; + /** + * The angle (rad) associated to the current value. + */ + valueAngle: null | number; } >({ value: null, @@ -118,6 +122,7 @@ export const GaugeContext = React.createContext< cx: 0, cy: 0, maxRadius: 0, + valueAngle: null, }); export interface GaugeProviderProps extends GaugeConfig, CircularConfig { @@ -165,34 +170,40 @@ export function GaugeProvider(props: GaugeProviderProps) { const innerRadius = getPercentageValue(innerRadiusParam ?? '80%', maxRadius); const cornerRadius = getPercentageValue(cornerRadiusParam ?? 0, outerRadius - innerRadius); - const contextValue = React.useMemo( - () => ({ - value, - valueMin, - valueMax, - startAngle: (Math.PI * startAngle) / 180, - endAngle: (Math.PI * endAngle) / 180, - outerRadius, - innerRadius, - cornerRadius, - cx, - cy, - maxRadius, - }), - [ + const contextValue = React.useMemo(() => { + const startAngleRad = (Math.PI * startAngle) / 180; + const endAngleRad = (Math.PI * endAngle) / 180; + return { value, valueMin, valueMax, - startAngle, - endAngle, + startAngle: startAngleRad, + endAngle: endAngleRad, outerRadius, innerRadius, cornerRadius, cx, cy, maxRadius, - ], - ); + valueAngle: + value === null + ? null + : startAngleRad + + ((endAngleRad - startAngleRad) * (value - valueMin)) / (valueMax - valueMin), + }; + }, [ + value, + valueMin, + valueMax, + startAngle, + endAngle, + outerRadius, + innerRadius, + cornerRadius, + cx, + cy, + maxRadius, + ]); return {children}; } diff --git a/packages/x-charts/src/Gauge/index.ts b/packages/x-charts/src/Gauge/index.ts index 30ce6d63f97a3..8e742bb16073b 100644 --- a/packages/x-charts/src/Gauge/index.ts +++ b/packages/x-charts/src/Gauge/index.ts @@ -4,3 +4,4 @@ export * from './GaugeValueText'; export * from './GaugeValueArc'; export * from './GaugeReferenceArc'; export * from './gaugeClasses'; +export { useGaugeState } from './GaugeProvider'; From a1886ff5f459eb9e0944c9dab9335074c5038224 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 12 Feb 2024 14:34:02 +0100 Subject: [PATCH 14/20] docs --- docs/data/charts/gauge/gauge.md | 13 +++++++++---- docs/data/pages.ts | 2 +- docs/src/modules/components/ChartComponentsGrid.js | 6 ++++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/docs/data/charts/gauge/gauge.md b/docs/data/charts/gauge/gauge.md index 2b7436299af45..2bd1ba3912d6f 100644 --- a/docs/data/charts/gauge/gauge.md +++ b/docs/data/charts/gauge/gauge.md @@ -68,11 +68,11 @@ THe first solution is to add your component as children. They will be stacked on top of the default rendering. ```tsx -import { Gauge } from '@mui/x-charts/Gauge' +import { Gauge } from '@mui/x-charts/Gauge'; - +; ``` ### Using the Gauge container @@ -84,13 +84,18 @@ The second solution is to start from scratch with our components: - GaugeValueText ```tsx -import { GaugeContainer, Gauge , GaugeReferenceArc, GaugeValueArc } from '@mui/x-charts/Gauge' +import { + GaugeContainer, + Gauge, + GaugeReferenceArc, + GaugeValueArc, +} from '@mui/x-charts/Gauge'; - +; ``` ### Creating your components diff --git a/docs/data/pages.ts b/docs/data/pages.ts index a1eadb385cf86..66a29204d8955 100644 --- a/docs/data/pages.ts +++ b/docs/data/pages.ts @@ -407,6 +407,7 @@ const pages: MuiPage[] = [ { pathname: '/x/react-charts/bar-demo', title: 'Demos' }, ], }, + { pathname: '/x/react-charts/gauge', title: 'Gauge' }, { pathname: '/x/react-charts-lines', title: 'Lines', @@ -458,7 +459,6 @@ const pages: MuiPage[] = [ pathname: '/x/react-charts-future', subheader: 'Future components', children: [ - { pathname: '/x/react-charts/gauge', title: 'Gauge', planned: true }, { pathname: '/x/react-charts/heat-map', title: 'Heat map', planned: true }, { pathname: '/x/react-charts/radar', title: 'Radar', planned: true }, { pathname: '/x/react-charts/tree-map', title: 'Treemap', planned: true }, diff --git a/docs/src/modules/components/ChartComponentsGrid.js b/docs/src/modules/components/ChartComponentsGrid.js index 01ff00ecee366..6731a2f9cff6d 100644 --- a/docs/src/modules/components/ChartComponentsGrid.js +++ b/docs/src/modules/components/ChartComponentsGrid.js @@ -38,6 +38,12 @@ function components() { srcDark: '/static/x/component-illustrations/sparkline-dark.png', href: '/x/react-charts/sparkline/', }, + // { + // title: 'Gauge', + // srcLight: '/static/x/component-illustrations/gauge-light.png', + // srcDark: '/static/x/component-illustrations/gauge-dark.png', + // href: '/x/react-charts/gauge/', + // }, ]; } From b4b9d62b1fb48849e04e2f2082b1f108b2b29272 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 12 Feb 2024 14:50:42 +0100 Subject: [PATCH 15/20] scripts --- docs/pages/x/api/charts/gauge-container.json | 5 ++++- docs/pages/x/api/charts/gauge.json | 5 ++++- .../api-docs/charts/gauge-container/gauge-container.json | 2 +- docs/translations/api-docs/charts/gauge/gauge.json | 2 +- packages/x-charts/src/Gauge/Gauge.tsx | 5 +++-- packages/x-charts/src/Gauge/GaugeContainer.tsx | 5 +++-- scripts/x-charts.exports.json | 1 + 7 files changed, 17 insertions(+), 8 deletions(-) diff --git a/docs/pages/x/api/charts/gauge-container.json b/docs/pages/x/api/charts/gauge-container.json index 80d1aff0376c7..e23ab70ab0dab 100644 --- a/docs/pages/x/api/charts/gauge-container.json +++ b/docs/pages/x/api/charts/gauge-container.json @@ -1,6 +1,9 @@ { "props": { - "cornerRadius": { "type": { "name": "number" }, "default": "'50%'" }, + "cornerRadius": { + "type": { "name": "union", "description": "number
| string" }, + "default": "0" + }, "cx": { "type": { "name": "union", "description": "number
| string" } }, "cy": { "type": { "name": "union", "description": "number
| string" } }, "disableAxisListener": { "type": { "name": "bool" }, "default": "false" }, diff --git a/docs/pages/x/api/charts/gauge.json b/docs/pages/x/api/charts/gauge.json index a5bafe86b40e4..48c9dfb790cc2 100644 --- a/docs/pages/x/api/charts/gauge.json +++ b/docs/pages/x/api/charts/gauge.json @@ -1,6 +1,9 @@ { "props": { - "cornerRadius": { "type": { "name": "number" }, "default": "'50%'" }, + "cornerRadius": { + "type": { "name": "union", "description": "number
| string" }, + "default": "0" + }, "cx": { "type": { "name": "union", "description": "number
| string" } }, "cy": { "type": { "name": "union", "description": "number
| string" } }, "disableAxisListener": { "type": { "name": "bool" }, "default": "false" }, diff --git a/docs/translations/api-docs/charts/gauge-container/gauge-container.json b/docs/translations/api-docs/charts/gauge-container/gauge-container.json index 6c230d3a76104..d1712fc443149 100644 --- a/docs/translations/api-docs/charts/gauge-container/gauge-container.json +++ b/docs/translations/api-docs/charts/gauge-container/gauge-container.json @@ -2,7 +2,7 @@ "componentDescription": "", "propDescriptions": { "cornerRadius": { - "description": "The radius applied to arc corners (similar to border radius)." + "description": "The radius applied to arc corners (similar to border radius). Set it to '50%' to get rounded arc." }, "cx": { "description": "The x coordinate of the pie center. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the width the drawing area." diff --git a/docs/translations/api-docs/charts/gauge/gauge.json b/docs/translations/api-docs/charts/gauge/gauge.json index 0bb21d98477eb..af156f44ef821 100644 --- a/docs/translations/api-docs/charts/gauge/gauge.json +++ b/docs/translations/api-docs/charts/gauge/gauge.json @@ -2,7 +2,7 @@ "componentDescription": "", "propDescriptions": { "cornerRadius": { - "description": "The radius applied to arc corners (similar to border radius)." + "description": "The radius applied to arc corners (similar to border radius). Set it to '50%' to get rounded arc." }, "cx": { "description": "The x coordinate of the pie center. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the width the drawing area." diff --git a/packages/x-charts/src/Gauge/Gauge.tsx b/packages/x-charts/src/Gauge/Gauge.tsx index 0df69d8d240af..1fc780cadbf6a 100644 --- a/packages/x-charts/src/Gauge/Gauge.tsx +++ b/packages/x-charts/src/Gauge/Gauge.tsx @@ -48,9 +48,10 @@ Gauge.propTypes = { className: PropTypes.string, /** * The radius applied to arc corners (similar to border radius). - * @default '50%' + * Set it to '50%' to get rounded arc. + * @default 0 */ - cornerRadius: PropTypes.number, + cornerRadius: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), /** * The x coordinate of the pie center. * Can be a number (in px) or a string with a percentage such as '50%'. diff --git a/packages/x-charts/src/Gauge/GaugeContainer.tsx b/packages/x-charts/src/Gauge/GaugeContainer.tsx index aa6c10d399ffd..ce2576cb77c31 100644 --- a/packages/x-charts/src/Gauge/GaugeContainer.tsx +++ b/packages/x-charts/src/Gauge/GaugeContainer.tsx @@ -127,9 +127,10 @@ GaugeContainer.propTypes = { className: PropTypes.string, /** * The radius applied to arc corners (similar to border radius). - * @default '50%' + * Set it to '50%' to get rounded arc. + * @default 0 */ - cornerRadius: PropTypes.number, + cornerRadius: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), /** * The x coordinate of the pie center. * Can be a number (in px) or a string with a percentage such as '50%'. diff --git a/scripts/x-charts.exports.json b/scripts/x-charts.exports.json index af30bf2893f00..1115db0329013 100644 --- a/scripts/x-charts.exports.json +++ b/scripts/x-charts.exports.json @@ -250,6 +250,7 @@ { "name": "StackOffsetType", "kind": "TypeAlias" }, { "name": "StackOrderType", "kind": "TypeAlias" }, { "name": "useDrawingArea", "kind": "Function" }, + { "name": "useGaugeState", "kind": "Function" }, { "name": "useXScale", "kind": "Function" }, { "name": "useYScale", "kind": "Function" } ] From ebaefbe12a935bc86e0baf80152e55c954b57efb Mon Sep 17 00:00:00 2001 From: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:46:02 +0100 Subject: [PATCH 16/20] Apply suggestions from code review Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Co-authored-by: Lukas Signed-off-by: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com> --- docs/data/charts/gauge/gauge.md | 47 +++++++++---------- packages/x-charts/src/Gauge/GaugeProvider.tsx | 4 +- packages/x-charts/src/Gauge/utils.ts | 2 +- 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/docs/data/charts/gauge/gauge.md b/docs/data/charts/gauge/gauge.md index 2bd1ba3912d6f..1926de20675ce 100644 --- a/docs/data/charts/gauge/gauge.md +++ b/docs/data/charts/gauge/gauge.md @@ -11,16 +11,14 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/meter/ ## Basic gauge -The Gauge display a numeric value that varies within a defined range. +The Gauge displays a numeric value that varies within a defined range. {{"demo": "BasicGauges.js"}} ## Value range -The value of the Gauge is provided by props `value`. - -By default it's assumed to be between 0 and 100. -You can modify this range with props `valueMin` and `valueMax`. +The Gauge chart's value is provided through the `value` props, which accept a value range between 0 and 100. +To modify it, use the `valueMin` and `valueMax` props. {{"demo": "GaugeValueRangeNoSnap.js"}} @@ -28,16 +26,16 @@ You can modify this range with props `valueMin` and `valueMax`. You can modify the arc shape with the following props: -- `startAngle`, `endAngle`: Angle range provided in degrees -- `innerRadius`, `outerRadius`: Radius of the arc. It can be a number for fix number of px. Or a percentage string which will be a percent of the maximal available radius. -- `cornerRadius`: It can be a number for fix number of px. Or a percentage string which will be a percent of distance between inner and outer radius. +- `startAngle` and `endAngle`: The angle range provided in degrees +- `innerRadius` and `outerRadius`: The arc's radii. It can be a fixed number of pixels or a percentage string, which will be a percent of the maximal available radius. +- `cornerRadius`: It can be a fixed number of pixels or a percentage string, which will be a percent of the maximal available radius. {{"demo": "ArcPlaygroundNoSnap.js"}} :::info -Notice that the arc position is computed to let the Gauge take as much space as possible in the drawing area. +Notice that the arc position is computed to let the Gauge chart take as much space as possible in the drawing area. -Provide props `cx` and/or `cy` to fix the coordinate of the arc center. +Use the `cx` and/or `cy` props to fix the coordinate of the arc center. ::: ## Text configuration @@ -48,14 +46,15 @@ To modify it, use the `text` prop. This prop can be a string, or a formatter. In the second case, the formatter argument contains the `value`, `valueMin` and `valueMax`. -To modify the layout of the text, use the class name `gaugeClasses.valueText`. +To modify the text's layout, use the `gaugeClasses.valueText` class name. {{"demo": "TextPlaygroundNoSnap.js"}} ## Arc design -You can customize the Gauge style with usual selectors. -The `gaugeClasses` provides class names to select parts of the component, such as `valueText`, `valueArc`, and `referenceArc`. +To customize the Gauge styles, use the `chartsGaugeClasses` export to pull class names from different parts of the component, such as `valueText`, `valueArc`, and `referenceArc`. + +For a full reference list, visit the [API page](/x/api/charts/gauge/#classes). {{"demo": "ArcDesign.js"}} @@ -63,9 +62,7 @@ The `gaugeClasses` provides class names to select parts of the component, such a ### Using the default Gauge -If the default Gauge does not contain all the visual elements you're looking for, you can add them. -THe first solution is to add your component as children. -They will be stacked on top of the default rendering. +To insert more elements into the Gauge chart, the first option would be to add them as children, which means they will be stacked on top of the default rendering. ```tsx import { Gauge } from '@mui/x-charts/Gauge'; @@ -77,7 +74,7 @@ import { Gauge } from '@mui/x-charts/Gauge'; ### Using the Gauge container -The second solution is to start from scratch with our components: +The second option is to make use of the following elements that are available within the Gauge module: - GaugeReferenceArc - GaugeValueArc @@ -100,19 +97,19 @@ import { ### Creating your components -To create your own components, use `useGaugeState` hook which provides all you need about the gauge configuration: +To create your own components, use the `useGaugeState` hook which provides all you need about the gauge configuration: -- Information about the value: `value`, `valueMin`, `valueMax` -- Information to plot the arc: `startAngle`, `endAngle`, `outerRadius`, `innerRadius`, `cornerRadius`, `cx`, and `cy` -- Computed values: - - `maxRadius` the maximal radius that can fit in the drawing area. - - `valueAngle` the angle associated to the current value. +- information about the value: `value`, `valueMin`, `valueMax`; +- information to plot the arc: `startAngle`, `endAngle`, `outerRadius`, `innerRadius`, `cornerRadius`, `cx`, and `cy`; +- computed values: + - `maxRadius` the maximal radius that can fit the drawing area; + - `valueAngle` the angle associated with the current value. {{"demo": "CompositionExample.js"}} ## Accessibility -(WAI-ARIA: [https://www.w3.org/WAI/ARIA/apg/patterns/meter/](https://www.w3.org/WAI/ARIA/apg/patterns/meter/)) +The MUI X Gauge chart is compliant with the [Meter ARIA pattern](https://www.w3.org/WAI/ARIA/apg/patterns/meter/), which includes the addition of the `meter` role to the parent container and correct usage of the `aria-valuenow`, `aria-valuemin`, and `aria-valuemax` attributes. ### Label @@ -124,7 +121,7 @@ Otherwise, the label can be provided by `aria-label`. Assistive technologies often present the value as a percentage. This can be modified by providing `aria-valuetext` attribute. -For example a battery level indicator is better with a duration in hours. +For example, a battery level indicator is better with an hour-long duration. ```jsx

diff --git a/packages/x-charts/src/Gauge/GaugeProvider.tsx b/packages/x-charts/src/Gauge/GaugeProvider.tsx index 28fe4d8a14bc9..8b415a555f10c 100644 --- a/packages/x-charts/src/Gauge/GaugeProvider.tsx +++ b/packages/x-charts/src/Gauge/GaugeProvider.tsx @@ -83,7 +83,7 @@ interface ProcessedCircularConfig { interface GaugeConfig { /** * The value of the gauge. - * Set to `null` if no value to display. + * Set to `null` to not display a value. */ value?: number | null; /** @@ -102,7 +102,7 @@ export const GaugeContext = React.createContext< Required & ProcessedCircularConfig & { /** - * The maximal radius from (cx, cy) that fit that arc in the drawing area. + * The maximal radius from (cx, cy) that fits the arc in the drawing area. */ maxRadius: number; /** diff --git a/packages/x-charts/src/Gauge/utils.ts b/packages/x-charts/src/Gauge/utils.ts index b78e37cd30349..f8730c788e6c4 100644 --- a/packages/x-charts/src/Gauge/utils.ts +++ b/packages/x-charts/src/Gauge/utils.ts @@ -15,7 +15,7 @@ export function getArcRatios(startAngle: number, endAngle: number) { // Set the start, end and center point. const points = [[0, 0], getPoint(startAngle), getPoint(endAngle)]; - // Add cardinals points included in the arc + // Add cardinal points included in the arc const minAngle = Math.min(startAngle, endAngle); const maxAngle = Math.max(startAngle, endAngle); From fe2328a58f9f5a9af9c36f58a5fba2b2d8fa69f8 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 15 Feb 2024 13:25:48 +0100 Subject: [PATCH 17/20] scripts --- .../api-docs/charts/gauge-container/gauge-container.json | 2 +- docs/translations/api-docs/charts/gauge/gauge.json | 2 +- packages/x-charts/src/Gauge/Gauge.tsx | 2 +- packages/x-charts/src/Gauge/GaugeContainer.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/translations/api-docs/charts/gauge-container/gauge-container.json b/docs/translations/api-docs/charts/gauge-container/gauge-container.json index d1712fc443149..1088efeac4079 100644 --- a/docs/translations/api-docs/charts/gauge-container/gauge-container.json +++ b/docs/translations/api-docs/charts/gauge-container/gauge-container.json @@ -28,7 +28,7 @@ }, "startAngle": { "description": "The start angle (deg)." }, "value": { - "description": "The value of the gauge. Set to null if no value to display." + "description": "The value of the gauge. Set to null to not display a value." }, "valueMax": { "description": "The maximal value of the gauge." }, "valueMin": { "description": "The minimal value of the gauge." }, diff --git a/docs/translations/api-docs/charts/gauge/gauge.json b/docs/translations/api-docs/charts/gauge/gauge.json index af156f44ef821..cacdb3667ba09 100644 --- a/docs/translations/api-docs/charts/gauge/gauge.json +++ b/docs/translations/api-docs/charts/gauge/gauge.json @@ -28,7 +28,7 @@ }, "startAngle": { "description": "The start angle (deg)." }, "value": { - "description": "The value of the gauge. Set to null if no value to display." + "description": "The value of the gauge. Set to null to not display a value." }, "valueMax": { "description": "The maximal value of the gauge." }, "valueMin": { "description": "The minimal value of the gauge." }, diff --git a/packages/x-charts/src/Gauge/Gauge.tsx b/packages/x-charts/src/Gauge/Gauge.tsx index 1fc780cadbf6a..03662169de878 100644 --- a/packages/x-charts/src/Gauge/Gauge.tsx +++ b/packages/x-charts/src/Gauge/Gauge.tsx @@ -121,7 +121,7 @@ Gauge.propTypes = { title: PropTypes.string, /** * The value of the gauge. - * Set to `null` if no value to display. + * Set to `null` to not display a value. */ value: PropTypes.number, /** diff --git a/packages/x-charts/src/Gauge/GaugeContainer.tsx b/packages/x-charts/src/Gauge/GaugeContainer.tsx index ce2576cb77c31..3fbb2de9824fc 100644 --- a/packages/x-charts/src/Gauge/GaugeContainer.tsx +++ b/packages/x-charts/src/Gauge/GaugeContainer.tsx @@ -199,7 +199,7 @@ GaugeContainer.propTypes = { title: PropTypes.string, /** * The value of the gauge. - * Set to `null` if no value to display. + * Set to `null` to not display a value. */ value: PropTypes.number, /** From a4f47693c066fb7a45a7014b790cd0a90636fb5a Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 15 Feb 2024 13:36:35 +0100 Subject: [PATCH 18/20] prevent deleting numbers --- docs/src/modules/components/DemoPropsForm.tsx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/src/modules/components/DemoPropsForm.tsx b/docs/src/modules/components/DemoPropsForm.tsx index 8f0d4a5eaefb6..87cc5e0666b58 100644 --- a/docs/src/modules/components/DemoPropsForm.tsx +++ b/docs/src/modules/components/DemoPropsForm.tsx @@ -367,14 +367,15 @@ export default function ChartDemoPropsForm( ? (props[propName] as number) : (defaultValue as string) } - onChange={(event) => + onChange={(event) => { + if (Number.isNaN(Number.parseFloat(event.target.value))) { + return; + } setProps((latestProps) => ({ ...latestProps, - [propName]: Number.isNaN(event.target.value) - ? undefined - : Number.parseFloat(event.target.value), - })) - } + [propName]: Number.parseFloat(event.target.value), + })); + }} sx={{ textTransform: 'capitalize', [`& .${inputClasses.root}`]: { From 5b3111f53aa3c69cca32c04aa98185a282576a9f Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 15 Feb 2024 14:03:43 +0100 Subject: [PATCH 19/20] feedback --- docs/data/charts/gauge/gauge.md | 4 ++++ .../api-docs/charts/gauge-container/gauge-container.json | 4 ++-- docs/translations/api-docs/charts/gauge/gauge.json | 4 ++-- packages/x-charts/src/Gauge/Gauge.tsx | 6 +++--- packages/x-charts/src/Gauge/GaugeContainer.tsx | 4 ++-- packages/x-charts/src/Gauge/GaugeProvider.tsx | 4 ++-- 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/docs/data/charts/gauge/gauge.md b/docs/data/charts/gauge/gauge.md index 1926de20675ce..8e64e50022d05 100644 --- a/docs/data/charts/gauge/gauge.md +++ b/docs/data/charts/gauge/gauge.md @@ -2,6 +2,8 @@ title: React Gauge chart productId: x-charts components: Gauge, GaugeContainer +packageName: '@mui/x-charts' +githubLabel: 'component: charts' waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/meter/ --- @@ -9,6 +11,8 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/meter/

Gauge charts let the user evaluate metrics.

+{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} + ## Basic gauge The Gauge displays a numeric value that varies within a defined range. diff --git a/docs/translations/api-docs/charts/gauge-container/gauge-container.json b/docs/translations/api-docs/charts/gauge-container/gauge-container.json index 1088efeac4079..06c25cdf282c1 100644 --- a/docs/translations/api-docs/charts/gauge-container/gauge-container.json +++ b/docs/translations/api-docs/charts/gauge-container/gauge-container.json @@ -5,10 +5,10 @@ "description": "The radius applied to arc corners (similar to border radius). Set it to '50%' to get rounded arc." }, "cx": { - "description": "The x coordinate of the pie center. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the width the drawing area." + "description": "The x coordinate of the arc center. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the width the drawing area." }, "cy": { - "description": "The y coordinate of the pie center. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the height the drawing area." + "description": "The y coordinate of the arc center. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the height the drawing area." }, "disableAxisListener": { "description": "If true, the charts will not listen to the mouse move event. It might break interactive features, but will improve performance." diff --git a/docs/translations/api-docs/charts/gauge/gauge.json b/docs/translations/api-docs/charts/gauge/gauge.json index cacdb3667ba09..9e20b39149427 100644 --- a/docs/translations/api-docs/charts/gauge/gauge.json +++ b/docs/translations/api-docs/charts/gauge/gauge.json @@ -5,10 +5,10 @@ "description": "The radius applied to arc corners (similar to border radius). Set it to '50%' to get rounded arc." }, "cx": { - "description": "The x coordinate of the pie center. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the width the drawing area." + "description": "The x coordinate of the arc center. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the width the drawing area." }, "cy": { - "description": "The y coordinate of the pie center. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the height the drawing area." + "description": "The y coordinate of the arc center. Can be a number (in px) or a string with a percentage such as '50%'. The '100%' is the height the drawing area." }, "disableAxisListener": { "description": "If true, the charts will not listen to the mouse move event. It might break interactive features, but will improve performance." diff --git a/packages/x-charts/src/Gauge/Gauge.tsx b/packages/x-charts/src/Gauge/Gauge.tsx index 03662169de878..1884344bec29a 100644 --- a/packages/x-charts/src/Gauge/Gauge.tsx +++ b/packages/x-charts/src/Gauge/Gauge.tsx @@ -26,7 +26,7 @@ const useUtilityClasses = (props: GaugeProps) => { }; function Gauge(props: GaugeProps) { - const { text, children, ...other } = props; + const { text, children, classes: propsClasses, ...other } = props; const classes = useUtilityClasses(props); return ( @@ -53,13 +53,13 @@ Gauge.propTypes = { */ cornerRadius: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), /** - * The x coordinate of the pie center. + * The x coordinate of the arc center. * Can be a number (in px) or a string with a percentage such as '50%'. * The '100%' is the width the drawing area. */ cx: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), /** - * The y coordinate of the pie center. + * The y coordinate of the arc center. * Can be a number (in px) or a string with a percentage such as '50%'. * The '100%' is the height the drawing area. */ diff --git a/packages/x-charts/src/Gauge/GaugeContainer.tsx b/packages/x-charts/src/Gauge/GaugeContainer.tsx index 3fbb2de9824fc..8b00d695c5026 100644 --- a/packages/x-charts/src/Gauge/GaugeContainer.tsx +++ b/packages/x-charts/src/Gauge/GaugeContainer.tsx @@ -132,13 +132,13 @@ GaugeContainer.propTypes = { */ cornerRadius: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), /** - * The x coordinate of the pie center. + * The x coordinate of the arc center. * Can be a number (in px) or a string with a percentage such as '50%'. * The '100%' is the width the drawing area. */ cx: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), /** - * The y coordinate of the pie center. + * The y coordinate of the arc center. * Can be a number (in px) or a string with a percentage such as '50%'. * The '100%' is the height the drawing area. */ diff --git a/packages/x-charts/src/Gauge/GaugeProvider.tsx b/packages/x-charts/src/Gauge/GaugeProvider.tsx index 8b415a555f10c..ffdb99ecb0df6 100644 --- a/packages/x-charts/src/Gauge/GaugeProvider.tsx +++ b/packages/x-charts/src/Gauge/GaugeProvider.tsx @@ -36,13 +36,13 @@ interface CircularConfig { */ cornerRadius?: number | string; /** - * The x coordinate of the pie center. + * The x coordinate of the arc center. * Can be a number (in px) or a string with a percentage such as '50%'. * The '100%' is the width the drawing area. */ cx?: number | string; /** - * The y coordinate of the pie center. + * The y coordinate of the arc center. * Can be a number (in px) or a string with a percentage such as '50%'. * The '100%' is the height the drawing area. */ From 8dfeffd18fa5baf87dcca265e2e51b834ffa514e Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 15 Feb 2024 14:49:57 +0100 Subject: [PATCH 20/20] script --- docs/.link-check-errors.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/.link-check-errors.txt b/docs/.link-check-errors.txt index b753b2a7b7041..87eaaff0f8d8b 100644 --- a/docs/.link-check-errors.txt +++ b/docs/.link-check-errors.txt @@ -11,6 +11,7 @@ Broken links found by `yarn docs:link-check` that exist: - https://mui.com/system/styles/api/#serverstylesheets - https://mui.com/system/styles/api/#stylesprovider - https://mui.com/system/styles/api/#themeprovider +- https://mui.com/x/api/charts/gauge/#classes - https://mui.com/x/api/data-grid/data-grid/#DataGrid-prop-filterDebounceMs - https://mui.com/x/api/data-grid/data-grid/#props - https://mui.com/x/api/data-grid/data-grid/#slots