@mantine/charts 9.6.1 → 9.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"GaugeChart.mjs","names":["classes"],"sources":["../../src/GaugeChart/GaugeChart.tsx"],"sourcesContent":["import {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getThemeColor,\n MantineColor,\n rem,\n StylesApiProps,\n useMantineTheme,\n useProps,\n useStyles,\n} from '@mantine/core';\nimport classes from './GaugeChart.module.css';\n\nexport interface GaugeChartSection {\n /** Upper bound value for this section */\n value: number;\n\n /** Color of the section */\n color: MantineColor;\n}\n\nexport type GaugeChartStylesNames = 'root' | 'track' | 'section' | 'needle' | 'label';\n\nexport type GaugeChartCssVariables = {\n root: '--gauge-size';\n};\n\nexport interface GaugeChartProps\n extends\n BoxProps,\n StylesApiProps<GaugeChartFactory>,\n ElementProps<'svg', 'display' | 'opacity' | 'viewBox' | 'width' | 'height' | 'target'> {\n /** Current value to display. Fills the arc from `min` up to `value`, unless `sections` is set – then the arc is colored by thresholds and the value is displayed only in the center label. */\n value: number;\n\n /** Minimum value of the gauge, @default 0 */\n min?: number;\n\n /** Maximum value of the gauge, @default 100 */\n max?: number;\n\n /** Value marked on the arc with a line marker, use to display a goal or the current value of a gauge with `sections` */\n target?: number;\n\n /** Threshold sections of the gauge arc, each section is filled from the previous section upper bound to its own `value`. If set, the arc is not filled based on `value`. */\n sections?: GaugeChartSection[];\n\n /** Arc thickness in px, @default 12 */\n thickness?: number;\n\n /** Chart size (width and height), @default 200 */\n size?: number;\n\n /** Start angle in degrees, @default -120 */\n startAngle?: number;\n\n /** End angle in degrees, @default 120 */\n endAngle?: number;\n\n /** Label displayed in the center of the gauge */\n label?: React.ReactNode;\n\n /** Value formatter for default label, @default (v) => String(v) */\n valueFormatter?: (value: number) => string;\n\n /** Color of the gauge track (unfilled portion) */\n trackColor?: MantineColor;\n\n /** Color of the filled arc when sections are not provided */\n filledColor?: MantineColor;\n\n /** Color of the target marker */\n targetColor?: MantineColor;\n\n /** Thickness of the target marker, @default 2 */\n targetSize?: number;\n\n /** Whether to round arc endpoints. Not applied to `sections` – rounded caps of adjacent sections would overlap each other. @default false */\n roundCaps?: boolean;\n}\n\nexport type GaugeChartFactory = Factory<{\n props: GaugeChartProps;\n ref: SVGSVGElement;\n stylesNames: GaugeChartStylesNames;\n vars: GaugeChartCssVariables;\n}>;\n\nconst defaultProps = {\n min: 0,\n max: 100,\n thickness: 12,\n size: 200,\n startAngle: -120,\n endAngle: 120,\n roundCaps: false,\n targetSize: 2,\n} satisfies Partial<GaugeChartProps>;\n\nconst varsResolver = createVarsResolver<GaugeChartFactory>((_theme, { size }) => ({\n root: {\n '--gauge-size': rem(size),\n },\n}));\n\nfunction polarToCartesian(cx: number, cy: number, r: number, angleDeg: number) {\n const rad = ((angleDeg - 90) * Math.PI) / 180;\n return { x: cx + r * Math.cos(rad), y: cy + r * Math.sin(rad) };\n}\n\nfunction describeArc(cx: number, cy: number, r: number, startAngle: number, endAngle: number) {\n const delta = endAngle - startAngle;\n const sweep = delta >= 0 ? 1 : 0;\n const start = polarToCartesian(cx, cy, r, startAngle);\n\n // A single arc command cannot express a full circle – its endpoints would be identical\n // and nothing would be rendered, so it is split into two half-circle arcs.\n if (Math.abs(delta) >= 360) {\n const mid = polarToCartesian(cx, cy, r, startAngle + (delta >= 0 ? 180 : -180));\n return `M ${start.x} ${start.y} A ${r} ${r} 0 0 ${sweep} ${mid.x} ${mid.y} A ${r} ${r} 0 0 ${sweep} ${start.x} ${start.y}`;\n }\n\n const end = polarToCartesian(cx, cy, r, endAngle);\n const largeArc = Math.abs(delta) > 180 ? 1 : 0;\n return `M ${start.x} ${start.y} A ${r} ${r} 0 ${largeArc} ${sweep} ${end.x} ${end.y}`;\n}\n\nfunction valueToAngle(\n value: number,\n min: number,\n max: number,\n startAngle: number,\n endAngle: number\n) {\n if (max === min) {\n return startAngle;\n }\n const clamped = Math.max(min, Math.min(max, value));\n return startAngle + ((clamped - min) / (max - min)) * (endAngle - startAngle);\n}\n\nfunction isAngleInArc(angle: number, start: number, end: number) {\n const delta = end - start;\n\n if (Math.abs(delta) >= 360) {\n return true;\n }\n\n // Distance from the start angle measured along the direction the arc sweeps,\n // so that descending ranges (endAngle < startAngle) are handled the same way.\n const distance = delta >= 0 ? angle - start : start - angle;\n return ((distance % 360) + 360) % 360 <= Math.abs(delta);\n}\n\nfunction getArcBoundingBox(\n cx: number,\n cy: number,\n r: number,\n startAngle: number,\n endAngle: number,\n padding: number,\n labelReserve: number\n) {\n const startPt = polarToCartesian(cx, cy, r, startAngle);\n const endPt = polarToCartesian(cx, cy, r, endAngle);\n\n let minX = Math.min(startPt.x, endPt.x, cx - labelReserve);\n let maxX = Math.max(startPt.x, endPt.x, cx + labelReserve);\n let minY = Math.min(startPt.y, endPt.y, cy - labelReserve);\n let maxY = Math.max(startPt.y, endPt.y, cy + labelReserve);\n\n const cardinals = [\n { angle: 0, x: cx, y: cy - r },\n { angle: 90, x: cx + r, y: cy },\n { angle: 180, x: cx, y: cy + r },\n { angle: 270, x: cx - r, y: cy },\n ];\n\n for (const cardinal of cardinals) {\n if (isAngleInArc(cardinal.angle, startAngle, endAngle)) {\n minX = Math.min(minX, cardinal.x);\n maxX = Math.max(maxX, cardinal.x);\n minY = Math.min(minY, cardinal.y);\n maxY = Math.max(maxY, cardinal.y);\n }\n }\n\n return {\n x: minX - padding,\n y: minY - padding,\n width: maxX - minX + padding * 2,\n height: maxY - minY + padding * 2,\n };\n}\n\nexport const GaugeChart = factory<GaugeChartFactory>((_props) => {\n const props = useProps('GaugeChart', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n attributes,\n value,\n min,\n max,\n target,\n sections,\n thickness,\n size,\n startAngle,\n endAngle,\n label,\n valueFormatter,\n trackColor,\n filledColor,\n targetColor,\n targetSize,\n roundCaps,\n variant,\n ...others\n } = props;\n\n const theme = useMantineTheme();\n\n const getStyles = useStyles<GaugeChartFactory>({\n name: 'GaugeChart',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const svgSize = size!;\n const cx = svgSize / 2;\n const cy = svgSize / 2;\n const r = (svgSize - thickness!) / 2;\n const strokeLinecap = roundCaps ? 'round' : 'butt';\n const needleLength = thickness! * 1.5;\n\n // The needle sticks out past the arc radius, and a round cap adds half of its own\n // width on top of that – both contribute at the same time. Only reserved when there is a\n // target to draw, otherwise every gauge without one would get an oversized viewBox and\n // render its arc smaller than the requested `size`.\n const needleExtent = needleLength / 2 + (roundCaps ? targetSize! / 2 : 0);\n const strokePadding = target != null ? Math.max(thickness! / 2, needleExtent) : thickness! / 2;\n\n // A gauge cannot span more than a full turn – a larger range would wrap the arc onto\n // itself and make later sections overwrite earlier ones.\n const span = endAngle! - startAngle!;\n const resolvedEndAngle = startAngle! + Math.max(-360, Math.min(360, span));\n\n const labelReserve = Math.max(thickness!, svgSize * 0.11);\n const bbox = getArcBoundingBox(\n cx,\n cy,\n r,\n startAngle!,\n resolvedEndAngle,\n strokePadding,\n labelReserve\n );\n\n const resolvedTrackColor = trackColor\n ? getThemeColor(trackColor, theme)\n : 'var(--mantine-color-default-border)';\n\n const trackPath = describeArc(cx, cy, r, startAngle!, resolvedEndAngle);\n\n const sectionElements =\n sections && sections.length > 0 ? (\n (() => {\n const sortedSections = [...sections].sort((a, b) => a.value - b.value);\n const direction = resolvedEndAngle >= startAngle! ? 1 : -1;\n let prevAngle = startAngle!;\n\n return sortedSections.map((section, index) => {\n const sectionEndAngle = valueToAngle(\n section.value,\n min!,\n max!,\n startAngle!,\n resolvedEndAngle\n );\n if ((sectionEndAngle - prevAngle) * direction <= 0) {\n return null;\n }\n const path = describeArc(cx, cy, r, prevAngle, sectionEndAngle);\n const resolvedColor = getThemeColor(section.color, theme);\n prevAngle = sectionEndAngle;\n\n return (\n <path\n key={index}\n {...getStyles('section')}\n d={path}\n fill=\"none\"\n stroke={resolvedColor}\n strokeWidth={thickness}\n strokeLinecap=\"butt\"\n />\n );\n });\n })()\n ) : (\n <path\n {...getStyles('section')}\n d={describeArc(\n cx,\n cy,\n r,\n startAngle!,\n valueToAngle(value, min!, max!, startAngle!, resolvedEndAngle)\n )}\n fill=\"none\"\n stroke={\n filledColor ? getThemeColor(filledColor, theme) : 'var(--mantine-primary-color-filled)'\n }\n strokeWidth={thickness}\n strokeLinecap={strokeLinecap}\n />\n );\n\n const needleElement =\n target != null\n ? (() => {\n const targetAngle = valueToAngle(target, min!, max!, startAngle!, resolvedEndAngle);\n const inner = polarToCartesian(cx, cy, r - needleLength / 2, targetAngle);\n const outer = polarToCartesian(cx, cy, r + needleLength / 2, targetAngle);\n const resolvedTargetColor = targetColor\n ? getThemeColor(targetColor, theme)\n : 'var(--mantine-color-bright)';\n\n return (\n <line\n {...getStyles('needle')}\n x1={inner.x}\n y1={inner.y}\n x2={outer.x}\n y2={outer.y}\n stroke={resolvedTargetColor}\n strokeWidth={targetSize}\n strokeLinecap={strokeLinecap}\n />\n );\n })()\n : null;\n\n const formatValue = valueFormatter || ((v: number) => String(v));\n\n // The arc is drawn from the clamped value, and `aria-valuetext` is defined as the\n // human-readable equivalent of `aria-valuenow` – reporting the raw value in either the\n // default label or `aria-valuetext` would contradict both the arc and `aria-valuenow`.\n const clampedValue = Math.max(min!, Math.min(max!, value));\n const formattedValue = formatValue(clampedValue);\n const labelContent = label !== undefined ? label : formattedValue;\n\n // A meter with no accessible name is announced as \"meter\" and nothing else, so there is\n // always a name. A string `label` names the metric (\"CPU usage\") and is used unless an\n // explicit `aria-label` is given; the generic fallback covers the rest. The default label\n // is the formatted value, which would only repeat `aria-valuetext`.\n const ariaLabel =\n others['aria-labelledby'] !== undefined\n ? undefined\n : (others['aria-label'] ?? (typeof label === 'string' ? label : undefined) ?? 'Gauge');\n\n return (\n <Box\n component=\"svg\"\n viewBox={`${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}`}\n __vars={{ '--gauge-aspect-ratio': `${bbox.width} / ${bbox.height}` }}\n {...getStyles('root')}\n variant={variant}\n role=\"meter\"\n aria-label={ariaLabel}\n aria-valuenow={clampedValue}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuetext={formattedValue}\n {...others}\n >\n <path\n {...getStyles('track')}\n d={trackPath}\n fill=\"none\"\n stroke={resolvedTrackColor}\n strokeWidth={thickness}\n strokeLinecap={strokeLinecap}\n />\n\n {sectionElements}\n {needleElement}\n\n <foreignObject x={bbox.x} y={bbox.y} width={bbox.width} height={bbox.height}>\n <div\n {...getStyles('label', {\n style: {\n transform: `translate(${cx - bbox.x - bbox.width / 2}px, ${cy - bbox.y - bbox.height / 2}px)`,\n },\n })}\n >\n {labelContent}\n </div>\n </foreignObject>\n </Box>\n );\n});\n\nGaugeChart.displayName = '@mantine/charts/GaugeChart';\nGaugeChart.classes = classes;\nGaugeChart.varsResolver = varsResolver;\n"],"mappings":"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"}
1
+ {"version":3,"file":"GaugeChart.mjs","names":["classes"],"sources":["../../src/GaugeChart/GaugeChart.tsx"],"sourcesContent":["import {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getThemeColor,\n MantineColor,\n rem,\n StylesApiProps,\n useMantineTheme,\n useProps,\n useStyles,\n} from '@mantine/core';\nimport classes from './GaugeChart.module.css';\n\nexport interface GaugeChartSection {\n /** Upper bound value for this section */\n value: number;\n\n /** Color of the section */\n color: MantineColor;\n}\n\nexport type GaugeChartStylesNames =\n | 'root'\n | 'track'\n | 'section'\n | 'sectionCap'\n | 'needle'\n | 'label';\n\nexport type GaugeChartCssVariables = {\n root: '--gauge-size';\n};\n\nexport interface GaugeChartProps\n extends\n BoxProps,\n StylesApiProps<GaugeChartFactory>,\n ElementProps<'svg', 'display' | 'opacity' | 'viewBox' | 'width' | 'height' | 'target'> {\n /** Current value to display. Fills the arc from `min` up to `value`, unless `sections` is set – then the arc is colored by thresholds and the value is displayed only in the center label. */\n value: number;\n\n /** Minimum value of the gauge, @default 0 */\n min?: number;\n\n /** Maximum value of the gauge, @default 100 */\n max?: number;\n\n /** Value marked on the arc with a line marker, use to display a goal or the current value of a gauge with `sections` */\n target?: number;\n\n /** Threshold sections of the gauge arc, each section is filled from the previous section upper bound to its own `value`. If set, the arc is not filled based on `value`. */\n sections?: GaugeChartSection[];\n\n /** Arc thickness in px, @default 12 */\n thickness?: number;\n\n /** Chart size (width and height), @default 200 */\n size?: number;\n\n /** Start angle in degrees, @default -120 */\n startAngle?: number;\n\n /** End angle in degrees, @default 120 */\n endAngle?: number;\n\n /** Label displayed in the center of the gauge */\n label?: React.ReactNode;\n\n /** Value formatter for default label, @default (v) => String(v) */\n valueFormatter?: (value: number) => string;\n\n /** Color of the gauge track (unfilled portion) */\n trackColor?: MantineColor;\n\n /** Color of the filled arc when sections are not provided */\n filledColor?: MantineColor;\n\n /** Color of the target marker */\n targetColor?: MantineColor;\n\n /** Thickness of the target marker, @default 2 */\n targetSize?: number;\n\n /** Whether to round arc endpoints. With `sections`, only the outer ends of the first and last sections are rounded. @default false */\n roundCaps?: boolean;\n}\n\nexport type GaugeChartFactory = Factory<{\n props: GaugeChartProps;\n ref: SVGSVGElement;\n stylesNames: GaugeChartStylesNames;\n vars: GaugeChartCssVariables;\n}>;\n\nconst defaultProps = {\n min: 0,\n max: 100,\n thickness: 12,\n size: 200,\n startAngle: -120,\n endAngle: 120,\n roundCaps: false,\n targetSize: 2,\n} satisfies Partial<GaugeChartProps>;\n\nconst varsResolver = createVarsResolver<GaugeChartFactory>((_theme, { size }) => ({\n root: {\n '--gauge-size': rem(size),\n },\n}));\n\nfunction polarToCartesian(cx: number, cy: number, r: number, angleDeg: number) {\n const rad = ((angleDeg - 90) * Math.PI) / 180;\n return { x: cx + r * Math.cos(rad), y: cy + r * Math.sin(rad) };\n}\n\nfunction describeArc(cx: number, cy: number, r: number, startAngle: number, endAngle: number) {\n const delta = endAngle - startAngle;\n const sweep = delta >= 0 ? 1 : 0;\n const start = polarToCartesian(cx, cy, r, startAngle);\n\n // A single arc command cannot express a full circle – its endpoints would be identical\n // and nothing would be rendered, so it is split into two half-circle arcs.\n if (Math.abs(delta) >= 360) {\n const mid = polarToCartesian(cx, cy, r, startAngle + (delta >= 0 ? 180 : -180));\n return `M ${start.x} ${start.y} A ${r} ${r} 0 0 ${sweep} ${mid.x} ${mid.y} A ${r} ${r} 0 0 ${sweep} ${start.x} ${start.y}`;\n }\n\n const end = polarToCartesian(cx, cy, r, endAngle);\n const largeArc = Math.abs(delta) > 180 ? 1 : 0;\n return `M ${start.x} ${start.y} A ${r} ${r} 0 ${largeArc} ${sweep} ${end.x} ${end.y}`;\n}\n\nfunction valueToAngle(\n value: number,\n min: number,\n max: number,\n startAngle: number,\n endAngle: number\n) {\n if (max === min) {\n return startAngle;\n }\n const clamped = Math.max(min, Math.min(max, value));\n return startAngle + ((clamped - min) / (max - min)) * (endAngle - startAngle);\n}\n\nfunction isAngleInArc(angle: number, start: number, end: number) {\n const delta = end - start;\n\n if (Math.abs(delta) >= 360) {\n return true;\n }\n\n // Distance from the start angle measured along the direction the arc sweeps,\n // so that descending ranges (endAngle < startAngle) are handled the same way.\n const distance = delta >= 0 ? angle - start : start - angle;\n return ((distance % 360) + 360) % 360 <= Math.abs(delta);\n}\n\nfunction getArcBoundingBox(\n cx: number,\n cy: number,\n r: number,\n startAngle: number,\n endAngle: number,\n padding: number,\n labelReserve: number\n) {\n const startPt = polarToCartesian(cx, cy, r, startAngle);\n const endPt = polarToCartesian(cx, cy, r, endAngle);\n\n let minX = Math.min(startPt.x, endPt.x, cx - labelReserve);\n let maxX = Math.max(startPt.x, endPt.x, cx + labelReserve);\n let minY = Math.min(startPt.y, endPt.y, cy - labelReserve);\n let maxY = Math.max(startPt.y, endPt.y, cy + labelReserve);\n\n const cardinals = [\n { angle: 0, x: cx, y: cy - r },\n { angle: 90, x: cx + r, y: cy },\n { angle: 180, x: cx, y: cy + r },\n { angle: 270, x: cx - r, y: cy },\n ];\n\n for (const cardinal of cardinals) {\n if (isAngleInArc(cardinal.angle, startAngle, endAngle)) {\n minX = Math.min(minX, cardinal.x);\n maxX = Math.max(maxX, cardinal.x);\n minY = Math.min(minY, cardinal.y);\n maxY = Math.max(maxY, cardinal.y);\n }\n }\n\n return {\n x: minX - padding,\n y: minY - padding,\n width: maxX - minX + padding * 2,\n height: maxY - minY + padding * 2,\n };\n}\n\nexport const GaugeChart = factory<GaugeChartFactory>((_props) => {\n const props = useProps('GaugeChart', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n attributes,\n value,\n min,\n max,\n target,\n sections,\n thickness,\n size,\n startAngle,\n endAngle,\n label,\n valueFormatter,\n trackColor,\n filledColor,\n targetColor,\n targetSize,\n roundCaps,\n variant,\n ...others\n } = props;\n\n const theme = useMantineTheme();\n\n const getStyles = useStyles<GaugeChartFactory>({\n name: 'GaugeChart',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const svgSize = size!;\n const cx = svgSize / 2;\n const cy = svgSize / 2;\n const r = (svgSize - thickness!) / 2;\n const strokeLinecap = roundCaps ? 'round' : 'butt';\n const needleLength = thickness! * 1.5;\n\n // The needle sticks out past the arc radius, and a round cap adds half of its own\n // width on top of that – both contribute at the same time. Only reserved when there is a\n // target to draw, otherwise every gauge without one would get an oversized viewBox and\n // render its arc smaller than the requested `size`.\n const needleExtent = needleLength / 2 + (roundCaps ? targetSize! / 2 : 0);\n const strokePadding = target != null ? Math.max(thickness! / 2, needleExtent) : thickness! / 2;\n\n // A gauge cannot span more than a full turn – a larger range would wrap the arc onto\n // itself and make later sections overwrite earlier ones.\n const span = endAngle! - startAngle!;\n const resolvedEndAngle = startAngle! + Math.max(-360, Math.min(360, span));\n\n const labelReserve = Math.max(thickness!, svgSize * 0.11);\n const bbox = getArcBoundingBox(\n cx,\n cy,\n r,\n startAngle!,\n resolvedEndAngle,\n strokePadding,\n labelReserve\n );\n\n const resolvedTrackColor = trackColor\n ? getThemeColor(trackColor, theme)\n : 'var(--mantine-color-default-border)';\n\n const trackPath = describeArc(cx, cy, r, startAngle!, resolvedEndAngle);\n\n const sectionElements =\n sections && sections.length > 0 ? (\n (() => {\n const sortedSections = [...sections].sort((a, b) => a.value - b.value);\n const direction = resolvedEndAngle >= startAngle! ? 1 : -1;\n let prevAngle = startAngle!;\n\n const resolvedSections = sortedSections.map((section) => {\n const sectionEndAngle = valueToAngle(\n section.value,\n min!,\n max!,\n startAngle!,\n resolvedEndAngle\n );\n if ((sectionEndAngle - prevAngle) * direction <= 0) {\n return null;\n }\n const path = describeArc(cx, cy, r, prevAngle, sectionEndAngle);\n prevAngle = sectionEndAngle;\n return { path, color: getThemeColor(section.color, theme) };\n });\n\n const visibleSections = resolvedSections.filter((section) => section !== null);\n\n const capSections =\n roundCaps && visibleSections.length > 0\n ? visibleSections.length === 1\n ? [visibleSections[0]]\n : [visibleSections[0], visibleSections[visibleSections.length - 1]]\n : [];\n\n return (\n <>\n {capSections.map((section, index) => (\n <path\n key={index}\n {...getStyles('sectionCap')}\n d={section.path}\n fill=\"none\"\n stroke={section.color}\n strokeWidth={thickness}\n strokeLinecap=\"round\"\n />\n ))}\n {resolvedSections.map((section, index) =>\n section ? (\n <path\n key={index}\n {...getStyles('section')}\n d={section.path}\n fill=\"none\"\n stroke={section.color}\n strokeWidth={thickness}\n strokeLinecap=\"butt\"\n />\n ) : null\n )}\n </>\n );\n })()\n ) : (\n <path\n {...getStyles('section')}\n d={describeArc(\n cx,\n cy,\n r,\n startAngle!,\n valueToAngle(value, min!, max!, startAngle!, resolvedEndAngle)\n )}\n fill=\"none\"\n stroke={\n filledColor ? getThemeColor(filledColor, theme) : 'var(--mantine-primary-color-filled)'\n }\n strokeWidth={thickness}\n strokeLinecap={strokeLinecap}\n />\n );\n\n const needleElement =\n target != null\n ? (() => {\n const targetAngle = valueToAngle(target, min!, max!, startAngle!, resolvedEndAngle);\n const inner = polarToCartesian(cx, cy, r - needleLength / 2, targetAngle);\n const outer = polarToCartesian(cx, cy, r + needleLength / 2, targetAngle);\n const resolvedTargetColor = targetColor\n ? getThemeColor(targetColor, theme)\n : 'var(--mantine-color-bright)';\n\n return (\n <line\n {...getStyles('needle')}\n x1={inner.x}\n y1={inner.y}\n x2={outer.x}\n y2={outer.y}\n stroke={resolvedTargetColor}\n strokeWidth={targetSize}\n strokeLinecap={strokeLinecap}\n />\n );\n })()\n : null;\n\n const formatValue = valueFormatter || ((v: number) => String(v));\n\n // The arc is drawn from the clamped value, and `aria-valuetext` is defined as the\n // human-readable equivalent of `aria-valuenow` – reporting the raw value in either the\n // default label or `aria-valuetext` would contradict both the arc and `aria-valuenow`.\n const clampedValue = Math.max(min!, Math.min(max!, value));\n const formattedValue = formatValue(clampedValue);\n const labelContent = label !== undefined ? label : formattedValue;\n\n // A meter with no accessible name is announced as \"meter\" and nothing else, so there is\n // always a name. A string `label` names the metric (\"CPU usage\") and is used unless an\n // explicit `aria-label` is given; the generic fallback covers the rest. The default label\n // is the formatted value, which would only repeat `aria-valuetext`.\n const ariaLabel =\n others['aria-labelledby'] !== undefined\n ? undefined\n : (others['aria-label'] ?? (typeof label === 'string' ? label : undefined) ?? 'Gauge');\n\n return (\n <Box\n component=\"svg\"\n viewBox={`${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}`}\n __vars={{ '--gauge-aspect-ratio': `${bbox.width} / ${bbox.height}` }}\n {...getStyles('root')}\n variant={variant}\n role=\"meter\"\n aria-label={ariaLabel}\n aria-valuenow={clampedValue}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuetext={formattedValue}\n {...others}\n >\n <path\n {...getStyles('track')}\n d={trackPath}\n fill=\"none\"\n stroke={resolvedTrackColor}\n strokeWidth={thickness}\n strokeLinecap={strokeLinecap}\n />\n\n {sectionElements}\n {needleElement}\n\n <foreignObject x={bbox.x} y={bbox.y} width={bbox.width} height={bbox.height}>\n <div\n {...getStyles('label', {\n style: {\n transform: `translate(${cx - bbox.x - bbox.width / 2}px, ${cy - bbox.y - bbox.height / 2}px)`,\n },\n })}\n >\n {labelContent}\n </div>\n </foreignObject>\n </Box>\n );\n});\n\nGaugeChart.displayName = '@mantine/charts/GaugeChart';\nGaugeChart.classes = classes;\nGaugeChart.varsResolver = varsResolver;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Heatmap.mjs","names":["classes"],"sources":["../../src/Heatmap/Heatmap.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Box,\n BoxProps,\n ElementProps,\n factory,\n Factory,\n StylesApiProps,\n Tooltip,\n TooltipFloatingProps,\n useProps,\n useStyles,\n} from '@mantine/core';\nimport { getBoundaries } from './get-boundaries/get-boundaries';\nimport { getColumns, getFirstMonthColumnIndex, HeatmapColumn } from './get-columns/get-columns';\nimport { getDatesRange } from './get-dates-range/get-dates-range';\nimport { getMonthsRange } from './get-months-range/get-months-range';\nimport { HeatmapSplitWeeks } from './HeatmapSplitWeeks';\nimport { HeatmapWeeks } from './HeatmapWeeks';\nimport { rotateWeekdaysNames } from './rotate-weekdays-names/rotate-weekdays-names';\nimport classes from './Heatmap.module.css';\n\nexport type HeatmapStylesNames =\n | 'root'\n | 'rect'\n | 'weekdayLabel'\n | 'monthLabel'\n | 'legend'\n | 'legendLabel'\n | 'legendRect';\n\ninterface HeatmapRectData {\n date: string;\n value: number | null;\n}\n\nexport interface HeatmapProps\n extends\n BoxProps,\n StylesApiProps<HeatmapFactory>,\n ElementProps<'svg', 'display' | 'opacity' | 'viewBox' | 'width' | 'height'> {\n /** Heatmap data, key is date in `YYYY-MM-DD` format (interpreted as a UTC calendar day) */\n data: Record<string, number>;\n\n /** Heatmap domain, array of 2 numbers, min and max values, calculated from data by default */\n domain?: [number, number];\n\n /** Heatmap start date. Current date - 1 year by default. Date is normalized to UTC midnight of the intended calendar day. */\n startDate?: Date | string;\n\n /** Heatmap end date. Current date by default. Date is normalized to UTC midnight of the intended calendar day. */\n endDate?: Date | string;\n\n /** If set, month labels are displayed @default false */\n withMonthLabels?: boolean;\n\n /** Month labels position relative to the heatmap @default 'top' */\n monthLabelsPosition?: 'top' | 'bottom';\n\n /** Month labels, array of 12 elements, can be used for localization */\n monthLabels?: string[];\n\n /** If set, weekday labels are displayed @default false */\n withWeekdayLabels?: boolean;\n\n /** Weekday labels, array of 7 elements, can be used for localization */\n weekdayLabels?: string[];\n\n /** If set, trailing dates that do not fall into the given `startDate` – `endDate` range are displayed to fill empty space. @default true */\n withOutsideDates?: boolean;\n\n /** First day of week, 0 – Sunday, 1 – Monday. @default 1 – Monday */\n firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n\n /** Size of day rect in px @default 10 */\n rectSize?: number;\n\n /** Gap between rects in px @default 1 */\n gap?: number;\n\n /** Rect radius in px @default 2 */\n rectRadius?: number;\n\n /** Colors array, used to calculate color for each value, by default 4 shades of green colors are used */\n colors?: string[];\n\n /** Width of weekday labels column @default 30 */\n weekdaysLabelsWidth?: number;\n\n /** Height of month labels row @default 30 */\n monthsLabelsHeight?: number;\n\n /** Font size of month and weekday labels @default 12 */\n fontSize?: number;\n\n /** A function to generate tooltip label based on the hovered rect date and value, required for the tooltip to be visible */\n getTooltipLabel?: (input: HeatmapRectData) => React.ReactNode;\n\n /** If set, tooltip is displayed on rect hover @default false */\n withTooltip?: boolean;\n\n /** Props passed down to the `Tooltip.Floating` component */\n tooltipProps?: Partial<TooltipFloatingProps>;\n\n /** Props passed down to each rect depending on its date and associated value */\n getRectProps?: (input: HeatmapRectData) => React.ComponentProps<'rect'>;\n\n /** If set, inserts a spacer column between months @default false */\n splitMonths?: boolean;\n\n /** If set, legend with color levels is displayed below the heatmap @default false */\n withLegend?: boolean;\n\n /** Legend labels, array of 2 elements: [min label, max label] @default ['Less', 'More'] */\n legendLabels?: [string, string];\n}\n\nexport type HeatmapFactory = Factory<{\n props: HeatmapProps;\n ref: SVGSVGElement;\n stylesNames: HeatmapStylesNames;\n}>;\n\nconst defaultProps = {\n monthLabels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\n weekdayLabels: ['Sun', 'Mon', '', 'Wed', '', 'Fri', ''],\n monthLabelsPosition: 'top',\n withOutsideDates: true,\n firstDayOfWeek: 1,\n rectSize: 10,\n weekdaysLabelsWidth: 30,\n monthsLabelsHeight: 14,\n gap: 1,\n rectRadius: 2,\n fontSize: 12,\n colors: [\n 'var(--heatmap-level-1)',\n 'var(--heatmap-level-2)',\n 'var(--heatmap-level-3)',\n 'var(--heatmap-level-4)',\n ],\n legendLabels: ['Less', 'More'] as [string, string],\n} satisfies Partial<HeatmapProps>;\n\nexport const Heatmap = factory<HeatmapFactory>((_props) => {\n const props = useProps('Heatmap', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n data,\n startDate,\n endDate,\n withMonthLabels,\n monthLabelsPosition,\n withWeekdayLabels,\n weekdayLabels,\n withOutsideDates,\n monthLabels,\n firstDayOfWeek,\n rectSize = 10,\n gap = 1,\n rectRadius,\n domain,\n colors,\n weekdaysLabelsWidth,\n monthsLabelsHeight,\n fontSize,\n getTooltipLabel,\n withTooltip,\n tooltipProps,\n getRectProps,\n splitMonths,\n withLegend,\n legendLabels,\n attributes,\n ...others\n } = props;\n\n const getStyles = useStyles<HeatmapFactory>({\n name: 'Heatmap',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n });\n\n const [hoveredRect, setHoveredRect] = useState<HeatmapRectData | null>(null);\n const rectSizeWithGap = rectSize + gap;\n const weekdaysOffset = withWeekdayLabels ? weekdaysLabelsWidth : 0;\n const monthsLabelAtTop = withMonthLabels && monthLabelsPosition === 'top';\n const monthsLabelAtBottom = withMonthLabels && monthLabelsPosition === 'bottom';\n const monthsOffset = monthsLabelAtTop ? monthsLabelsHeight : 0;\n const monthsBottomHeight = monthsLabelAtBottom ? monthsLabelsHeight : 0;\n const [min, max] = getBoundaries({ data, domain });\n const rotatedWeekdayLabels = useMemo(\n () => rotateWeekdaysNames(weekdayLabels, firstDayOfWeek),\n [weekdayLabels, firstDayOfWeek]\n );\n\n const datesRange = getDatesRange({\n startDate,\n endDate,\n withOutsideDates,\n firstDayOfWeek,\n });\n\n // Calculate months range for labels and optional split between months\n const monthsRange = withMonthLabels || splitMonths ? getMonthsRange(datesRange) : [];\n\n // Shared props for weeks rendering components\n const weeksProps = {\n data,\n datesRange,\n rectSize,\n gap,\n rectRadius,\n min,\n max,\n colors,\n withTooltip,\n setHoveredRect,\n getRectProps,\n getStyles,\n };\n\n // Use different rendering logic based on splitMonths\n const weeks = splitMonths ? (\n <HeatmapSplitWeeks {...weeksProps} />\n ) : (\n <HeatmapWeeks {...weeksProps} />\n );\n\n // Calculate total columns based on whether splitMonths is enabled\n const totalColumns = splitMonths ? getColumns(datesRange, splitMonths).length : datesRange.length;\n\n const computeMonthLabelX = (monthPosition: number, monthIndex: number) => {\n if (!splitMonths) {\n return monthPosition * rectSizeWithGap + gap + weekdaysOffset;\n }\n\n // For split months, find the first column index that has this month and shift label by 1 column\n const firstMonth = monthsRange[monthIndex];\n const columns: HeatmapColumn[] = getColumns(datesRange, splitMonths);\n const i = getFirstMonthColumnIndex(columns, firstMonth.month);\n const base = i >= 0 ? i : monthPosition;\n // shift right by one column\n return (base + 1) * rectSizeWithGap + gap + weekdaysOffset;\n };\n\n const monthsLabelsNodes =\n withMonthLabels && monthLabels\n ? monthsRange.map((month, monthIndex) => {\n // For non-split months, use original logic with minimum size of 3\n // For split months, use minimum size of 2\n const minSize = splitMonths ? 2 : 3;\n if (month.size < minSize) {\n return null;\n }\n\n const monthLabel = monthLabels[month.month];\n\n const monthLabelY = monthsLabelAtBottom\n ? rectSizeWithGap * 7 + gap + monthsLabelsHeight - 4\n : monthsLabelsHeight - 4;\n\n return (\n <text\n key={monthIndex}\n x={computeMonthLabelX(month.position, monthIndex)}\n y={monthLabelY}\n width={month.size * rectSizeWithGap}\n fontSize={fontSize}\n {...getStyles('monthLabel')}\n >\n {monthLabel}\n </text>\n );\n })\n : null;\n\n const weekdayLabelsNodes =\n withWeekdayLabels && weekdayLabels\n ? rotatedWeekdayLabels.map((weekdayLabel, dayIndex) => (\n <text\n key={dayIndex}\n x={0}\n y={(dayIndex + 1) * rectSizeWithGap - gap + monthsOffset}\n width={weekdaysLabelsWidth}\n fontSize={fontSize}\n {...getStyles('weekdayLabel')}\n >\n {weekdayLabel}\n </text>\n ))\n : null;\n\n const label = getTooltipLabel && hoveredRect && withTooltip ? getTooltipLabel(hoveredRect) : null;\n\n const legendPadding = 10;\n const legendHeight = withLegend ? legendPadding + rectSize : 0;\n const svgWidth = rectSizeWithGap * totalColumns + gap + weekdaysOffset;\n const svgHeight = rectSizeWithGap * 7 + gap + monthsOffset + monthsBottomHeight + legendHeight;\n\n const legendNode = withLegend\n ? (() => {\n const lessLabel = legendLabels![0];\n const moreLabel = legendLabels![1];\n const textGap = 6;\n const charWidth = fontSize! * 0.6;\n const lessWidth = lessLabel.length * charWidth;\n const allColors = [undefined, ...(colors || [])];\n const rectsWidth = allColors.length * rectSize + (allColors.length - 1) * gap;\n const moreWidth = moreLabel.length * charWidth;\n const totalLegendWidth = lessWidth + textGap + rectsWidth + textGap + moreWidth;\n\n const legendX = svgWidth - totalLegendWidth;\n const legendY =\n rectSizeWithGap * 7 + gap + monthsOffset + monthsBottomHeight + legendPadding;\n\n return (\n <g\n transform={`translate(${legendX}, ${legendY})`}\n data-id=\"legend\"\n {...getStyles('legend')}\n >\n <text\n x={0}\n y={rectSize / 2}\n fontSize={fontSize}\n dominantBaseline=\"central\"\n {...getStyles('legendLabel')}\n >\n {lessLabel}\n </text>\n {allColors.map((color, i) => (\n <rect\n key={i}\n x={lessWidth + textGap + i * (rectSize + gap)}\n y={0}\n width={rectSize}\n height={rectSize}\n rx={rectRadius}\n fill={color}\n data-empty={color === undefined || undefined}\n {...getStyles('legendRect')}\n />\n ))}\n <text\n x={lessWidth + textGap + rectsWidth + textGap}\n y={rectSize / 2}\n fontSize={fontSize}\n dominantBaseline=\"central\"\n {...getStyles('legendLabel')}\n >\n {moreLabel}\n </text>\n </g>\n );\n })()\n : null;\n\n return (\n <Box component=\"svg\" width={svgWidth} height={svgHeight} {...getStyles('root')} {...others}>\n <Tooltip.Floating\n label={label}\n disabled={!withTooltip || !label}\n position=\"top\"\n {...tooltipProps}\n >\n <g transform={`translate(${weekdaysOffset}, ${monthsOffset})`} data-id=\"all-weeks\">\n {/* Required for tooltip to remain visible while gaps between rects are hovered */}\n {withTooltip && (\n <rect\n fill=\"transparent\"\n width={rectSizeWithGap * totalColumns + gap}\n height={rectSizeWithGap * 7 + gap}\n />\n )}\n {weeks}\n </g>\n </Tooltip.Floating>\n {weekdayLabelsNodes}\n {monthsLabelsNodes}\n {legendNode}\n </Box>\n );\n});\n\nHeatmap.displayName = '@mantine/charts/Heatmap';\nHeatmap.classes = classes;\n\nexport namespace Heatmap {\n export type Props = HeatmapProps;\n export type StylesNames = HeatmapStylesNames;\n export type Factory = HeatmapFactory;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"Heatmap.mjs","names":["classes"],"sources":["../../src/Heatmap/Heatmap.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Box,\n BoxProps,\n ElementProps,\n factory,\n Factory,\n StylesApiProps,\n Tooltip,\n TooltipFloatingProps,\n useProps,\n useStyles,\n} from '@mantine/core';\nimport { getBoundaries } from './get-boundaries/get-boundaries';\nimport { getColumns, getFirstMonthColumnIndex, HeatmapColumn } from './get-columns/get-columns';\nimport { getDatesRange } from './get-dates-range/get-dates-range';\nimport { getMonthsRange } from './get-months-range/get-months-range';\nimport { HeatmapSplitWeeks } from './HeatmapSplitWeeks';\nimport { HeatmapWeeks } from './HeatmapWeeks';\nimport { rotateWeekdaysNames } from './rotate-weekdays-names/rotate-weekdays-names';\nimport classes from './Heatmap.module.css';\n\nexport type HeatmapStylesNames =\n | 'root'\n | 'rect'\n | 'weekdayLabel'\n | 'monthLabel'\n | 'legend'\n | 'legendLabel'\n | 'legendRect';\n\ninterface HeatmapRectData {\n date: string;\n value: number | null;\n}\n\nexport interface HeatmapProps\n extends\n BoxProps,\n StylesApiProps<HeatmapFactory>,\n ElementProps<'svg', 'display' | 'opacity' | 'viewBox' | 'width' | 'height'> {\n /** Heatmap data, key is date in `YYYY-MM-DD` format (interpreted as a UTC calendar day) */\n data: Record<string, number>;\n\n /** Heatmap domain, array of 2 numbers, min and max values, calculated from data by default */\n domain?: [number, number];\n\n /** Heatmap start date. Current date - 1 year by default. Date is normalized to UTC midnight of the intended calendar day. */\n startDate?: Date | string;\n\n /** Heatmap end date. Current date by default. Date is normalized to UTC midnight of the intended calendar day. */\n endDate?: Date | string;\n\n /** If set, month labels are displayed @default false */\n withMonthLabels?: boolean;\n\n /** Month labels position relative to the heatmap @default 'top' */\n monthLabelsPosition?: 'top' | 'bottom';\n\n /** Month labels, array of 12 elements, can be used for localization */\n monthLabels?: string[];\n\n /** If set, weekday labels are displayed @default false */\n withWeekdayLabels?: boolean;\n\n /** Weekday labels, array of 7 elements, can be used for localization */\n weekdayLabels?: string[];\n\n /** If set, trailing dates that do not fall into the given `startDate` – `endDate` range are displayed to fill empty space. @default true */\n withOutsideDates?: boolean;\n\n /** First day of week, 0 – Sunday, 1 – Monday. @default 1 – Monday */\n firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n\n /** Size of day rect in px @default 10 */\n rectSize?: number;\n\n /** Gap between rects in px @default 1 */\n gap?: number;\n\n /** Rect radius in px @default 2 */\n rectRadius?: number;\n\n /** Colors array, used to calculate color for each value, by default 4 shades of green colors are used */\n colors?: string[];\n\n /** Width of weekday labels column @default 30 */\n weekdaysLabelsWidth?: number;\n\n /** Height of month labels row @default 14 */\n monthsLabelsHeight?: number;\n\n /** Font size of month and weekday labels @default 12 */\n fontSize?: number;\n\n /** A function to generate tooltip label based on the hovered rect date and value, required for the tooltip to be visible */\n getTooltipLabel?: (input: HeatmapRectData) => React.ReactNode;\n\n /** If set, tooltip is displayed on rect hover @default false */\n withTooltip?: boolean;\n\n /** Props passed down to the `Tooltip.Floating` component */\n tooltipProps?: Partial<TooltipFloatingProps>;\n\n /** Props passed down to each rect depending on its date and associated value */\n getRectProps?: (input: HeatmapRectData) => React.ComponentProps<'rect'>;\n\n /** If set, inserts a spacer column between months @default false */\n splitMonths?: boolean;\n\n /** If set, legend with color levels is displayed below the heatmap @default false */\n withLegend?: boolean;\n\n /** Legend labels, array of 2 elements: [min label, max label] @default ['Less', 'More'] */\n legendLabels?: [string, string];\n}\n\nexport type HeatmapFactory = Factory<{\n props: HeatmapProps;\n ref: SVGSVGElement;\n stylesNames: HeatmapStylesNames;\n}>;\n\nconst defaultProps = {\n monthLabels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\n weekdayLabels: ['Sun', 'Mon', '', 'Wed', '', 'Fri', ''],\n monthLabelsPosition: 'top',\n withOutsideDates: true,\n firstDayOfWeek: 1,\n rectSize: 10,\n weekdaysLabelsWidth: 30,\n monthsLabelsHeight: 14,\n gap: 1,\n rectRadius: 2,\n fontSize: 12,\n colors: [\n 'var(--heatmap-level-1)',\n 'var(--heatmap-level-2)',\n 'var(--heatmap-level-3)',\n 'var(--heatmap-level-4)',\n ],\n legendLabels: ['Less', 'More'] as [string, string],\n} satisfies Partial<HeatmapProps>;\n\nexport const Heatmap = factory<HeatmapFactory>((_props) => {\n const props = useProps('Heatmap', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n data,\n startDate,\n endDate,\n withMonthLabels,\n monthLabelsPosition,\n withWeekdayLabels,\n weekdayLabels,\n withOutsideDates,\n monthLabels,\n firstDayOfWeek,\n rectSize = 10,\n gap = 1,\n rectRadius,\n domain,\n colors,\n weekdaysLabelsWidth,\n monthsLabelsHeight,\n fontSize,\n getTooltipLabel,\n withTooltip,\n tooltipProps,\n getRectProps,\n splitMonths,\n withLegend,\n legendLabels,\n attributes,\n ...others\n } = props;\n\n const getStyles = useStyles<HeatmapFactory>({\n name: 'Heatmap',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n });\n\n const [hoveredRect, setHoveredRect] = useState<HeatmapRectData | null>(null);\n const rectSizeWithGap = rectSize + gap;\n const weekdaysOffset = withWeekdayLabels ? weekdaysLabelsWidth : 0;\n const monthsLabelAtTop = withMonthLabels && monthLabelsPosition === 'top';\n const monthsLabelAtBottom = withMonthLabels && monthLabelsPosition === 'bottom';\n const monthsOffset = monthsLabelAtTop ? monthsLabelsHeight : 0;\n const monthsBottomHeight = monthsLabelAtBottom ? monthsLabelsHeight : 0;\n const [min, max] = getBoundaries({ data, domain });\n const rotatedWeekdayLabels = useMemo(\n () => rotateWeekdaysNames(weekdayLabels, firstDayOfWeek),\n [weekdayLabels, firstDayOfWeek]\n );\n\n const datesRange = getDatesRange({\n startDate,\n endDate,\n withOutsideDates,\n firstDayOfWeek,\n });\n\n // Calculate months range for labels and optional split between months\n const monthsRange = withMonthLabels || splitMonths ? getMonthsRange(datesRange) : [];\n\n // Shared props for weeks rendering components\n const weeksProps = {\n data,\n datesRange,\n rectSize,\n gap,\n rectRadius,\n min,\n max,\n colors,\n withTooltip,\n setHoveredRect,\n getRectProps,\n getStyles,\n };\n\n // Use different rendering logic based on splitMonths\n const weeks = splitMonths ? (\n <HeatmapSplitWeeks {...weeksProps} />\n ) : (\n <HeatmapWeeks {...weeksProps} />\n );\n\n // Calculate total columns based on whether splitMonths is enabled\n const totalColumns = splitMonths ? getColumns(datesRange, splitMonths).length : datesRange.length;\n\n const computeMonthLabelX = (monthPosition: number, monthIndex: number) => {\n if (!splitMonths) {\n return monthPosition * rectSizeWithGap + gap + weekdaysOffset;\n }\n\n // For split months, find the first column index that has this month and shift label by 1 column\n const firstMonth = monthsRange[monthIndex];\n const columns: HeatmapColumn[] = getColumns(datesRange, splitMonths);\n const i = getFirstMonthColumnIndex(columns, firstMonth.month);\n const base = i >= 0 ? i : monthPosition;\n // shift right by one column\n return (base + 1) * rectSizeWithGap + gap + weekdaysOffset;\n };\n\n const monthsLabelsNodes =\n withMonthLabels && monthLabels\n ? monthsRange.map((month, monthIndex) => {\n // For non-split months, use original logic with minimum size of 3\n // For split months, use minimum size of 2\n const minSize = splitMonths ? 2 : 3;\n if (month.size < minSize) {\n return null;\n }\n\n const monthLabel = monthLabels[month.month];\n\n const monthLabelY = monthsLabelAtBottom\n ? rectSizeWithGap * 7 + gap + monthsLabelsHeight - 4\n : monthsLabelsHeight - 4;\n\n return (\n <text\n key={monthIndex}\n x={computeMonthLabelX(month.position, monthIndex)}\n y={monthLabelY}\n width={month.size * rectSizeWithGap}\n fontSize={fontSize}\n {...getStyles('monthLabel')}\n >\n {monthLabel}\n </text>\n );\n })\n : null;\n\n const weekdayLabelsNodes =\n withWeekdayLabels && weekdayLabels\n ? rotatedWeekdayLabels.map((weekdayLabel, dayIndex) => (\n <text\n key={dayIndex}\n x={0}\n y={(dayIndex + 1) * rectSizeWithGap - gap + monthsOffset}\n width={weekdaysLabelsWidth}\n fontSize={fontSize}\n {...getStyles('weekdayLabel')}\n >\n {weekdayLabel}\n </text>\n ))\n : null;\n\n const label = getTooltipLabel && hoveredRect && withTooltip ? getTooltipLabel(hoveredRect) : null;\n\n const legendPadding = 10;\n const legendHeight = withLegend ? legendPadding + rectSize : 0;\n const svgWidth = rectSizeWithGap * totalColumns + gap + weekdaysOffset;\n const svgHeight = rectSizeWithGap * 7 + gap + monthsOffset + monthsBottomHeight + legendHeight;\n\n const legendNode = withLegend\n ? (() => {\n const lessLabel = legendLabels![0];\n const moreLabel = legendLabels![1];\n const textGap = 6;\n const charWidth = fontSize! * 0.6;\n const lessWidth = lessLabel.length * charWidth;\n const allColors = [undefined, ...(colors || [])];\n const rectsWidth = allColors.length * rectSize + (allColors.length - 1) * gap;\n const moreWidth = moreLabel.length * charWidth;\n const totalLegendWidth = lessWidth + textGap + rectsWidth + textGap + moreWidth;\n\n const legendX = svgWidth - totalLegendWidth;\n const legendY =\n rectSizeWithGap * 7 + gap + monthsOffset + monthsBottomHeight + legendPadding;\n\n return (\n <g\n transform={`translate(${legendX}, ${legendY})`}\n data-id=\"legend\"\n {...getStyles('legend')}\n >\n <text\n x={0}\n y={rectSize / 2}\n fontSize={fontSize}\n dominantBaseline=\"central\"\n {...getStyles('legendLabel')}\n >\n {lessLabel}\n </text>\n {allColors.map((color, i) => (\n <rect\n key={i}\n x={lessWidth + textGap + i * (rectSize + gap)}\n y={0}\n width={rectSize}\n height={rectSize}\n rx={rectRadius}\n fill={color}\n data-empty={color === undefined || undefined}\n {...getStyles('legendRect')}\n />\n ))}\n <text\n x={lessWidth + textGap + rectsWidth + textGap}\n y={rectSize / 2}\n fontSize={fontSize}\n dominantBaseline=\"central\"\n {...getStyles('legendLabel')}\n >\n {moreLabel}\n </text>\n </g>\n );\n })()\n : null;\n\n return (\n <Box component=\"svg\" width={svgWidth} height={svgHeight} {...getStyles('root')} {...others}>\n <Tooltip.Floating\n label={label}\n disabled={!withTooltip || !label}\n position=\"top\"\n {...tooltipProps}\n >\n <g transform={`translate(${weekdaysOffset}, ${monthsOffset})`} data-id=\"all-weeks\">\n {/* Required for tooltip to remain visible while gaps between rects are hovered */}\n {withTooltip && (\n <rect\n fill=\"transparent\"\n width={rectSizeWithGap * totalColumns + gap}\n height={rectSizeWithGap * 7 + gap}\n />\n )}\n {weeks}\n </g>\n </Tooltip.Floating>\n {weekdayLabelsNodes}\n {monthsLabelsNodes}\n {legendNode}\n </Box>\n );\n});\n\nHeatmap.displayName = '@mantine/charts/Heatmap';\nHeatmap.classes = classes;\n\nexport namespace Heatmap {\n export type Props = HeatmapProps;\n export type StylesNames = HeatmapStylesNames;\n export type Factory = HeatmapFactory;\n}\n"],"mappings":";;;;;;;;;;;;;AA2HA,MAAM,eAAe;CACnB,aAAa;EAAC;EAAO;EAAO;EAAO;EAAO;EAAO;EAAO;EAAO;EAAO;EAAO;EAAO;EAAO;CAAK;CAChG,eAAe;EAAC;EAAO;EAAO;EAAI;EAAO;EAAI;EAAO;CAAE;CACtD,qBAAqB;CACrB,kBAAkB;CAClB,gBAAgB;CAChB,UAAU;CACV,qBAAqB;CACrB,oBAAoB;CACpB,KAAK;CACL,YAAY;CACZ,UAAU;CACV,QAAQ;EACN;EACA;EACA;EACA;CACF;CACA,cAAc,CAAC,QAAQ,MAAM;AAC/B;AAEA,MAAa,UAAU,SAAyB,WAAW;CACzD,MAAM,QAAQ,SAAS,WAAW,cAAc,MAAM;CACtD,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,MACA,MACA,WACA,SACA,iBACA,qBACA,mBACA,eACA,kBACA,aACA,gBACA,WAAW,IACX,MAAM,GACN,YACA,QACA,QACA,qBACA,oBACA,UACA,iBACA,aACA,cACA,cACA,aACA,YACA,cACA,YACA,GAAG,WACD;CAEJ,MAAM,YAAY,UAA0B;EAC1C,MAAM;EACN,SAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,CAAC,aAAa,kBAAkB,SAAiC,IAAI;CAC3E,MAAM,kBAAkB,WAAW;CACnC,MAAM,iBAAiB,oBAAoB,sBAAsB;CACjE,MAAM,mBAAmB,mBAAmB,wBAAwB;CACpE,MAAM,sBAAsB,mBAAmB,wBAAwB;CACvE,MAAM,eAAe,mBAAmB,qBAAqB;CAC7D,MAAM,qBAAqB,sBAAsB,qBAAqB;CACtE,MAAM,CAAC,KAAK,OAAO,cAAc;EAAE;EAAM;CAAO,CAAC;CACjD,MAAM,uBAAuB,cACrB,oBAAoB,eAAe,cAAc,GACvD,CAAC,eAAe,cAAc,CAChC;CAEA,MAAM,aAAa,cAAc;EAC/B;EACA;EACA;EACA;CACF,CAAC;CAGD,MAAM,cAAc,mBAAmB,cAAc,eAAe,UAAU,IAAI,CAAC;CAGnF,MAAM,aAAa;EACjB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CAGA,MAAM,QAAQ,cACZ,oBAAC,mBAAD,EAAmB,GAAI,WAAa,CAAA,IAEpC,oBAAC,cAAD,EAAc,GAAI,WAAa,CAAA;CAIjC,MAAM,eAAe,cAAc,WAAW,YAAY,WAAW,CAAC,CAAC,SAAS,WAAW;CAE3F,MAAM,sBAAsB,eAAuB,eAAuB;EACxE,IAAI,CAAC,aACH,OAAO,gBAAgB,kBAAkB,MAAM;EAIjD,MAAM,aAAa,YAAY;EAC/B,MAAM,UAA2B,WAAW,YAAY,WAAW;EACnE,MAAM,IAAI,yBAAyB,SAAS,WAAW,KAAK;EAG5D,SAFa,KAAK,IAAI,IAAI,iBAEX,KAAK,kBAAkB,MAAM;CAC9C;CAEA,MAAM,oBACJ,mBAAmB,cACf,YAAY,KAAK,OAAO,eAAe;EAGrC,MAAM,UAAU,cAAc,IAAI;EAClC,IAAI,MAAM,OAAO,SACf,OAAO;EAGT,MAAM,aAAa,YAAY,MAAM;EAErC,MAAM,cAAc,sBAChB,kBAAkB,IAAI,MAAM,qBAAqB,IACjD,qBAAqB;EAEzB,OACE,oBAAC,QAAD;GAEE,GAAG,mBAAmB,MAAM,UAAU,UAAU;GAChD,GAAG;GACH,OAAO,MAAM,OAAO;GACV;GACV,GAAI,UAAU,YAAY;GAEzB,UAAA;EACG,GARC,UAQD;CAEV,CAAC,IACD;CAEN,MAAM,qBACJ,qBAAqB,gBACjB,qBAAqB,KAAK,cAAc,aACtC,oBAAC,QAAD;EAEE,GAAG;EACH,IAAI,WAAW,KAAK,kBAAkB,MAAM;EAC5C,OAAO;EACG;EACV,GAAI,UAAU,cAAc;EAE3B,UAAA;CACG,GARC,QAQD,CACP,IACD;CAEN,MAAM,QAAQ,mBAAmB,eAAe,cAAc,gBAAgB,WAAW,IAAI;CAE7F,MAAM,gBAAgB;CACtB,MAAM,eAAe,aAAa,gBAAgB,WAAW;CAC7D,MAAM,WAAW,kBAAkB,eAAe,MAAM;CACxD,MAAM,YAAY,kBAAkB,IAAI,MAAM,eAAe,qBAAqB;CAElF,MAAM,aAAa,oBACR;EACL,MAAM,YAAY,aAAc;EAChC,MAAM,YAAY,aAAc;EAChC,MAAM,UAAU;EAChB,MAAM,YAAY,WAAY;EAC9B,MAAM,YAAY,UAAU,SAAS;EACrC,MAAM,YAAY,CAAC,KAAA,GAAW,GAAI,UAAU,CAAC,CAAE;EAC/C,MAAM,aAAa,UAAU,SAAS,YAAY,UAAU,SAAS,KAAK;EAC1E,MAAM,YAAY,UAAU,SAAS;EACrC,MAAM,mBAAmB,YAAY,UAAU,aAAa,UAAU;EAEtE,MAAM,UAAU,WAAW;EAC3B,MAAM,UACJ,kBAAkB,IAAI,MAAM,eAAe,qBAAqB;EAElE,OACE,qBAAC,KAAD;GACE,WAAW,aAAa,QAAQ,IAAI,QAAQ;GAC5C,WAAQ;GACR,GAAI,UAAU,QAAQ;GAHxB,UAAA;IAKE,oBAAC,QAAD;KACE,GAAG;KACH,GAAG,WAAW;KACJ;KACV,kBAAiB;KACjB,GAAI,UAAU,aAAa;KAE1B,UAAA;IACG,CAAA;IACL,UAAU,KAAK,OAAO,MACrB,oBAAC,QAAD;KAEE,GAAG,YAAY,UAAU,KAAK,WAAW;KACzC,GAAG;KACH,OAAO;KACP,QAAQ;KACR,IAAI;KACJ,MAAM;KACN,cAAY,UAAU,KAAA,KAAa,KAAA;KACnC,GAAI,UAAU,YAAY;IAC3B,GATM,CASN,CACF;IACD,oBAAC,QAAD;KACE,GAAG,YAAY,UAAU,aAAa;KACtC,GAAG,WAAW;KACJ;KACV,kBAAiB;KACjB,GAAI,UAAU,aAAa;KAE1B,UAAA;IACG,CAAA;GACL;;CAEP,EAAA,CAAG,IACH;CAEJ,OACE,qBAAC,KAAD;EAAK,WAAU;EAAM,OAAO;EAAU,QAAQ;EAAW,GAAI,UAAU,MAAM;EAAG,GAAI;EAApF,UAAA;GACE,oBAAC,QAAQ,UAAT;IACS;IACP,UAAU,CAAC,eAAe,CAAC;IAC3B,UAAS;IACT,GAAI;IAEJ,UAAA,qBAAC,KAAD;KAAG,WAAW,aAAa,eAAe,IAAI,aAAa;KAAI,WAAQ;KAAvE,UAAA,CAEG,eACC,oBAAC,QAAD;MACE,MAAK;MACL,OAAO,kBAAkB,eAAe;MACxC,QAAQ,kBAAkB,IAAI;KAC/B,CAAA,GAEF,KACA;;GACa,CAAA;GACjB;GACA;GACA;EACE;;AAET,CAAC;AAED,QAAQ,cAAc;AACtB,QAAQ,UAAUA"}
@@ -38,7 +38,7 @@ const varsResolver = createVarsResolver((theme, { textColor, gridColor }) => ({
38
38
  } }));
39
39
  const LineChart$1 = factory((_props) => {
40
40
  const props = useProps("LineChart", defaultProps, _props);
41
- const { classNames, className, style, styles, unstyled, vars, data, withLegend, legendProps, series, onMouseLeave, dataKey, withTooltip, withXAxis, withYAxis, gridAxis, tickLine, xAxisProps, yAxisProps, unit, tooltipAnimationDuration, strokeDasharray, gridProps, tooltipProps, referenceLines, referenceAreas, referenceDots, withDots, dotProps, activeDotProps, strokeWidth, lineChartProps, connectNulls, fillOpacity, curveType, orientation, dir, valueFormatter, children, lineProps, xAxisLabel, yAxisLabel, type, gradientStops, withRightYAxis, rightYAxisLabel, rightYAxisProps, withPointLabels, attributes, gridColor, accessibilityLayer, withBrush, brushProps, ...others } = props;
41
+ const { classNames, className, style, styles, unstyled, vars, data, withLegend, legendProps, series, onMouseLeave, dataKey, withTooltip, withXAxis, withYAxis, gridAxis, tickLine, xAxisProps, yAxisProps, unit, tooltipAnimationDuration, strokeDasharray, gridProps, tooltipProps, referenceLines, referenceAreas, referenceDots, withDots, dotProps, activeDotProps, strokeWidth, lineChartProps, connectNulls, fillOpacity, curveType, orientation, dir, valueFormatter, children, lineProps, xAxisLabel, yAxisLabel, type, gradientStops, withRightYAxis, rightYAxisLabel, rightYAxisProps, withPointLabels, attributes, gridColor, textColor, accessibilityLayer, withBrush, brushProps, ...others } = props;
42
42
  const theme = useMantineTheme();
43
43
  const withXTickLine = gridAxis !== "none" && (tickLine === "x" || tickLine === "xy");
44
44
  const withYTickLine = gridAxis !== "none" && (tickLine === "y" || tickLine === "xy");
@@ -1 +1 @@
1
- {"version":3,"file":"LineChart.mjs","names":["LineChart","useId","ReChartsLineChart","Tooltip","classes"],"sources":["../../src/LineChart/LineChart.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n CartesianGrid,\n Label,\n Legend,\n Line,\n LineProps,\n LineChart as ReChartsLineChart,\n ReferenceArea,\n ReferenceDot,\n ReferenceLine,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from 'recharts';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getThemeColor,\n MantineColor,\n StylesApiProps,\n useMantineTheme,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '@mantine/core';\nimport { useId } from '@mantine/hooks';\nimport { ChartBrush } from '../ChartBrush';\nimport { ChartLegend, ChartLegendStylesNames } from '../ChartLegend';\nimport { ChartTooltip, ChartTooltipStylesNames } from '../ChartTooltip';\nimport { PointLabel } from '../PointLabel/PointLabel';\nimport type {\n BaseChartStylesNames,\n ChartSeries,\n GridChartBaseProps,\n MantineChartDotProps,\n} from '../types';\nimport classes from '../grid-chart.module.css';\n\nexport type LineChartType = 'default' | 'gradient';\n\nexport interface LineChartGradientStop {\n offset: number;\n color: MantineColor;\n}\n\nexport type LineChartCurveType =\n | 'bump'\n | 'linear'\n | 'natural'\n | 'monotone'\n | 'step'\n | 'stepBefore'\n | 'stepAfter';\n\nexport interface LineChartSeries extends ChartSeries {\n strokeDasharray?: string | number;\n curveType?: LineChartCurveType;\n}\n\nexport type LineChartStylesNames =\n | 'line'\n | BaseChartStylesNames\n | ChartLegendStylesNames\n | ChartTooltipStylesNames;\n\nexport type LineChartCssVariables = {\n root: '--chart-text-color' | '--chart-grid-color';\n};\n\nexport interface LineChartProps\n extends BoxProps, GridChartBaseProps, StylesApiProps<LineChartFactory>, ElementProps<'div'> {\n /** Data used to display chart */\n data: Record<string, any>[];\n\n /** An array of objects with `name` and `color` keys. Determines which data should be consumed from the `data` array. */\n series: LineChartSeries[];\n\n /** Controls styles of the line @default 'default' */\n type?: LineChartType;\n\n /** Data used to generate gradient stops @default [{ offset: 0, color: 'red' }, { offset: 100, color: 'blue' }] */\n gradientStops?: LineChartGradientStop[];\n\n /** Type of the curve @default 'monotone' */\n curveType?: LineChartCurveType;\n\n /** Controls fill opacity of all lines @default 1 */\n fillOpacity?: number;\n\n /** Determines whether dots should be displayed @default true */\n withDots?: boolean;\n\n /** Props passed down to all dots. Ignored if `withDots={false}` is set. */\n dotProps?: MantineChartDotProps;\n\n /** Props passed down to all active dots. Ignored if `withDots={false}` is set. */\n activeDotProps?: MantineChartDotProps;\n\n /** Stroke width for the chart lines @default 2 */\n strokeWidth?: number;\n\n /** Props passed down to recharts `LineChart` component */\n lineChartProps?: React.ComponentProps<typeof ReChartsLineChart>;\n\n /** Determines whether points with `null` values should be connected @default true */\n connectNulls?: boolean;\n\n /** Additional components that are rendered inside recharts `LineChart` component */\n children?: React.ReactNode;\n\n /** Props passed down to recharts `Line` component */\n lineProps?:\n | ((series: LineChartSeries) => Partial<Omit<LineProps, 'ref'>>)\n | Partial<Omit<LineProps, 'ref'>>;\n\n /** Determines whether each point should have associated label @default false */\n withPointLabels?: boolean;\n}\n\nexport type LineChartFactory = Factory<{\n props: LineChartProps;\n ref: HTMLDivElement;\n stylesNames: LineChartStylesNames;\n vars: LineChartCssVariables;\n}>;\n\nconst defaultProps = {\n withXAxis: true,\n withYAxis: true,\n withTooltip: true,\n tooltipAnimationDuration: 0,\n fillOpacity: 1,\n tickLine: 'y',\n strokeDasharray: '5 5',\n gridAxis: 'x',\n withDots: true,\n connectNulls: true,\n strokeWidth: 2,\n curveType: 'monotone',\n gradientStops: [\n { offset: 0, color: 'red' },\n { offset: 100, color: 'blue' },\n ],\n accessibilityLayer: true,\n} satisfies Partial<LineChartProps>;\n\nconst varsResolver = createVarsResolver<LineChartFactory>((theme, { textColor, gridColor }) => ({\n root: {\n '--chart-text-color': textColor ? getThemeColor(textColor, theme) : undefined,\n '--chart-grid-color': gridColor ? getThemeColor(gridColor, theme) : undefined,\n },\n}));\n\nexport const LineChart = factory<LineChartFactory>((_props) => {\n const props = useProps('LineChart', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n data,\n withLegend,\n legendProps,\n series,\n onMouseLeave,\n dataKey,\n withTooltip,\n withXAxis,\n withYAxis,\n gridAxis,\n tickLine,\n xAxisProps,\n yAxisProps,\n unit,\n tooltipAnimationDuration,\n strokeDasharray,\n gridProps,\n tooltipProps,\n referenceLines,\n referenceAreas,\n referenceDots,\n withDots,\n dotProps,\n activeDotProps,\n strokeWidth,\n lineChartProps,\n connectNulls,\n fillOpacity,\n curveType,\n orientation,\n dir,\n valueFormatter,\n children,\n lineProps,\n xAxisLabel,\n yAxisLabel,\n type,\n gradientStops,\n withRightYAxis,\n rightYAxisLabel,\n rightYAxisProps,\n withPointLabels,\n attributes,\n gridColor,\n accessibilityLayer,\n withBrush,\n brushProps,\n ...others\n } = props;\n\n const theme = useMantineTheme();\n const withXTickLine = gridAxis !== 'none' && (tickLine === 'x' || tickLine === 'xy');\n const withYTickLine = gridAxis !== 'none' && (tickLine === 'y' || tickLine === 'xy');\n const [highlightedArea, setHighlightedArea] = useState<string | number | null>(null);\n const shouldHighlight = highlightedArea !== null;\n const handleMouseLeave = (event: React.MouseEvent<HTMLDivElement>) => {\n setHighlightedArea(null);\n onMouseLeave?.(event);\n };\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<LineChartFactory>({\n classNames,\n styles,\n props,\n });\n\n const getStyles = useStyles<LineChartFactory>({\n name: 'LineChart',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const id = useId();\n const gradientId = `line-chart-gradient-${id}`;\n const stops = gradientStops?.map((stop) => (\n <stop\n key={stop.color}\n offset={`${stop.offset}%`}\n stopColor={getThemeColor(stop.color, theme)}\n />\n ));\n\n const lines = series.map((item) => {\n const color = getThemeColor(item.color, theme);\n const dimmed = shouldHighlight && highlightedArea !== item.name;\n\n return (\n <Line\n {...getStyles('line')}\n key={item.name}\n name={item.name}\n dataKey={item.name}\n dot={\n withDots\n ? {\n fillOpacity: dimmed ? 0 : 1,\n strokeOpacity: dimmed ? 0 : 1,\n strokeWidth: 1,\n fill: type === 'gradient' ? 'var(--mantine-color-gray-7)' : color,\n stroke: type === 'gradient' ? 'white' : color,\n ...dotProps,\n }\n : false\n }\n activeDot={\n withDots\n ? {\n fill: type === 'gradient' ? 'var(--mantine-color-gray-7)' : color,\n stroke: type === 'gradient' ? 'white' : color,\n ...activeDotProps,\n }\n : false\n }\n fill={color}\n stroke={type === 'gradient' ? `url(#${gradientId})` : color}\n strokeWidth={strokeWidth}\n isAnimationActive={false}\n fillOpacity={dimmed ? 0 : fillOpacity}\n strokeOpacity={dimmed ? 0.5 : fillOpacity}\n connectNulls={connectNulls}\n type={item.curveType ?? curveType}\n strokeDasharray={item.strokeDasharray}\n yAxisId={item.yAxisId || undefined}\n label={withPointLabels ? <PointLabel valueFormatter={valueFormatter} /> : undefined}\n {...(typeof lineProps === 'function' ? lineProps(item) : lineProps)}\n />\n );\n });\n\n const referenceLinesItems = referenceLines?.map(\n ({ color: lineColor, labelPosition, ...line }, index) => {\n const color = getThemeColor(lineColor, theme);\n return (\n <ReferenceLine\n key={index}\n stroke={lineColor ? color : 'var(--chart-grid-color)'}\n strokeWidth={1}\n yAxisId={line.yAxisId || undefined}\n {...line}\n label={{\n fill: lineColor ? color : 'currentColor',\n fontSize: 12,\n position: labelPosition ?? 'insideBottomLeft',\n ...(typeof line.label === 'object' ? line.label : { value: line.label }),\n }}\n {...getStyles('referenceLine')}\n />\n );\n }\n );\n\n const referenceAreasItems = referenceAreas?.map(\n ({ color: areaColor, labelPosition, ...area }, index) => {\n const color = getThemeColor(areaColor, theme);\n return (\n <ReferenceArea\n key={index}\n fill={areaColor ? color : 'var(--chart-grid-color)'}\n fillOpacity={0.2}\n stroke={areaColor ? color : 'var(--chart-grid-color)'}\n strokeOpacity={0.6}\n yAxisId={area.yAxisId || undefined}\n {...area}\n label={{\n fill: areaColor ? color : 'currentColor',\n fontSize: 12,\n position: labelPosition ?? 'insideTop',\n ...(typeof area.label === 'object' ? area.label : { value: area.label }),\n }}\n {...getStyles('referenceArea')}\n />\n );\n }\n );\n\n const referenceDotsItems = referenceDots?.map(\n ({ color: dotColor, labelPosition, ...dot }, index) => {\n const color = getThemeColor(dotColor, theme);\n return (\n <ReferenceDot\n key={index}\n r={5}\n fill={dotColor ? color : 'var(--chart-grid-color)'}\n stroke=\"var(--mantine-color-body)\"\n strokeWidth={2}\n yAxisId={dot.yAxisId || undefined}\n {...dot}\n label={{\n fill: dotColor ? color : 'currentColor',\n fontSize: 12,\n position: labelPosition ?? 'top',\n ...(typeof dot.label === 'object' ? dot.label : { value: dot.label }),\n }}\n {...getStyles('referenceDot')}\n />\n );\n }\n );\n\n const sharedYAxisProps = {\n axisLine: false,\n ...(orientation === 'vertical'\n ? { dataKey, type: 'category' as const }\n : { type: 'number' as const }),\n tickLine: withYTickLine ? { stroke: 'currentColor' } : false,\n allowDecimals: true,\n unit,\n tickFormatter: orientation === 'vertical' ? undefined : valueFormatter,\n ...getStyles('axis'),\n };\n\n return (\n <Box {...getStyles('root')} onMouseLeave={handleMouseLeave} dir={dir || 'ltr'} {...others}>\n <ResponsiveContainer {...getStyles('container')}>\n <ReChartsLineChart\n data={data}\n layout={orientation}\n margin={{\n bottom: xAxisLabel ? 30 : undefined,\n left: yAxisLabel ? 10 : undefined,\n right: yAxisLabel ? 5 : undefined,\n }}\n accessibilityLayer={accessibilityLayer}\n {...lineChartProps}\n >\n {referenceAreasItems}\n {type === 'gradient' && (\n <defs>\n <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n {stops}\n </linearGradient>\n </defs>\n )}\n\n {withLegend && (\n <Legend\n verticalAlign=\"top\"\n content={(payload) => (\n <ChartLegend\n payload={payload.payload}\n onHighlight={setHighlightedArea}\n legendPosition={legendProps?.verticalAlign || 'top'}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n series={series}\n showColor={type !== 'gradient'}\n attributes={attributes}\n />\n )}\n {...legendProps}\n />\n )}\n\n <XAxis\n hide={!withXAxis}\n {...(orientation === 'vertical' ? { type: 'number' } : { dataKey })}\n tick={{ transform: 'translate(0, 10)', fontSize: 12, fill: 'currentColor' }}\n stroke=\"\"\n interval=\"preserveStartEnd\"\n tickLine={withXTickLine ? { stroke: 'currentColor' } : false}\n minTickGap={5}\n tickFormatter={orientation === 'vertical' ? valueFormatter : undefined}\n {...getStyles('axis')}\n {...xAxisProps}\n >\n {xAxisLabel && (\n <Label position=\"insideBottom\" offset={-20} fontSize={12} {...getStyles('axisLabel')}>\n {xAxisLabel}\n </Label>\n )}\n {xAxisProps?.children}\n </XAxis>\n\n <YAxis\n // yAxisId=\"left\"\n // orientation=\"left\"\n tick={{ transform: 'translate(-10, 0)', fontSize: 12, fill: 'currentColor' }}\n hide={!withYAxis}\n {...sharedYAxisProps}\n {...yAxisProps}\n >\n {yAxisLabel && (\n <Label\n position=\"insideLeft\"\n angle={-90}\n textAnchor=\"middle\"\n fontSize={12}\n offset={-5}\n {...getStyles('axisLabel')}\n >\n {yAxisLabel}\n </Label>\n )}\n {yAxisProps?.children}\n </YAxis>\n\n <YAxis\n yAxisId=\"right\"\n orientation=\"right\"\n tick={{ transform: 'translate(10, 0)', fontSize: 12, fill: 'currentColor' }}\n hide={!withRightYAxis}\n {...sharedYAxisProps}\n {...rightYAxisProps}\n >\n {rightYAxisLabel && (\n <Label\n position=\"insideRight\"\n angle={90}\n textAnchor=\"middle\"\n fontSize={12}\n offset={-5}\n {...getStyles('axisLabel')}\n >\n {rightYAxisLabel}\n </Label>\n )}\n {yAxisProps?.children}\n </YAxis>\n\n <CartesianGrid\n strokeDasharray={strokeDasharray as string}\n vertical={gridAxis === 'y' || gridAxis === 'xy'}\n horizontal={gridAxis === 'x' || gridAxis === 'xy'}\n {...getStyles('grid')}\n {...gridProps}\n />\n\n {withTooltip && (\n <Tooltip\n animationDuration={tooltipAnimationDuration}\n isAnimationActive={tooltipAnimationDuration !== 0}\n position={orientation === 'vertical' ? {} : { y: 0 }}\n cursor={{\n stroke: 'var(--chart-grid-color)',\n strokeWidth: 1,\n strokeDasharray,\n }}\n content={({ label, payload, labelFormatter }) => (\n <ChartTooltip\n label={labelFormatter && payload ? labelFormatter(label, payload) : label}\n payload={payload}\n unit={unit}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n series={series}\n valueFormatter={valueFormatter}\n showColor={type !== 'gradient'}\n attributes={attributes}\n />\n )}\n {...tooltipProps}\n />\n )}\n\n {lines}\n {referenceLinesItems}\n {referenceDotsItems}\n {withBrush && (\n <ChartBrush\n dataKey={dataKey}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n {...brushProps}\n />\n )}\n {children}\n </ReChartsLineChart>\n </ResponsiveContainer>\n </Box>\n );\n});\n\nLineChart.displayName = '@mantine/charts/LineChart';\nLineChart.classes = classes;\nLineChart.varsResolver = varsResolver;\n\nexport namespace LineChart {\n export type Props = LineChartProps;\n export type CssVariables = LineChartCssVariables;\n export type Factory = LineChartFactory;\n export type Series = LineChartSeries;\n export type StylesNames = LineChartStylesNames;\n export type CurveType = LineChartCurveType;\n}\n"],"mappings":";;;;;;;;;;;;AAoIA,MAAM,eAAe;CACnB,WAAW;CACX,WAAW;CACX,aAAa;CACb,0BAA0B;CAC1B,aAAa;CACb,UAAU;CACV,iBAAiB;CACjB,UAAU;CACV,UAAU;CACV,cAAc;CACd,aAAa;CACb,WAAW;CACX,eAAe,CACb;EAAE,QAAQ;EAAG,OAAO;CAAM,GAC1B;EAAE,QAAQ;EAAK,OAAO;CAAO,CAC/B;CACA,oBAAoB;AACtB;AAEA,MAAM,eAAe,oBAAsC,OAAO,EAAE,WAAW,iBAAiB,EAC9F,MAAM;CACJ,sBAAsB,YAAY,cAAc,WAAW,KAAK,IAAI,KAAA;CACpE,sBAAsB,YAAY,cAAc,WAAW,KAAK,IAAI,KAAA;AACtE,EACF,EAAE;AAEF,MAAaA,cAAY,SAA2B,WAAW;CAC7D,MAAM,QAAQ,SAAS,aAAa,cAAc,MAAM;CACxD,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,MACA,MACA,YACA,aACA,QACA,cACA,SACA,aACA,WACA,WACA,UACA,UACA,YACA,YACA,MACA,0BACA,iBACA,WACA,cACA,gBACA,gBACA,eACA,UACA,UACA,gBACA,aACA,gBACA,cACA,aACA,WACA,aACA,KACA,gBACA,UACA,WACA,YACA,YACA,MACA,eACA,gBACA,iBACA,iBACA,iBACA,YACA,WACA,oBACA,WACA,YACA,GAAG,WACD;CAEJ,MAAM,QAAQ,gBAAgB;CAC9B,MAAM,gBAAgB,aAAa,WAAW,aAAa,OAAO,aAAa;CAC/E,MAAM,gBAAgB,aAAa,WAAW,aAAa,OAAO,aAAa;CAC/E,MAAM,CAAC,iBAAiB,sBAAsB,SAAiC,IAAI;CACnF,MAAM,kBAAkB,oBAAoB;CAC5C,MAAM,oBAAoB,UAA4C;EACpE,mBAAmB,IAAI;EACvB,eAAe,KAAK;CACtB;CACA,MAAM,EAAE,oBAAoB,mBAAmB,qBAAuC;EACpF;EACA;EACA;CACF,CAAC;CAED,MAAM,YAAY,UAA4B;EAC5C,MAAM;EACN,SAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAGD,MAAM,aAAa,uBADRC,QACgC;CAC3C,MAAM,QAAQ,eAAe,KAAK,SAChC,oBAAC,QAAD;EAEE,QAAQ,GAAG,KAAK,OAAO;EACvB,WAAW,cAAc,KAAK,OAAO,KAAK;CAC3C,GAHM,KAAK,KAGX,CACF;CAED,MAAM,QAAQ,OAAO,KAAK,SAAS;EACjC,MAAM,QAAQ,cAAc,KAAK,OAAO,KAAK;EAC7C,MAAM,SAAS,mBAAmB,oBAAoB,KAAK;EAE3D,OACE,8BAAC,MAAD;GACE,GAAI,UAAU,MAAM;GACpB,KAAK,KAAK;GACV,MAAM,KAAK;GACX,SAAS,KAAK;GACd,KACE,WACI;IACE,aAAa,SAAS,IAAI;IAC1B,eAAe,SAAS,IAAI;IAC5B,aAAa;IACb,MAAM,SAAS,aAAa,gCAAgC;IAC5D,QAAQ,SAAS,aAAa,UAAU;IACxC,GAAG;GACL,IACA;GAEN,WACE,WACI;IACE,MAAM,SAAS,aAAa,gCAAgC;IAC5D,QAAQ,SAAS,aAAa,UAAU;IACxC,GAAG;GACL,IACA;GAEN,MAAM;GACN,QAAQ,SAAS,aAAa,QAAQ,WAAW,KAAK;GACzC;GACb,mBAAmB;GACnB,aAAa,SAAS,IAAI;GAC1B,eAAe,SAAS,KAAM;GAChB;GACd,MAAM,KAAK,aAAa;GACxB,iBAAiB,KAAK;GACtB,SAAS,KAAK,WAAW,KAAA;GACzB,OAAO,kBAAkB,oBAAC,YAAD,EAA4B,eAAiB,CAAA,IAAI,KAAA;GAC1E,GAAK,OAAO,cAAc,aAAa,UAAU,IAAI,IAAI;EAC1D,CAAA;CAEL,CAAC;CAED,MAAM,sBAAsB,gBAAgB,KACzC,EAAE,OAAO,WAAW,eAAe,GAAG,QAAQ,UAAU;EACvD,MAAM,QAAQ,cAAc,WAAW,KAAK;EAC5C,OACE,oBAAC,eAAD;GAEE,QAAQ,YAAY,QAAQ;GAC5B,aAAa;GACb,SAAS,KAAK,WAAW,KAAA;GACzB,GAAI;GACJ,OAAO;IACL,MAAM,YAAY,QAAQ;IAC1B,UAAU;IACV,UAAU,iBAAiB;IAC3B,GAAI,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM;GACxE;GACA,GAAI,UAAU,eAAe;EAC9B,GAZM,KAYN;CAEL,CACF;CAEA,MAAM,sBAAsB,gBAAgB,KACzC,EAAE,OAAO,WAAW,eAAe,GAAG,QAAQ,UAAU;EACvD,MAAM,QAAQ,cAAc,WAAW,KAAK;EAC5C,OACE,oBAAC,eAAD;GAEE,MAAM,YAAY,QAAQ;GAC1B,aAAa;GACb,QAAQ,YAAY,QAAQ;GAC5B,eAAe;GACf,SAAS,KAAK,WAAW,KAAA;GACzB,GAAI;GACJ,OAAO;IACL,MAAM,YAAY,QAAQ;IAC1B,UAAU;IACV,UAAU,iBAAiB;IAC3B,GAAI,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM;GACxE;GACA,GAAI,UAAU,eAAe;EAC9B,GAdM,KAcN;CAEL,CACF;CAEA,MAAM,qBAAqB,eAAe,KACvC,EAAE,OAAO,UAAU,eAAe,GAAG,OAAO,UAAU;EACrD,MAAM,QAAQ,cAAc,UAAU,KAAK;EAC3C,OACE,oBAAC,cAAD;GAEE,GAAG;GACH,MAAM,WAAW,QAAQ;GACzB,QAAO;GACP,aAAa;GACb,SAAS,IAAI,WAAW,KAAA;GACxB,GAAI;GACJ,OAAO;IACL,MAAM,WAAW,QAAQ;IACzB,UAAU;IACV,UAAU,iBAAiB;IAC3B,GAAI,OAAO,IAAI,UAAU,WAAW,IAAI,QAAQ,EAAE,OAAO,IAAI,MAAM;GACrE;GACA,GAAI,UAAU,cAAc;EAC7B,GAdM,KAcN;CAEL,CACF;CAEA,MAAM,mBAAmB;EACvB,UAAU;EACV,GAAI,gBAAgB,aAChB;GAAE;GAAS,MAAM;EAAoB,IACrC,EAAE,MAAM,SAAkB;EAC9B,UAAU,gBAAgB,EAAE,QAAQ,eAAe,IAAI;EACvD,eAAe;EACf;EACA,eAAe,gBAAgB,aAAa,KAAA,IAAY;EACxD,GAAG,UAAU,MAAM;CACrB;CAEA,OACE,oBAAC,KAAD;EAAK,GAAI,UAAU,MAAM;EAAG,cAAc;EAAkB,KAAK,OAAO;EAAO,GAAI;EACjF,UAAA,oBAAC,qBAAD;GAAqB,GAAI,UAAU,WAAW;GAC5C,UAAA,qBAACC,WAAD;IACQ;IACN,QAAQ;IACR,QAAQ;KACN,QAAQ,aAAa,KAAK,KAAA;KAC1B,MAAM,aAAa,KAAK,KAAA;KACxB,OAAO,aAAa,IAAI,KAAA;IAC1B;IACoB;IACpB,GAAI;IATN,UAAA;KAWG;KACA,SAAS,cACR,oBAAC,QAAD,EAAA,UACE,oBAAC,kBAAD;MAAgB,IAAI;MAAY,IAAG;MAAI,IAAG;MAAI,IAAG;MAAI,IAAG;MACrD,UAAA;KACa,CAAA,EACZ,CAAA;KAGP,cACC,oBAAC,QAAD;MACE,eAAc;MACd,UAAU,YACR,oBAAC,aAAD;OACE,SAAS,QAAQ;OACjB,aAAa;OACb,gBAAgB,aAAa,iBAAiB;OAC9C,YAAY;OACZ,QAAQ;OACA;OACR,WAAW,SAAS;OACR;MACb,CAAA;MAEH,GAAI;KACL,CAAA;KAGH,qBAAC,OAAD;MACE,MAAM,CAAC;MACP,GAAK,gBAAgB,aAAa,EAAE,MAAM,SAAS,IAAI,EAAE,QAAQ;MACjE,MAAM;OAAE,WAAW;OAAoB,UAAU;OAAI,MAAM;MAAe;MAC1E,QAAO;MACP,UAAS;MACT,UAAU,gBAAgB,EAAE,QAAQ,eAAe,IAAI;MACvD,YAAY;MACZ,eAAe,gBAAgB,aAAa,iBAAiB,KAAA;MAC7D,GAAI,UAAU,MAAM;MACpB,GAAI;MAVN,UAAA,CAYG,cACC,oBAAC,OAAD;OAAO,UAAS;OAAe,QAAQ;OAAK,UAAU;OAAI,GAAI,UAAU,WAAW;OAChF,UAAA;MACI,CAAA,GAER,YAAY,QACR;;KAEP,qBAAC,OAAD;MAGE,MAAM;OAAE,WAAW;OAAqB,UAAU;OAAI,MAAM;MAAe;MAC3E,MAAM,CAAC;MACP,GAAI;MACJ,GAAI;MANN,UAAA,CAQG,cACC,oBAAC,OAAD;OACE,UAAS;OACT,OAAO;OACP,YAAW;OACX,UAAU;OACV,QAAQ;OACR,GAAI,UAAU,WAAW;OAExB,UAAA;MACI,CAAA,GAER,YAAY,QACR;;KAEP,qBAAC,OAAD;MACE,SAAQ;MACR,aAAY;MACZ,MAAM;OAAE,WAAW;OAAoB,UAAU;OAAI,MAAM;MAAe;MAC1E,MAAM,CAAC;MACP,GAAI;MACJ,GAAI;MANN,UAAA,CAQG,mBACC,oBAAC,OAAD;OACE,UAAS;OACT,OAAO;OACP,YAAW;OACX,UAAU;OACV,QAAQ;OACR,GAAI,UAAU,WAAW;OAExB,UAAA;MACI,CAAA,GAER,YAAY,QACR;;KAEP,oBAAC,eAAD;MACmB;MACjB,UAAU,aAAa,OAAO,aAAa;MAC3C,YAAY,aAAa,OAAO,aAAa;MAC7C,GAAI,UAAU,MAAM;MACpB,GAAI;KACL,CAAA;KAEA,eACC,oBAACC,WAAD;MACE,mBAAmB;MACnB,mBAAmB,6BAA6B;MAChD,UAAU,gBAAgB,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE;MACnD,QAAQ;OACN,QAAQ;OACR,aAAa;OACb;MACF;MACA,UAAU,EAAE,OAAO,SAAS,qBAC1B,oBAAC,cAAD;OACE,OAAO,kBAAkB,UAAU,eAAe,OAAO,OAAO,IAAI;OAC3D;OACH;OACN,YAAY;OACZ,QAAQ;OACA;OACQ;OAChB,WAAW,SAAS;OACR;MACb,CAAA;MAEH,GAAI;KACL,CAAA;KAGF;KACA;KACA;KACA,aACC,oBAAC,YAAD;MACW;MACT,YAAY;MACZ,QAAQ;MACR,GAAI;KACL,CAAA;KAEF;IACgB;;EACA,CAAA;CAClB,CAAA;AAET,CAAC;AAED,YAAU,cAAc;AACxB,YAAU,UAAUC;AACpB,YAAU,eAAe"}
1
+ {"version":3,"file":"LineChart.mjs","names":["LineChart","useId","ReChartsLineChart","Tooltip","classes"],"sources":["../../src/LineChart/LineChart.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n CartesianGrid,\n Label,\n Legend,\n Line,\n LineProps,\n LineChart as ReChartsLineChart,\n ReferenceArea,\n ReferenceDot,\n ReferenceLine,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from 'recharts';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getThemeColor,\n MantineColor,\n StylesApiProps,\n useMantineTheme,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '@mantine/core';\nimport { useId } from '@mantine/hooks';\nimport { ChartBrush } from '../ChartBrush';\nimport { ChartLegend, ChartLegendStylesNames } from '../ChartLegend';\nimport { ChartTooltip, ChartTooltipStylesNames } from '../ChartTooltip';\nimport { PointLabel } from '../PointLabel/PointLabel';\nimport type {\n BaseChartStylesNames,\n ChartSeries,\n GridChartBaseProps,\n MantineChartDotProps,\n} from '../types';\nimport classes from '../grid-chart.module.css';\n\nexport type LineChartType = 'default' | 'gradient';\n\nexport interface LineChartGradientStop {\n offset: number;\n color: MantineColor;\n}\n\nexport type LineChartCurveType =\n | 'bump'\n | 'linear'\n | 'natural'\n | 'monotone'\n | 'step'\n | 'stepBefore'\n | 'stepAfter';\n\nexport interface LineChartSeries extends ChartSeries {\n strokeDasharray?: string | number;\n curveType?: LineChartCurveType;\n}\n\nexport type LineChartStylesNames =\n | 'line'\n | BaseChartStylesNames\n | ChartLegendStylesNames\n | ChartTooltipStylesNames;\n\nexport type LineChartCssVariables = {\n root: '--chart-text-color' | '--chart-grid-color';\n};\n\nexport interface LineChartProps\n extends BoxProps, GridChartBaseProps, StylesApiProps<LineChartFactory>, ElementProps<'div'> {\n /** Data used to display chart */\n data: Record<string, any>[];\n\n /** An array of objects with `name` and `color` keys. Determines which data should be consumed from the `data` array. */\n series: LineChartSeries[];\n\n /** Controls styles of the line @default 'default' */\n type?: LineChartType;\n\n /** Data used to generate gradient stops @default [{ offset: 0, color: 'red' }, { offset: 100, color: 'blue' }] */\n gradientStops?: LineChartGradientStop[];\n\n /** Type of the curve @default 'monotone' */\n curveType?: LineChartCurveType;\n\n /** Controls fill opacity of all lines @default 1 */\n fillOpacity?: number;\n\n /** Determines whether dots should be displayed @default true */\n withDots?: boolean;\n\n /** Props passed down to all dots. Ignored if `withDots={false}` is set. */\n dotProps?: MantineChartDotProps;\n\n /** Props passed down to all active dots. Ignored if `withDots={false}` is set. */\n activeDotProps?: MantineChartDotProps;\n\n /** Stroke width for the chart lines @default 2 */\n strokeWidth?: number;\n\n /** Props passed down to recharts `LineChart` component */\n lineChartProps?: React.ComponentProps<typeof ReChartsLineChart>;\n\n /** Determines whether points with `null` values should be connected @default true */\n connectNulls?: boolean;\n\n /** Additional components that are rendered inside recharts `LineChart` component */\n children?: React.ReactNode;\n\n /** Props passed down to recharts `Line` component */\n lineProps?:\n | ((series: LineChartSeries) => Partial<Omit<LineProps, 'ref'>>)\n | Partial<Omit<LineProps, 'ref'>>;\n\n /** Determines whether each point should have associated label @default false */\n withPointLabels?: boolean;\n}\n\nexport type LineChartFactory = Factory<{\n props: LineChartProps;\n ref: HTMLDivElement;\n stylesNames: LineChartStylesNames;\n vars: LineChartCssVariables;\n}>;\n\nconst defaultProps = {\n withXAxis: true,\n withYAxis: true,\n withTooltip: true,\n tooltipAnimationDuration: 0,\n fillOpacity: 1,\n tickLine: 'y',\n strokeDasharray: '5 5',\n gridAxis: 'x',\n withDots: true,\n connectNulls: true,\n strokeWidth: 2,\n curveType: 'monotone',\n gradientStops: [\n { offset: 0, color: 'red' },\n { offset: 100, color: 'blue' },\n ],\n accessibilityLayer: true,\n} satisfies Partial<LineChartProps>;\n\nconst varsResolver = createVarsResolver<LineChartFactory>((theme, { textColor, gridColor }) => ({\n root: {\n '--chart-text-color': textColor ? getThemeColor(textColor, theme) : undefined,\n '--chart-grid-color': gridColor ? getThemeColor(gridColor, theme) : undefined,\n },\n}));\n\nexport const LineChart = factory<LineChartFactory>((_props) => {\n const props = useProps('LineChart', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n data,\n withLegend,\n legendProps,\n series,\n onMouseLeave,\n dataKey,\n withTooltip,\n withXAxis,\n withYAxis,\n gridAxis,\n tickLine,\n xAxisProps,\n yAxisProps,\n unit,\n tooltipAnimationDuration,\n strokeDasharray,\n gridProps,\n tooltipProps,\n referenceLines,\n referenceAreas,\n referenceDots,\n withDots,\n dotProps,\n activeDotProps,\n strokeWidth,\n lineChartProps,\n connectNulls,\n fillOpacity,\n curveType,\n orientation,\n dir,\n valueFormatter,\n children,\n lineProps,\n xAxisLabel,\n yAxisLabel,\n type,\n gradientStops,\n withRightYAxis,\n rightYAxisLabel,\n rightYAxisProps,\n withPointLabels,\n attributes,\n gridColor,\n textColor,\n accessibilityLayer,\n withBrush,\n brushProps,\n ...others\n } = props;\n\n const theme = useMantineTheme();\n const withXTickLine = gridAxis !== 'none' && (tickLine === 'x' || tickLine === 'xy');\n const withYTickLine = gridAxis !== 'none' && (tickLine === 'y' || tickLine === 'xy');\n const [highlightedArea, setHighlightedArea] = useState<string | number | null>(null);\n const shouldHighlight = highlightedArea !== null;\n const handleMouseLeave = (event: React.MouseEvent<HTMLDivElement>) => {\n setHighlightedArea(null);\n onMouseLeave?.(event);\n };\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<LineChartFactory>({\n classNames,\n styles,\n props,\n });\n\n const getStyles = useStyles<LineChartFactory>({\n name: 'LineChart',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const id = useId();\n const gradientId = `line-chart-gradient-${id}`;\n const stops = gradientStops?.map((stop) => (\n <stop\n key={stop.color}\n offset={`${stop.offset}%`}\n stopColor={getThemeColor(stop.color, theme)}\n />\n ));\n\n const lines = series.map((item) => {\n const color = getThemeColor(item.color, theme);\n const dimmed = shouldHighlight && highlightedArea !== item.name;\n\n return (\n <Line\n {...getStyles('line')}\n key={item.name}\n name={item.name}\n dataKey={item.name}\n dot={\n withDots\n ? {\n fillOpacity: dimmed ? 0 : 1,\n strokeOpacity: dimmed ? 0 : 1,\n strokeWidth: 1,\n fill: type === 'gradient' ? 'var(--mantine-color-gray-7)' : color,\n stroke: type === 'gradient' ? 'white' : color,\n ...dotProps,\n }\n : false\n }\n activeDot={\n withDots\n ? {\n fill: type === 'gradient' ? 'var(--mantine-color-gray-7)' : color,\n stroke: type === 'gradient' ? 'white' : color,\n ...activeDotProps,\n }\n : false\n }\n fill={color}\n stroke={type === 'gradient' ? `url(#${gradientId})` : color}\n strokeWidth={strokeWidth}\n isAnimationActive={false}\n fillOpacity={dimmed ? 0 : fillOpacity}\n strokeOpacity={dimmed ? 0.5 : fillOpacity}\n connectNulls={connectNulls}\n type={item.curveType ?? curveType}\n strokeDasharray={item.strokeDasharray}\n yAxisId={item.yAxisId || undefined}\n label={withPointLabels ? <PointLabel valueFormatter={valueFormatter} /> : undefined}\n {...(typeof lineProps === 'function' ? lineProps(item) : lineProps)}\n />\n );\n });\n\n const referenceLinesItems = referenceLines?.map(\n ({ color: lineColor, labelPosition, ...line }, index) => {\n const color = getThemeColor(lineColor, theme);\n return (\n <ReferenceLine\n key={index}\n stroke={lineColor ? color : 'var(--chart-grid-color)'}\n strokeWidth={1}\n yAxisId={line.yAxisId || undefined}\n {...line}\n label={{\n fill: lineColor ? color : 'currentColor',\n fontSize: 12,\n position: labelPosition ?? 'insideBottomLeft',\n ...(typeof line.label === 'object' ? line.label : { value: line.label }),\n }}\n {...getStyles('referenceLine')}\n />\n );\n }\n );\n\n const referenceAreasItems = referenceAreas?.map(\n ({ color: areaColor, labelPosition, ...area }, index) => {\n const color = getThemeColor(areaColor, theme);\n return (\n <ReferenceArea\n key={index}\n fill={areaColor ? color : 'var(--chart-grid-color)'}\n fillOpacity={0.2}\n stroke={areaColor ? color : 'var(--chart-grid-color)'}\n strokeOpacity={0.6}\n yAxisId={area.yAxisId || undefined}\n {...area}\n label={{\n fill: areaColor ? color : 'currentColor',\n fontSize: 12,\n position: labelPosition ?? 'insideTop',\n ...(typeof area.label === 'object' ? area.label : { value: area.label }),\n }}\n {...getStyles('referenceArea')}\n />\n );\n }\n );\n\n const referenceDotsItems = referenceDots?.map(\n ({ color: dotColor, labelPosition, ...dot }, index) => {\n const color = getThemeColor(dotColor, theme);\n return (\n <ReferenceDot\n key={index}\n r={5}\n fill={dotColor ? color : 'var(--chart-grid-color)'}\n stroke=\"var(--mantine-color-body)\"\n strokeWidth={2}\n yAxisId={dot.yAxisId || undefined}\n {...dot}\n label={{\n fill: dotColor ? color : 'currentColor',\n fontSize: 12,\n position: labelPosition ?? 'top',\n ...(typeof dot.label === 'object' ? dot.label : { value: dot.label }),\n }}\n {...getStyles('referenceDot')}\n />\n );\n }\n );\n\n const sharedYAxisProps = {\n axisLine: false,\n ...(orientation === 'vertical'\n ? { dataKey, type: 'category' as const }\n : { type: 'number' as const }),\n tickLine: withYTickLine ? { stroke: 'currentColor' } : false,\n allowDecimals: true,\n unit,\n tickFormatter: orientation === 'vertical' ? undefined : valueFormatter,\n ...getStyles('axis'),\n };\n\n return (\n <Box {...getStyles('root')} onMouseLeave={handleMouseLeave} dir={dir || 'ltr'} {...others}>\n <ResponsiveContainer {...getStyles('container')}>\n <ReChartsLineChart\n data={data}\n layout={orientation}\n margin={{\n bottom: xAxisLabel ? 30 : undefined,\n left: yAxisLabel ? 10 : undefined,\n right: yAxisLabel ? 5 : undefined,\n }}\n accessibilityLayer={accessibilityLayer}\n {...lineChartProps}\n >\n {referenceAreasItems}\n {type === 'gradient' && (\n <defs>\n <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n {stops}\n </linearGradient>\n </defs>\n )}\n\n {withLegend && (\n <Legend\n verticalAlign=\"top\"\n content={(payload) => (\n <ChartLegend\n payload={payload.payload}\n onHighlight={setHighlightedArea}\n legendPosition={legendProps?.verticalAlign || 'top'}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n series={series}\n showColor={type !== 'gradient'}\n attributes={attributes}\n />\n )}\n {...legendProps}\n />\n )}\n\n <XAxis\n hide={!withXAxis}\n {...(orientation === 'vertical' ? { type: 'number' } : { dataKey })}\n tick={{ transform: 'translate(0, 10)', fontSize: 12, fill: 'currentColor' }}\n stroke=\"\"\n interval=\"preserveStartEnd\"\n tickLine={withXTickLine ? { stroke: 'currentColor' } : false}\n minTickGap={5}\n tickFormatter={orientation === 'vertical' ? valueFormatter : undefined}\n {...getStyles('axis')}\n {...xAxisProps}\n >\n {xAxisLabel && (\n <Label position=\"insideBottom\" offset={-20} fontSize={12} {...getStyles('axisLabel')}>\n {xAxisLabel}\n </Label>\n )}\n {xAxisProps?.children}\n </XAxis>\n\n <YAxis\n // yAxisId=\"left\"\n // orientation=\"left\"\n tick={{ transform: 'translate(-10, 0)', fontSize: 12, fill: 'currentColor' }}\n hide={!withYAxis}\n {...sharedYAxisProps}\n {...yAxisProps}\n >\n {yAxisLabel && (\n <Label\n position=\"insideLeft\"\n angle={-90}\n textAnchor=\"middle\"\n fontSize={12}\n offset={-5}\n {...getStyles('axisLabel')}\n >\n {yAxisLabel}\n </Label>\n )}\n {yAxisProps?.children}\n </YAxis>\n\n <YAxis\n yAxisId=\"right\"\n orientation=\"right\"\n tick={{ transform: 'translate(10, 0)', fontSize: 12, fill: 'currentColor' }}\n hide={!withRightYAxis}\n {...sharedYAxisProps}\n {...rightYAxisProps}\n >\n {rightYAxisLabel && (\n <Label\n position=\"insideRight\"\n angle={90}\n textAnchor=\"middle\"\n fontSize={12}\n offset={-5}\n {...getStyles('axisLabel')}\n >\n {rightYAxisLabel}\n </Label>\n )}\n {yAxisProps?.children}\n </YAxis>\n\n <CartesianGrid\n strokeDasharray={strokeDasharray as string}\n vertical={gridAxis === 'y' || gridAxis === 'xy'}\n horizontal={gridAxis === 'x' || gridAxis === 'xy'}\n {...getStyles('grid')}\n {...gridProps}\n />\n\n {withTooltip && (\n <Tooltip\n animationDuration={tooltipAnimationDuration}\n isAnimationActive={tooltipAnimationDuration !== 0}\n position={orientation === 'vertical' ? {} : { y: 0 }}\n cursor={{\n stroke: 'var(--chart-grid-color)',\n strokeWidth: 1,\n strokeDasharray,\n }}\n content={({ label, payload, labelFormatter }) => (\n <ChartTooltip\n label={labelFormatter && payload ? labelFormatter(label, payload) : label}\n payload={payload}\n unit={unit}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n series={series}\n valueFormatter={valueFormatter}\n showColor={type !== 'gradient'}\n attributes={attributes}\n />\n )}\n {...tooltipProps}\n />\n )}\n\n {lines}\n {referenceLinesItems}\n {referenceDotsItems}\n {withBrush && (\n <ChartBrush\n dataKey={dataKey}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n {...brushProps}\n />\n )}\n {children}\n </ReChartsLineChart>\n </ResponsiveContainer>\n </Box>\n );\n});\n\nLineChart.displayName = '@mantine/charts/LineChart';\nLineChart.classes = classes;\nLineChart.varsResolver = varsResolver;\n\nexport namespace LineChart {\n export type Props = LineChartProps;\n export type CssVariables = LineChartCssVariables;\n export type Factory = LineChartFactory;\n export type Series = LineChartSeries;\n export type StylesNames = LineChartStylesNames;\n export type CurveType = LineChartCurveType;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PieChart.mjs","names":["classes","PieChart","ReChartsPieChart","Tooltip"],"sources":["../../src/PieChart/PieChart.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Legend,\n LegendProps,\n Pie,\n PieLabel,\n PieProps,\n PieChart as ReChartsPieChart,\n ResponsiveContainer,\n Tooltip,\n TooltipProps,\n} from 'recharts';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getThemeColor,\n MantineColor,\n rem,\n StylesApiProps,\n useMantineTheme,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '@mantine/core';\nimport { ChartLegend, ChartLegendStylesNames } from '../ChartLegend';\nimport { ChartTooltip, ChartTooltipStylesNames } from '../ChartTooltip/ChartTooltip';\nimport { getPieChartData } from '../utils';\nimport classes from './PieChart.module.css';\n\nexport interface PieChartCell {\n key?: string | number;\n name: string;\n value: number;\n color: MantineColor;\n}\n\nexport type PieChartStylesNames = 'root' | ChartTooltipStylesNames | ChartLegendStylesNames;\nexport type PieChartCssVariables = {\n root: '--chart-stroke-color' | '--chart-labels-color' | '--chart-size';\n};\n\nexport interface PieChartProps\n extends BoxProps, StylesApiProps<PieChartFactory>, ElementProps<'div'> {\n /** Data used to render chart */\n data: PieChartCell[];\n\n /** Determines whether the tooltip should be displayed when one of the section is hovered @default true */\n withTooltip?: boolean;\n\n /** Determines whether the legend should be displayed @default false */\n withLegend?: boolean;\n\n /** Props passed down to recharts `Legend` component */\n legendProps?: Omit<LegendProps, 'ref'>;\n\n /** Tooltip animation duration in ms @default 0 */\n tooltipAnimationDuration?: number;\n\n /** Props passed down to `Tooltip` recharts component */\n tooltipProps?: Omit<TooltipProps<any, any>, 'ref'>;\n\n /** Props passed down to recharts `Pie` component */\n pieProps?: Partial<Omit<PieProps, 'ref'>>;\n\n /** Controls color of the segments stroke, by default depends on color scheme */\n strokeColor?: MantineColor;\n\n /** Controls text color of all labels, white by default */\n labelColor?: MantineColor;\n\n /** Controls padding between segments @default 0 */\n paddingAngle?: number;\n\n /** Determines whether each segment should have associated label @default false */\n withLabels?: boolean;\n\n /** Determines whether segments labels should have lines that connect the segment with the label @default true */\n withLabelsLine?: boolean;\n\n /** Controls chart width and height, height is increased by 40 if `withLabels` prop is set. Cannot be less than `thickness`. @default 80 */\n size?: number;\n\n /** Controls width of segments stroke @default 1 */\n strokeWidth?: number;\n\n /** Controls angle at which chart starts. Set to `180` to render the chart as semicircle. @default 0 */\n startAngle?: number;\n\n /** Controls angle at which charts ends. Set to `0` to render the chart as semicircle. @default 360 */\n endAngle?: number;\n\n /** Determines which data is displayed in the tooltip. `'all'` – display all values, `'segment'` – display only hovered segment. @default 'all' */\n tooltipDataSource?: 'segment' | 'all';\n\n /** Additional elements rendered inside `PieChart` component */\n children?: React.ReactNode;\n\n /** Props passed down to recharts `PieChart` component */\n pieChartProps?: React.ComponentProps<typeof ReChartsPieChart>;\n\n /** Controls labels position relative to the segment @default 'outside' */\n labelsPosition?: 'inside' | 'outside';\n\n /** Type of labels to display @default 'value' */\n labelsType?: 'value' | 'percent' | 'name';\n\n /** A function to format values inside the tooltip */\n valueFormatter?: (value: number) => string;\n\n /** Props passed down to each segment of the chart */\n cellProps?:\n | ((series: PieChartCell) => Partial<Omit<React.SVGProps<SVGElement>, 'ref'>>)\n | Partial<Omit<React.SVGProps<SVGElement>, 'ref'>>;\n\n /** Determines whether the chart should be keyboard-navigable with the recharts accessibility layer, `true` by default */\n accessibilityLayer?: boolean;\n}\n\nexport type PieChartFactory = Factory<{\n props: PieChartProps;\n ref: HTMLDivElement;\n stylesNames: PieChartStylesNames;\n vars: PieChartCssVariables;\n}>;\n\nconst defaultProps = {\n withTooltip: false,\n withLabelsLine: true,\n paddingAngle: 0,\n size: 160,\n strokeWidth: 1,\n startAngle: 0,\n endAngle: 360,\n tooltipDataSource: 'all',\n labelsPosition: 'outside',\n labelsType: 'value',\n accessibilityLayer: true,\n} satisfies Partial<PieChartProps>;\n\nconst varsResolver = createVarsResolver<PieChartFactory>(\n (theme, { strokeColor, labelColor, withLabels, withLegend, size, labelsPosition }) => ({\n root: {\n '--chart-stroke-color': strokeColor ? getThemeColor(strokeColor, theme) : undefined,\n '--chart-labels-color': labelColor ? getThemeColor(labelColor, theme) : undefined,\n '--chart-size': rem(\n size! + (withLabels && labelsPosition === 'outside' ? 80 : 0) + (withLegend ? 80 : 0)\n ),\n },\n })\n);\n\nconst getLabelValue = (\n labelsType: PieChartProps['labelsType'],\n value: number | undefined,\n percent: number | undefined,\n name: string | undefined,\n valueFormatter?: PieChartProps['valueFormatter']\n) => {\n if (labelsType === 'name') {\n return name;\n }\n\n if (labelsType === 'percent' && typeof percent === 'number') {\n return `${(percent * 100).toFixed(0)}%`;\n }\n\n if (typeof valueFormatter === 'function' && typeof value === 'number') {\n return valueFormatter(value);\n }\n\n return value;\n};\n\nconst getInsideLabel =\n (\n labelsType: 'value' | 'percent' | 'name',\n valueFormatter?: PieChartProps['valueFormatter']\n ): PieLabel =>\n ({ cx, cy, midAngle, innerRadius, outerRadius, value, percent, name }) => {\n const RADIAN = Math.PI / 180;\n const radius = Number(innerRadius) + (Number(outerRadius) - Number(innerRadius)) * 0.5;\n const x = Number(cx) + radius * Math.cos(-(midAngle || 0) * RADIAN);\n const y = Number(cy) + radius * Math.sin(-(midAngle || 0) * RADIAN);\n\n return (\n <text\n x={x}\n y={y}\n textAnchor={x > Number(cx) ? 'start' : 'end'}\n dominantBaseline=\"central\"\n className={classes.label}\n >\n {getLabelValue(labelsType, Number(value), Number(percent), name as string, valueFormatter)}\n </text>\n );\n };\n\nconst getOutsideLabel =\n (\n labelsType: 'value' | 'percent' | 'name',\n valueFormatter?: PieChartProps['valueFormatter']\n ): PieLabel =>\n ({ x, y, cx, cy, percent, value, name }) => (\n <text\n x={x}\n y={y}\n cx={cx}\n cy={cy}\n textAnchor={x > Number(cx) ? 'start' : 'end'}\n fill=\"var(--chart-labels-color, var(--mantine-color-dimmed))\"\n fontFamily=\"var(--mantine-font-family)\"\n fontSize={12}\n >\n <tspan x={x}>\n {getLabelValue(labelsType, Number(value), Number(percent), name as string, valueFormatter)}\n </tspan>\n </text>\n );\n\nexport const PieChart = factory<PieChartFactory>((_props) => {\n const props = useProps('PieChart', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n data,\n withTooltip,\n withLegend,\n legendProps,\n tooltipAnimationDuration,\n tooltipProps,\n pieProps,\n paddingAngle,\n withLabels,\n withLabelsLine,\n size,\n strokeWidth,\n startAngle,\n endAngle,\n tooltipDataSource,\n children,\n pieChartProps,\n labelsPosition,\n valueFormatter,\n labelsType,\n strokeColor,\n attributes,\n cellProps,\n accessibilityLayer,\n ...others\n } = props;\n\n const theme = useMantineTheme();\n const [highlightedIndex, setHighlightedIndex] = useState<number | null>(null);\n\n const getStyles = useStyles<PieChartFactory>({\n name: 'PieChart',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<PieChartFactory>({\n classNames,\n styles,\n props,\n });\n\n const pieData = getPieChartData({ data, theme, strokeWidth, highlightedIndex, cellProps });\n\n return (\n <Box size={size} {...getStyles('root')} {...others}>\n <ResponsiveContainer>\n <ReChartsPieChart accessibilityLayer={accessibilityLayer} {...pieChartProps}>\n <Pie\n data={pieData as any}\n innerRadius={0}\n outerRadius={size / 2}\n dataKey=\"value\"\n isAnimationActive={false}\n paddingAngle={paddingAngle}\n startAngle={startAngle}\n endAngle={endAngle}\n label={\n withLabels\n ? labelsPosition === 'inside'\n ? getInsideLabel(labelsType || 'value', valueFormatter)\n : getOutsideLabel(labelsType || 'value', valueFormatter)\n : false\n }\n labelLine={\n withLabelsLine && labelsPosition === 'outside'\n ? {\n stroke: 'var(--chart-label-color, var(--mantine-color-dimmed))',\n strokeWidth: 1,\n }\n : false\n }\n {...pieProps}\n />\n\n {withTooltip && (\n <Tooltip\n animationDuration={tooltipAnimationDuration}\n isAnimationActive={false}\n content={({ payload }) => (\n <ChartTooltip\n payload={data}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n type=\"radial\"\n segmentId={\n tooltipDataSource === 'segment'\n ? (payload?.[0]?.payload?.__segmentIndex as number)\n : undefined\n }\n valueFormatter={valueFormatter}\n attributes={attributes}\n />\n )}\n {...tooltipProps}\n />\n )}\n\n {withLegend && (\n <Legend\n verticalAlign=\"bottom\"\n content={(payload) => (\n <ChartLegend\n payload={payload.payload?.map((item) => ({\n ...item,\n dataKey: (item.payload as any)?.name,\n highlightKey: (item.payload as any)?.__segmentIndex,\n }))}\n onHighlight={(value) =>\n setHighlightedIndex(typeof value === 'number' ? value : null)\n }\n legendPosition={legendProps?.verticalAlign || 'bottom'}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n centered\n attributes={attributes}\n />\n )}\n {...legendProps}\n />\n )}\n\n {children}\n </ReChartsPieChart>\n </ResponsiveContainer>\n </Box>\n );\n});\n\nPieChart.displayName = '@mantine/charts/PieChart';\nPieChart.classes = classes;\nPieChart.varsResolver = varsResolver;\n\nexport namespace PieChart {\n export type Props = PieChartProps;\n export type StylesNames = PieChartStylesNames;\n export type CssVariables = PieChartCssVariables;\n export type Factory = PieChartFactory;\n export type Cell = PieChartCell;\n}\n"],"mappings":";;;;;;;;;;AAiIA,MAAM,eAAe;CACnB,aAAa;CACb,gBAAgB;CAChB,cAAc;CACd,MAAM;CACN,aAAa;CACb,YAAY;CACZ,UAAU;CACV,mBAAmB;CACnB,gBAAgB;CAChB,YAAY;CACZ,oBAAoB;AACtB;AAEA,MAAM,eAAe,oBAClB,OAAO,EAAE,aAAa,YAAY,YAAY,YAAY,MAAM,sBAAsB,EACrF,MAAM;CACJ,wBAAwB,cAAc,cAAc,aAAa,KAAK,IAAI,KAAA;CAC1E,wBAAwB,aAAa,cAAc,YAAY,KAAK,IAAI,KAAA;CACxE,gBAAgB,IACd,QAAS,cAAc,mBAAmB,YAAY,KAAK,MAAM,aAAa,KAAK,EACrF;AACF,EACF,EACF;AAEA,MAAM,iBACJ,YACA,OACA,SACA,MACA,mBACG;CACH,IAAI,eAAe,QACjB,OAAO;CAGT,IAAI,eAAe,aAAa,OAAO,YAAY,UACjD,OAAO,IAAI,UAAU,IAAA,CAAK,QAAQ,CAAC,EAAE;CAGvC,IAAI,OAAO,mBAAmB,cAAc,OAAO,UAAU,UAC3D,OAAO,eAAe,KAAK;CAG7B,OAAO;AACT;AAEA,MAAM,kBAEF,YACA,oBAED,EAAE,IAAI,IAAI,UAAU,aAAa,aAAa,OAAO,SAAS,WAAW;CACxE,MAAM,SAAS,KAAK,KAAK;CACzB,MAAM,SAAS,OAAO,WAAW,KAAK,OAAO,WAAW,IAAI,OAAO,WAAW,KAAK;CACnF,MAAM,IAAI,OAAO,EAAE,IAAI,SAAS,KAAK,IAAI,EAAE,YAAY,KAAK,MAAM;CAClE,MAAM,IAAI,OAAO,EAAE,IAAI,SAAS,KAAK,IAAI,EAAE,YAAY,KAAK,MAAM;CAElE,OACE,oBAAC,QAAD;EACK;EACA;EACH,YAAY,IAAI,OAAO,EAAE,IAAI,UAAU;EACvC,kBAAiB;EACjB,WAAWA,wBAAQ;EAElB,UAAA,cAAc,YAAY,OAAO,KAAK,GAAG,OAAO,OAAO,GAAG,MAAgB,cAAc;CACrF,CAAA;AAEV;AAEF,MAAM,mBAEF,YACA,oBAED,EAAE,GAAG,GAAG,IAAI,IAAI,SAAS,OAAO,WAC/B,oBAAC,QAAD;CACK;CACA;CACC;CACA;CACJ,YAAY,IAAI,OAAO,EAAE,IAAI,UAAU;CACvC,MAAK;CACL,YAAW;CACX,UAAU;CAEV,UAAA,oBAAC,SAAD;EAAU;EACP,UAAA,cAAc,YAAY,OAAO,KAAK,GAAG,OAAO,OAAO,GAAG,MAAgB,cAAc;CACpF,CAAA;AACH,CAAA;AAGV,MAAaC,aAAW,SAA0B,WAAW;CAC3D,MAAM,QAAQ,SAAS,YAAY,cAAc,MAAM;CACvD,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,MACA,MACA,aACA,YACA,aACA,0BACA,cACA,UACA,cACA,YACA,gBACA,MACA,aACA,YACA,UACA,mBACA,UACA,eACA,gBACA,gBACA,YACA,aACA,YACA,WACA,oBACA,GAAG,WACD;CAEJ,MAAM,QAAQ,gBAAgB;CAC9B,MAAM,CAAC,kBAAkB,uBAAuB,SAAwB,IAAI;CAE5E,MAAM,YAAY,UAA2B;EAC3C,MAAM;EACN,SAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,EAAE,oBAAoB,mBAAmB,qBAAsC;EACnF;EACA;EACA;CACF,CAAC;CAED,MAAM,UAAU,gBAAgB;EAAE;EAAM;EAAO;EAAa;EAAkB;CAAU,CAAC;CAEzF,OACE,oBAAC,KAAD;EAAW;EAAM,GAAI,UAAU,MAAM;EAAG,GAAI;EAC1C,UAAA,oBAAC,qBAAD,EAAA,UACE,qBAACC,UAAD;GAAsC;GAAoB,GAAI;GAA9D,UAAA;IACE,oBAAC,KAAD;KACE,MAAM;KACN,aAAa;KACb,aAAa,OAAO;KACpB,SAAQ;KACR,mBAAmB;KACL;KACF;KACF;KACV,OACE,aACI,mBAAmB,WACjB,eAAe,cAAc,SAAS,cAAc,IACpD,gBAAgB,cAAc,SAAS,cAAc,IACvD;KAEN,WACE,kBAAkB,mBAAmB,YACjC;MACE,QAAQ;MACR,aAAa;KACf,IACA;KAEN,GAAI;IACL,CAAA;IAEA,eACC,oBAACC,WAAD;KACE,mBAAmB;KACnB,mBAAmB;KACnB,UAAU,EAAE,cACV,oBAAC,cAAD;MACE,SAAS;MACT,YAAY;MACZ,QAAQ;MACR,MAAK;MACL,WACE,sBAAsB,YACjB,UAAU,EAAE,EAAE,SAAS,iBACxB,KAAA;MAEU;MACJ;KACb,CAAA;KAEH,GAAI;IACL,CAAA;IAGF,cACC,oBAAC,QAAD;KACE,eAAc;KACd,UAAU,YACR,oBAAC,aAAD;MACE,SAAS,QAAQ,SAAS,KAAK,UAAU;OACvC,GAAG;OACH,SAAU,KAAK,SAAiB;OAChC,cAAe,KAAK,SAAiB;MACvC,EAAE;MACF,cAAc,UACZ,oBAAoB,OAAO,UAAU,WAAW,QAAQ,IAAI;MAE9D,gBAAgB,aAAa,iBAAiB;MAC9C,YAAY;MACZ,QAAQ;MACR,UAAA;MACY;KACb,CAAA;KAEH,GAAI;IACL,CAAA;IAGF;GACe;EACC,CAAA,EAAA,CAAA;CAClB,CAAA;AAET,CAAC;AAED,WAAS,cAAc;AACvB,WAAS,UAAUH;AACnB,WAAS,eAAe"}
1
+ {"version":3,"file":"PieChart.mjs","names":["classes","PieChart","ReChartsPieChart","Tooltip"],"sources":["../../src/PieChart/PieChart.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Legend,\n LegendProps,\n Pie,\n PieLabel,\n PieProps,\n PieChart as ReChartsPieChart,\n ResponsiveContainer,\n Tooltip,\n TooltipProps,\n} from 'recharts';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getThemeColor,\n MantineColor,\n rem,\n StylesApiProps,\n useMantineTheme,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '@mantine/core';\nimport { ChartLegend, ChartLegendStylesNames } from '../ChartLegend';\nimport { ChartTooltip, ChartTooltipStylesNames } from '../ChartTooltip/ChartTooltip';\nimport { getPieChartData } from '../utils';\nimport classes from './PieChart.module.css';\n\nexport interface PieChartCell {\n key?: string | number;\n name: string;\n value: number;\n color: MantineColor;\n}\n\nexport type PieChartStylesNames = 'root' | ChartTooltipStylesNames | ChartLegendStylesNames;\nexport type PieChartCssVariables = {\n root: '--chart-stroke-color' | '--chart-labels-color' | '--chart-size';\n};\n\nexport interface PieChartProps\n extends BoxProps, StylesApiProps<PieChartFactory>, ElementProps<'div'> {\n /** Data used to render chart */\n data: PieChartCell[];\n\n /** Determines whether the tooltip should be displayed when one of the section is hovered @default false */\n withTooltip?: boolean;\n\n /** Determines whether the legend should be displayed @default false */\n withLegend?: boolean;\n\n /** Props passed down to recharts `Legend` component */\n legendProps?: Omit<LegendProps, 'ref'>;\n\n /** Tooltip animation duration in ms @default 0 */\n tooltipAnimationDuration?: number;\n\n /** Props passed down to `Tooltip` recharts component */\n tooltipProps?: Omit<TooltipProps<any, any>, 'ref'>;\n\n /** Props passed down to recharts `Pie` component */\n pieProps?: Partial<Omit<PieProps, 'ref'>>;\n\n /** Controls color of the segments stroke, by default depends on color scheme */\n strokeColor?: MantineColor;\n\n /** Controls text color of all labels, white by default */\n labelColor?: MantineColor;\n\n /** Controls padding between segments @default 0 */\n paddingAngle?: number;\n\n /** Determines whether each segment should have associated label @default false */\n withLabels?: boolean;\n\n /** Determines whether segments labels should have lines that connect the segment with the label @default true */\n withLabelsLine?: boolean;\n\n /** Controls chart width and height, height is increased by 40 if `withLabels` prop is set. Cannot be less than `thickness`. @default 160 */\n size?: number;\n\n /** Controls width of segments stroke @default 1 */\n strokeWidth?: number;\n\n /** Controls angle at which chart starts. Set to `180` to render the chart as semicircle. @default 0 */\n startAngle?: number;\n\n /** Controls angle at which charts ends. Set to `0` to render the chart as semicircle. @default 360 */\n endAngle?: number;\n\n /** Determines which data is displayed in the tooltip. `'all'` – display all values, `'segment'` – display only hovered segment. @default 'all' */\n tooltipDataSource?: 'segment' | 'all';\n\n /** Additional elements rendered inside `PieChart` component */\n children?: React.ReactNode;\n\n /** Props passed down to recharts `PieChart` component */\n pieChartProps?: React.ComponentProps<typeof ReChartsPieChart>;\n\n /** Controls labels position relative to the segment @default 'outside' */\n labelsPosition?: 'inside' | 'outside';\n\n /** Type of labels to display @default 'value' */\n labelsType?: 'value' | 'percent' | 'name';\n\n /** A function to format values inside the tooltip */\n valueFormatter?: (value: number) => string;\n\n /** Props passed down to each segment of the chart */\n cellProps?:\n | ((series: PieChartCell) => Partial<Omit<React.SVGProps<SVGElement>, 'ref'>>)\n | Partial<Omit<React.SVGProps<SVGElement>, 'ref'>>;\n\n /** Determines whether the chart should be keyboard-navigable with the recharts accessibility layer, `true` by default */\n accessibilityLayer?: boolean;\n}\n\nexport type PieChartFactory = Factory<{\n props: PieChartProps;\n ref: HTMLDivElement;\n stylesNames: PieChartStylesNames;\n vars: PieChartCssVariables;\n}>;\n\nconst defaultProps = {\n withTooltip: false,\n withLabelsLine: true,\n paddingAngle: 0,\n size: 160,\n strokeWidth: 1,\n startAngle: 0,\n endAngle: 360,\n tooltipDataSource: 'all',\n labelsPosition: 'outside',\n labelsType: 'value',\n accessibilityLayer: true,\n} satisfies Partial<PieChartProps>;\n\nconst varsResolver = createVarsResolver<PieChartFactory>(\n (theme, { strokeColor, labelColor, withLabels, withLegend, size, labelsPosition }) => ({\n root: {\n '--chart-stroke-color': strokeColor ? getThemeColor(strokeColor, theme) : undefined,\n '--chart-labels-color': labelColor ? getThemeColor(labelColor, theme) : undefined,\n '--chart-size': rem(\n size! + (withLabels && labelsPosition === 'outside' ? 80 : 0) + (withLegend ? 80 : 0)\n ),\n },\n })\n);\n\nconst getLabelValue = (\n labelsType: PieChartProps['labelsType'],\n value: number | undefined,\n percent: number | undefined,\n name: string | undefined,\n valueFormatter?: PieChartProps['valueFormatter']\n) => {\n if (labelsType === 'name') {\n return name;\n }\n\n if (labelsType === 'percent' && typeof percent === 'number') {\n return `${(percent * 100).toFixed(0)}%`;\n }\n\n if (typeof valueFormatter === 'function' && typeof value === 'number') {\n return valueFormatter(value);\n }\n\n return value;\n};\n\nconst getInsideLabel =\n (\n labelsType: 'value' | 'percent' | 'name',\n valueFormatter?: PieChartProps['valueFormatter']\n ): PieLabel =>\n ({ cx, cy, midAngle, innerRadius, outerRadius, value, percent, name }) => {\n const RADIAN = Math.PI / 180;\n const radius = Number(innerRadius) + (Number(outerRadius) - Number(innerRadius)) * 0.5;\n const x = Number(cx) + radius * Math.cos(-(midAngle || 0) * RADIAN);\n const y = Number(cy) + radius * Math.sin(-(midAngle || 0) * RADIAN);\n\n return (\n <text\n x={x}\n y={y}\n textAnchor={x > Number(cx) ? 'start' : 'end'}\n dominantBaseline=\"central\"\n className={classes.label}\n >\n {getLabelValue(labelsType, Number(value), Number(percent), name as string, valueFormatter)}\n </text>\n );\n };\n\nconst getOutsideLabel =\n (\n labelsType: 'value' | 'percent' | 'name',\n valueFormatter?: PieChartProps['valueFormatter']\n ): PieLabel =>\n ({ x, y, cx, cy, percent, value, name }) => (\n <text\n x={x}\n y={y}\n cx={cx}\n cy={cy}\n textAnchor={x > Number(cx) ? 'start' : 'end'}\n fill=\"var(--chart-labels-color, var(--mantine-color-dimmed))\"\n fontFamily=\"var(--mantine-font-family)\"\n fontSize={12}\n >\n <tspan x={x}>\n {getLabelValue(labelsType, Number(value), Number(percent), name as string, valueFormatter)}\n </tspan>\n </text>\n );\n\nexport const PieChart = factory<PieChartFactory>((_props) => {\n const props = useProps('PieChart', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n data,\n withTooltip,\n withLegend,\n legendProps,\n tooltipAnimationDuration,\n tooltipProps,\n pieProps,\n paddingAngle,\n withLabels,\n withLabelsLine,\n size,\n strokeWidth,\n startAngle,\n endAngle,\n tooltipDataSource,\n children,\n pieChartProps,\n labelsPosition,\n valueFormatter,\n labelsType,\n strokeColor,\n attributes,\n cellProps,\n accessibilityLayer,\n ...others\n } = props;\n\n const theme = useMantineTheme();\n const [highlightedIndex, setHighlightedIndex] = useState<number | null>(null);\n\n const getStyles = useStyles<PieChartFactory>({\n name: 'PieChart',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi<PieChartFactory>({\n classNames,\n styles,\n props,\n });\n\n const pieData = getPieChartData({ data, theme, strokeWidth, highlightedIndex, cellProps });\n\n return (\n <Box size={size} {...getStyles('root')} {...others}>\n <ResponsiveContainer>\n <ReChartsPieChart accessibilityLayer={accessibilityLayer} {...pieChartProps}>\n <Pie\n data={pieData as any}\n innerRadius={0}\n outerRadius={size / 2}\n dataKey=\"value\"\n isAnimationActive={false}\n paddingAngle={paddingAngle}\n startAngle={startAngle}\n endAngle={endAngle}\n label={\n withLabels\n ? labelsPosition === 'inside'\n ? getInsideLabel(labelsType || 'value', valueFormatter)\n : getOutsideLabel(labelsType || 'value', valueFormatter)\n : false\n }\n labelLine={\n withLabelsLine && labelsPosition === 'outside'\n ? {\n stroke: 'var(--chart-label-color, var(--mantine-color-dimmed))',\n strokeWidth: 1,\n }\n : false\n }\n {...pieProps}\n />\n\n {withTooltip && (\n <Tooltip\n animationDuration={tooltipAnimationDuration}\n isAnimationActive={false}\n content={({ payload }) => (\n <ChartTooltip\n payload={data}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n type=\"radial\"\n segmentId={\n tooltipDataSource === 'segment'\n ? (payload?.[0]?.payload?.__segmentIndex as number)\n : undefined\n }\n valueFormatter={valueFormatter}\n attributes={attributes}\n />\n )}\n {...tooltipProps}\n />\n )}\n\n {withLegend && (\n <Legend\n verticalAlign=\"bottom\"\n content={(payload) => (\n <ChartLegend\n payload={payload.payload?.map((item) => ({\n ...item,\n dataKey: (item.payload as any)?.name,\n highlightKey: (item.payload as any)?.__segmentIndex,\n }))}\n onHighlight={(value) =>\n setHighlightedIndex(typeof value === 'number' ? value : null)\n }\n legendPosition={legendProps?.verticalAlign || 'bottom'}\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n centered\n attributes={attributes}\n />\n )}\n {...legendProps}\n />\n )}\n\n {children}\n </ReChartsPieChart>\n </ResponsiveContainer>\n </Box>\n );\n});\n\nPieChart.displayName = '@mantine/charts/PieChart';\nPieChart.classes = classes;\nPieChart.varsResolver = varsResolver;\n\nexport namespace PieChart {\n export type Props = PieChartProps;\n export type StylesNames = PieChartStylesNames;\n export type CssVariables = PieChartCssVariables;\n export type Factory = PieChartFactory;\n export type Cell = PieChartCell;\n}\n"],"mappings":"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"}
@@ -30,7 +30,7 @@ export interface BarsListProps extends BoxProps, StylesApiProps<BarsListFactory>
30
30
  renderBar?: (data: BarsListBarData, defaultBar: React.ReactNode) => React.ReactNode;
31
31
  /** Controls gap between bars @default 5 */
32
32
  barGap?: MantineSpacing;
33
- /** Minimum bar width @default 100 */
33
+ /** Minimum bar width @default 0 */
34
34
  minBarSize?: number | string;
35
35
  /** Bar height @default 32 */
36
36
  barHeight?: number | string;
@@ -38,7 +38,7 @@ export interface DonutChartProps extends BoxProps, StylesApiProps<DonutChartFact
38
38
  withLabelsLine?: boolean;
39
39
  /** Controls thickness of the chart segments @default 20 */
40
40
  thickness?: number;
41
- /** Controls chart width and height, height is increased by 40 if `withLabels` prop is set. Cannot be less than `thickness`. @default 80 */
41
+ /** Controls chart width and height, height is increased by 40 if `withLabels` prop is set. Cannot be less than `thickness`. @default 160 */
42
42
  size?: number;
43
43
  /** Controls width of segments stroke @default 1 */
44
44
  strokeWidth?: number;
@@ -5,7 +5,7 @@ export interface GaugeChartSection {
5
5
  /** Color of the section */
6
6
  color: MantineColor;
7
7
  }
8
- export type GaugeChartStylesNames = 'root' | 'track' | 'section' | 'needle' | 'label';
8
+ export type GaugeChartStylesNames = 'root' | 'track' | 'section' | 'sectionCap' | 'needle' | 'label';
9
9
  export type GaugeChartCssVariables = {
10
10
  root: '--gauge-size';
11
11
  };
@@ -40,7 +40,7 @@ export interface GaugeChartProps extends BoxProps, StylesApiProps<GaugeChartFact
40
40
  targetColor?: MantineColor;
41
41
  /** Thickness of the target marker, @default 2 */
42
42
  targetSize?: number;
43
- /** Whether to round arc endpoints. Not applied to `sections` – rounded caps of adjacent sections would overlap each other. @default false */
43
+ /** Whether to round arc endpoints. With `sections`, only the outer ends of the first and last sections are rounded. @default false */
44
44
  roundCaps?: boolean;
45
45
  }
46
46
  export type GaugeChartFactory = Factory<{
@@ -37,7 +37,7 @@ export interface HeatmapProps extends BoxProps, StylesApiProps<HeatmapFactory>,
37
37
  colors?: string[];
38
38
  /** Width of weekday labels column @default 30 */
39
39
  weekdaysLabelsWidth?: number;
40
- /** Height of month labels row @default 30 */
40
+ /** Height of month labels row @default 14 */
41
41
  monthsLabelsHeight?: number;
42
42
  /** Font size of month and weekday labels @default 12 */
43
43
  fontSize?: number;
@@ -15,7 +15,7 @@ export type PieChartCssVariables = {
15
15
  export interface PieChartProps extends BoxProps, StylesApiProps<PieChartFactory>, ElementProps<'div'> {
16
16
  /** Data used to render chart */
17
17
  data: PieChartCell[];
18
- /** Determines whether the tooltip should be displayed when one of the section is hovered @default true */
18
+ /** Determines whether the tooltip should be displayed when one of the section is hovered @default false */
19
19
  withTooltip?: boolean;
20
20
  /** Determines whether the legend should be displayed @default false */
21
21
  withLegend?: boolean;
@@ -37,7 +37,7 @@ export interface PieChartProps extends BoxProps, StylesApiProps<PieChartFactory>
37
37
  withLabels?: boolean;
38
38
  /** Determines whether segments labels should have lines that connect the segment with the label @default true */
39
39
  withLabelsLine?: boolean;
40
- /** Controls chart width and height, height is increased by 40 if `withLabels` prop is set. Cannot be less than `thickness`. @default 80 */
40
+ /** Controls chart width and height, height is increased by 40 if `withLabels` prop is set. Cannot be less than `thickness`. @default 160 */
41
41
  size?: number;
42
42
  /** Controls width of segments stroke @default 1 */
43
43
  strokeWidth?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mantine/charts",
3
- "version": "9.6.1",
3
+ "version": "9.6.3",
4
4
  "description": "Charts components built with recharts and Mantine",
5
5
  "homepage": "https://mantine.dev/",
6
6
  "license": "MIT",
@@ -35,8 +35,8 @@
35
35
  "directory": "packages/@mantine/charts"
36
36
  },
37
37
  "peerDependencies": {
38
- "@mantine/core": "9.6.1",
39
- "@mantine/hooks": "9.6.1",
38
+ "@mantine/core": "9.6.3",
39
+ "@mantine/hooks": "9.6.3",
40
40
  "react": "^19.2.0",
41
41
  "react-dom": "^19.2.0",
42
42
  "recharts": ">=3.2.1"