@mantine/charts 9.0.1 → 9.1.0
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.
- package/cjs/Heatmap/Heatmap.cjs +53 -5
- package/cjs/Heatmap/Heatmap.cjs.map +1 -1
- package/cjs/Heatmap/Heatmap.module.cjs +3 -1
- package/cjs/Heatmap/Heatmap.module.cjs.map +1 -1
- package/cjs/Treemap/Treemap.cjs +133 -0
- package/cjs/Treemap/Treemap.cjs.map +1 -0
- package/cjs/Treemap/Treemap.module.cjs +7 -0
- package/cjs/Treemap/Treemap.module.cjs.map +1 -0
- package/cjs/index.cjs +2 -0
- package/esm/Heatmap/Heatmap.mjs +53 -5
- package/esm/Heatmap/Heatmap.mjs.map +1 -1
- package/esm/Heatmap/Heatmap.module.mjs +3 -1
- package/esm/Heatmap/Heatmap.module.mjs.map +1 -1
- package/esm/Treemap/Treemap.mjs +131 -0
- package/esm/Treemap/Treemap.mjs.map +1 -0
- package/esm/Treemap/Treemap.module.mjs +7 -0
- package/esm/Treemap/Treemap.module.mjs.map +1 -0
- package/esm/index.mjs +2 -1
- package/lib/Heatmap/Heatmap.d.ts +5 -1
- package/lib/Treemap/Treemap.d.ts +57 -0
- package/lib/Treemap/index.d.ts +10 -0
- package/lib/index.d.mts +1 -0
- package/lib/index.d.ts +1 -0
- package/package.json +5 -5
- package/styles.css +16 -9
- package/styles.layer.css +16 -9
package/cjs/Heatmap/Heatmap.cjs
CHANGED
|
@@ -49,11 +49,12 @@ const defaultProps = {
|
|
|
49
49
|
"var(--heatmap-level-2)",
|
|
50
50
|
"var(--heatmap-level-3)",
|
|
51
51
|
"var(--heatmap-level-4)"
|
|
52
|
-
]
|
|
52
|
+
],
|
|
53
|
+
legendLabels: ["Less", "More"]
|
|
53
54
|
};
|
|
54
55
|
const Heatmap = (0, _mantine_core.factory)((_props) => {
|
|
55
56
|
const props = (0, _mantine_core.useProps)("Heatmap", defaultProps, _props);
|
|
56
|
-
const { classNames, className, style, styles, unstyled, vars, data, startDate, endDate, withMonthLabels, withWeekdayLabels, weekdayLabels, withOutsideDates, monthLabels, firstDayOfWeek, rectSize = 10, gap = 1, rectRadius, domain, colors, weekdaysLabelsWidth, monthsLabelsHeight, fontSize, getTooltipLabel, withTooltip, tooltipProps, getRectProps, splitMonths, attributes, ...others } = props;
|
|
57
|
+
const { classNames, className, style, styles, unstyled, vars, data, startDate, endDate, withMonthLabels, withWeekdayLabels, weekdayLabels, withOutsideDates, monthLabels, firstDayOfWeek, rectSize = 10, gap = 1, rectRadius, domain, colors, weekdaysLabelsWidth, monthsLabelsHeight, fontSize, getTooltipLabel, withTooltip, tooltipProps, getRectProps, splitMonths, withLegend, legendLabels, attributes, ...others } = props;
|
|
57
58
|
const getStyles = (0, _mantine_core.useStyles)({
|
|
58
59
|
name: "Heatmap",
|
|
59
60
|
classes: require_Heatmap_module.default,
|
|
@@ -126,10 +127,56 @@ const Heatmap = (0, _mantine_core.factory)((_props) => {
|
|
|
126
127
|
children: weekdayLabel
|
|
127
128
|
}, dayIndex)) : null;
|
|
128
129
|
const label = getTooltipLabel && hoveredRect && withTooltip ? getTooltipLabel(hoveredRect) : null;
|
|
130
|
+
const legendPadding = 10;
|
|
131
|
+
const legendHeight = withLegend ? legendPadding + rectSize : 0;
|
|
132
|
+
const svgWidth = rectSizeWithGap * totalColumns + gap + weekdaysOffset;
|
|
133
|
+
const legendNode = withLegend ? (() => {
|
|
134
|
+
const lessLabel = legendLabels[0];
|
|
135
|
+
const moreLabel = legendLabels[1];
|
|
136
|
+
const textGap = 6;
|
|
137
|
+
const charWidth = fontSize * .6;
|
|
138
|
+
const lessWidth = lessLabel.length * charWidth;
|
|
139
|
+
const allColors = [void 0, ...colors || []];
|
|
140
|
+
const rectsWidth = allColors.length * rectSize + (allColors.length - 1) * gap;
|
|
141
|
+
const moreWidth = moreLabel.length * charWidth;
|
|
142
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", {
|
|
143
|
+
transform: `translate(${svgWidth - (lessWidth + textGap + rectsWidth + textGap + moreWidth)}, ${rectSizeWithGap * 7 + gap + monthsOffset + legendPadding})`,
|
|
144
|
+
"data-id": "legend",
|
|
145
|
+
...getStyles("legend"),
|
|
146
|
+
children: [
|
|
147
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("text", {
|
|
148
|
+
x: 0,
|
|
149
|
+
y: rectSize / 2,
|
|
150
|
+
fontSize,
|
|
151
|
+
dominantBaseline: "central",
|
|
152
|
+
...getStyles("legendLabel"),
|
|
153
|
+
children: lessLabel
|
|
154
|
+
}),
|
|
155
|
+
allColors.map((color, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
|
|
156
|
+
x: lessWidth + textGap + i * (rectSize + gap),
|
|
157
|
+
y: 0,
|
|
158
|
+
width: rectSize,
|
|
159
|
+
height: rectSize,
|
|
160
|
+
rx: rectRadius,
|
|
161
|
+
fill: color,
|
|
162
|
+
"data-empty": color === void 0 || void 0,
|
|
163
|
+
...getStyles("legendRect")
|
|
164
|
+
}, i)),
|
|
165
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("text", {
|
|
166
|
+
x: lessWidth + textGap + rectsWidth + textGap,
|
|
167
|
+
y: rectSize / 2,
|
|
168
|
+
fontSize,
|
|
169
|
+
dominantBaseline: "central",
|
|
170
|
+
...getStyles("legendLabel"),
|
|
171
|
+
children: moreLabel
|
|
172
|
+
})
|
|
173
|
+
]
|
|
174
|
+
});
|
|
175
|
+
})() : null;
|
|
129
176
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mantine_core.Box, {
|
|
130
177
|
component: "svg",
|
|
131
|
-
width:
|
|
132
|
-
height: rectSizeWithGap * 7 + gap + monthsOffset,
|
|
178
|
+
width: svgWidth,
|
|
179
|
+
height: rectSizeWithGap * 7 + gap + monthsOffset + legendHeight,
|
|
133
180
|
...getStyles("root"),
|
|
134
181
|
...others,
|
|
135
182
|
children: [
|
|
@@ -149,7 +196,8 @@ const Heatmap = (0, _mantine_core.factory)((_props) => {
|
|
|
149
196
|
})
|
|
150
197
|
}),
|
|
151
198
|
weekdayLabelsNodes,
|
|
152
|
-
monthsLabelsNodes
|
|
199
|
+
monthsLabelsNodes,
|
|
200
|
+
legendNode
|
|
153
201
|
]
|
|
154
202
|
});
|
|
155
203
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Heatmap.cjs","names":["getBoundaries","rotateWeekdaysNames","getDatesRange","getMonthsRange","HeatmapSplitWeeks","HeatmapWeeks","getColumns","getFirstMonthColumnIndex","Box","Tooltip","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 = 'root' | 'rect' | 'weekdayLabel' | 'monthLabel';\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, 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\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 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} 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 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 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 monthsOffset = withMonthLabels ? 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 return (\n <text\n key={monthIndex}\n x={computeMonthLabelX(month.position, monthIndex)}\n y={monthsLabelsHeight - 4}\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 return (\n <Box\n component=\"svg\"\n width={rectSizeWithGap * totalColumns + gap + weekdaysOffset}\n height={rectSizeWithGap * 7 + gap + monthsOffset}\n {...getStyles('root')}\n {...others}\n >\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 </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.cjs","names":["getBoundaries","rotateWeekdaysNames","getDatesRange","getMonthsRange","HeatmapSplitWeeks","HeatmapWeeks","getColumns","getFirstMonthColumnIndex","Box","Tooltip","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, 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 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 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 monthsOffset = withMonthLabels ? 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 return (\n <text\n key={monthIndex}\n x={computeMonthLabelX(month.position, monthIndex)}\n y={monthsLabelsHeight - 4}\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\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 = rectSizeWithGap * 7 + gap + monthsOffset + 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\n component=\"svg\"\n width={svgWidth}\n height={rectSizeWithGap * 7 + gap + monthsOffset + legendHeight}\n {...getStyles('root')}\n {...others}\n >\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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"}
|
|
@@ -4,7 +4,9 @@ var Heatmap_module_default = {
|
|
|
4
4
|
"root": "m_2ef228c3",
|
|
5
5
|
"rect": "m_2ef201c5",
|
|
6
6
|
"monthLabel": "m_7e977775",
|
|
7
|
-
"weekdayLabel": "m_c4b68f8d"
|
|
7
|
+
"weekdayLabel": "m_c4b68f8d",
|
|
8
|
+
"legendLabel": "m_75b4f3e6",
|
|
9
|
+
"legendRect": "m_da847eb2"
|
|
8
10
|
};
|
|
9
11
|
//#endregion
|
|
10
12
|
exports.default = Heatmap_module_default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Heatmap.module.cjs","names":[],"sources":["../../src/Heatmap/Heatmap.module.css"],"sourcesContent":[".root {\n display: block;\n width: fit-content;\n\n @mixin where-light {\n --heatmap-level-1: rgba(81, 207, 102, 0.3);\n --heatmap-level-2: rgba(64, 192, 87, 0.45);\n --heatmap-level-3: rgba(55, 178, 77, 0.75);\n --heatmap-level-4: rgba(43, 138, 62, 1);\n }\n\n @mixin where-dark {\n --heatmap-level-1: rgba(43, 138, 62, 0.3);\n --heatmap-level-2: rgba(47, 158, 68, 0.45);\n --heatmap-level-3: rgba(55, 178, 77, 0.75);\n --heatmap-level-4: rgba(81, 207, 102, 1);\n
|
|
1
|
+
{"version":3,"file":"Heatmap.module.cjs","names":[],"sources":["../../src/Heatmap/Heatmap.module.css"],"sourcesContent":[".root {\n display: block;\n width: fit-content;\n\n @mixin where-light {\n --heatmap-level-1: rgba(81, 207, 102, 0.3);\n --heatmap-level-2: rgba(64, 192, 87, 0.45);\n --heatmap-level-3: rgba(55, 178, 77, 0.75);\n --heatmap-level-4: rgba(43, 138, 62, 1);\n --heatmap-empty-rect-bg: var(--mantine-color-gray-2);\n }\n\n @mixin where-dark {\n --heatmap-level-1: rgba(43, 138, 62, 0.3);\n --heatmap-level-2: rgba(47, 158, 68, 0.45);\n --heatmap-level-3: rgba(55, 178, 77, 0.75);\n --heatmap-level-4: rgba(81, 207, 102, 1);\n --heatmap-empty-rect-bg: var(--mantine-color-dark-5);\n }\n}\n\n.rect {\n stroke-width: 1px;\n\n &:where([data-empty]) {\n fill: var(--heatmap-empty-rect-bg);\n }\n}\n\n.monthLabel,\n.weekdayLabel,\n.legendLabel {\n cursor: default;\n user-select: none;\n fill: var(--mantine-color-dimmed);\n}\n\n.legendRect {\n &:where([data-empty]) {\n fill: var(--heatmap-empty-rect-bg);\n }\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_ChartTooltip = require("../ChartTooltip/ChartTooltip.cjs");
|
|
4
|
+
const require_Treemap_module = require("./Treemap.module.cjs");
|
|
5
|
+
let _mantine_core = require("@mantine/core");
|
|
6
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
7
|
+
let react = require("react");
|
|
8
|
+
react = require_runtime.__toESM(react);
|
|
9
|
+
let recharts = require("recharts");
|
|
10
|
+
//#region packages/@mantine/charts/src/Treemap/Treemap.tsx
|
|
11
|
+
const defaultProps = {
|
|
12
|
+
dataKey: "value",
|
|
13
|
+
withTooltip: true,
|
|
14
|
+
tooltipAnimationDuration: 0,
|
|
15
|
+
height: 300,
|
|
16
|
+
strokeWidth: 1,
|
|
17
|
+
aspectRatio: .5 * (1 + Math.sqrt(5))
|
|
18
|
+
};
|
|
19
|
+
const varsResolver = (0, _mantine_core.createVarsResolver)((theme, { strokeColor, height }) => ({ root: {
|
|
20
|
+
"--chart-stroke-color": strokeColor ? (0, _mantine_core.getThemeColor)(strokeColor, theme) : void 0,
|
|
21
|
+
"--chart-height": (0, _mantine_core.rem)(height)
|
|
22
|
+
} }));
|
|
23
|
+
function TreemapContent({ x, y, width, height, depth, name, resolvedColors, resolvedLabelColors, index, strokeWidth }) {
|
|
24
|
+
const fill = resolvedColors[name] || `var(--mantine-color-blue-${index % 9 + 1})`;
|
|
25
|
+
const labelColor = resolvedLabelColors[name] || "var(--mantine-color-white)";
|
|
26
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
|
|
27
|
+
x,
|
|
28
|
+
y,
|
|
29
|
+
width,
|
|
30
|
+
height,
|
|
31
|
+
fill: depth >= 1 ? fill : "transparent",
|
|
32
|
+
stroke: "var(--chart-stroke-color, var(--mantine-color-body))",
|
|
33
|
+
strokeWidth: depth >= 1 ? strokeWidth : 0
|
|
34
|
+
}), depth >= 1 && width > 30 && height > 20 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("text", {
|
|
35
|
+
x: x + width / 2,
|
|
36
|
+
y: y + height / 2,
|
|
37
|
+
textAnchor: "middle",
|
|
38
|
+
dominantBaseline: "central",
|
|
39
|
+
fill: labelColor,
|
|
40
|
+
fontSize: 12,
|
|
41
|
+
fontFamily: "var(--mantine-font-family)",
|
|
42
|
+
children: name
|
|
43
|
+
})] });
|
|
44
|
+
}
|
|
45
|
+
function resolveColors(data, theme, parentColor) {
|
|
46
|
+
const result = {};
|
|
47
|
+
for (const item of data) {
|
|
48
|
+
const color = item.color || parentColor;
|
|
49
|
+
if (color) result[item.name] = (0, _mantine_core.parseThemeColor)({
|
|
50
|
+
color,
|
|
51
|
+
theme
|
|
52
|
+
}).value;
|
|
53
|
+
if (item.children) Object.assign(result, resolveColors(item.children, theme, color));
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
function resolveLabelColors(resolvedColors, autoContrast, luminanceThreshold, textColor) {
|
|
58
|
+
const result = {};
|
|
59
|
+
for (const [name, color] of Object.entries(resolvedColors)) if (textColor) result[name] = textColor;
|
|
60
|
+
else if (autoContrast) result[name] = (0, _mantine_core.isLightColor)(color, luminanceThreshold) ? "var(--mantine-color-black)" : "var(--mantine-color-white)";
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
const Treemap = (0, _mantine_core.factory)((_props) => {
|
|
64
|
+
const props = (0, _mantine_core.useProps)("Treemap", defaultProps, _props);
|
|
65
|
+
const { classNames, className, style, styles, unstyled, vars, data, dataKey, aspectRatio, withTooltip, tooltipAnimationDuration, tooltipProps, treemapProps, strokeColor, textColor, height: chartHeight, strokeWidth, valueFormatter, autoContrast, children, attributes, ...others } = props;
|
|
66
|
+
const theme = (0, _mantine_core.useMantineTheme)();
|
|
67
|
+
const resolvedColors = resolveColors(data, theme);
|
|
68
|
+
const _autoContrast = (0, _mantine_core.getAutoContrastValue)(autoContrast, theme);
|
|
69
|
+
const _textColor = textColor ? (0, _mantine_core.getThemeColor)(textColor, theme) : void 0;
|
|
70
|
+
const resolvedLabelColors = resolveLabelColors(resolvedColors, _autoContrast, theme.luminanceThreshold, _textColor);
|
|
71
|
+
const getStyles = (0, _mantine_core.useStyles)({
|
|
72
|
+
name: "Treemap",
|
|
73
|
+
classes: require_Treemap_module.default,
|
|
74
|
+
props,
|
|
75
|
+
className,
|
|
76
|
+
style,
|
|
77
|
+
classNames,
|
|
78
|
+
styles,
|
|
79
|
+
unstyled,
|
|
80
|
+
attributes,
|
|
81
|
+
vars,
|
|
82
|
+
varsResolver
|
|
83
|
+
});
|
|
84
|
+
const { resolvedClassNames, resolvedStyles } = (0, _mantine_core.useResolvedStylesApi)({
|
|
85
|
+
classNames,
|
|
86
|
+
styles,
|
|
87
|
+
props
|
|
88
|
+
});
|
|
89
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mantine_core.Box, {
|
|
90
|
+
...getStyles("root"),
|
|
91
|
+
...others,
|
|
92
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(recharts.ResponsiveContainer, {
|
|
93
|
+
height: chartHeight,
|
|
94
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(recharts.Treemap, {
|
|
95
|
+
data,
|
|
96
|
+
dataKey,
|
|
97
|
+
aspectRatio,
|
|
98
|
+
isAnimationActive: false,
|
|
99
|
+
content: (nodeProps) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TreemapContent, {
|
|
100
|
+
...nodeProps,
|
|
101
|
+
resolvedColors,
|
|
102
|
+
resolvedLabelColors,
|
|
103
|
+
strokeWidth
|
|
104
|
+
}),
|
|
105
|
+
...treemapProps,
|
|
106
|
+
children: [withTooltip && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(recharts.Tooltip, {
|
|
107
|
+
animationDuration: tooltipAnimationDuration,
|
|
108
|
+
isAnimationActive: false,
|
|
109
|
+
content: ({ payload }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ChartTooltip.ChartTooltip, {
|
|
110
|
+
payload: payload?.map((item) => ({
|
|
111
|
+
name: item.name,
|
|
112
|
+
value: item.value,
|
|
113
|
+
color: resolvedColors[item.name] || "var(--mantine-color-blue-6)"
|
|
114
|
+
})) || [],
|
|
115
|
+
classNames: resolvedClassNames,
|
|
116
|
+
styles: resolvedStyles,
|
|
117
|
+
type: "radial",
|
|
118
|
+
valueFormatter,
|
|
119
|
+
attributes
|
|
120
|
+
}),
|
|
121
|
+
...tooltipProps
|
|
122
|
+
}), children]
|
|
123
|
+
})
|
|
124
|
+
})
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
Treemap.displayName = "@mantine/charts/Treemap";
|
|
128
|
+
Treemap.classes = require_Treemap_module.default;
|
|
129
|
+
Treemap.varsResolver = varsResolver;
|
|
130
|
+
//#endregion
|
|
131
|
+
exports.Treemap = Treemap;
|
|
132
|
+
|
|
133
|
+
//# sourceMappingURL=Treemap.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Treemap.cjs","names":["Box","ResponsiveContainer","RechartsTreemap","Tooltip","ChartTooltip","classes"],"sources":["../../src/Treemap/Treemap.tsx"],"sourcesContent":["import React from 'react';\nimport {\n Treemap as RechartsTreemap,\n TreemapProps as RechartsTreemapProps,\n ResponsiveContainer,\n Tooltip,\n TooltipProps,\n} from 'recharts';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getAutoContrastValue,\n getThemeColor,\n isLightColor,\n MantineColor,\n MantineTheme,\n parseThemeColor,\n rem,\n StylesApiProps,\n useMantineTheme,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '@mantine/core';\nimport { ChartTooltip, ChartTooltipStylesNames } from '../ChartTooltip/ChartTooltip';\nimport classes from './Treemap.module.css';\n\nexport interface TreemapData {\n name: string;\n value?: number;\n color?: MantineColor;\n children?: TreemapData[];\n [key: string]: unknown;\n}\n\nexport type TreemapStylesNames = 'root' | ChartTooltipStylesNames;\nexport type TreemapCssVariables = {\n root: '--chart-stroke-color' | '--chart-height';\n};\n\nexport interface TreemapProps\n extends BoxProps, StylesApiProps<TreemapFactory>, ElementProps<'div'> {\n /** Data used to render chart */\n data: TreemapData[];\n\n /** Key in data object for the value @default 'value' */\n dataKey?: string;\n\n /** The treemap will try to keep every single rectangle's aspect ratio near the aspectRatio given @default 1.618033988749895 */\n aspectRatio?: number;\n\n /** Determines whether the tooltip should be displayed when a node is hovered @default true */\n withTooltip?: boolean;\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 `Treemap` component */\n treemapProps?: Partial<Omit<RechartsTreemapProps, 'ref' | 'data' | 'dataKey'>>;\n\n /** Controls color of the node stroke, by default depends on color scheme */\n strokeColor?: MantineColor;\n\n /** Controls text color of labels @default dimmed */\n textColor?: MantineColor;\n\n /** Controls chart height @default 300 */\n height?: number;\n\n /** Controls width of node stroke @default 1 */\n strokeWidth?: number;\n\n /** A function to format values inside the tooltip */\n valueFormatter?: (value: number) => string;\n\n /** Determines whether text color should be adjusted based on background color to improve contrast */\n autoContrast?: boolean;\n\n /** Additional elements rendered inside `Treemap` component */\n children?: React.ReactNode;\n}\n\nexport type TreemapFactory = Factory<{\n props: TreemapProps;\n ref: HTMLDivElement;\n stylesNames: TreemapStylesNames;\n vars: TreemapCssVariables;\n}>;\n\nconst defaultProps = {\n dataKey: 'value',\n withTooltip: true,\n tooltipAnimationDuration: 0,\n height: 300,\n strokeWidth: 1,\n aspectRatio: 0.5 * (1 + Math.sqrt(5)),\n} satisfies Partial<TreemapProps>;\n\nconst varsResolver = createVarsResolver<TreemapFactory>((theme, { strokeColor, height }) => ({\n root: {\n '--chart-stroke-color': strokeColor ? getThemeColor(strokeColor, theme) : undefined,\n '--chart-height': rem(height),\n },\n}));\n\ninterface TreemapContentProps {\n x: number;\n y: number;\n width: number;\n height: number;\n depth: number;\n name: string;\n resolvedColors: Record<string, string>;\n resolvedLabelColors: Record<string, string>;\n index: number;\n strokeWidth: number;\n}\n\nfunction TreemapContent({\n x,\n y,\n width,\n height,\n depth,\n name,\n resolvedColors,\n resolvedLabelColors,\n index,\n strokeWidth,\n}: TreemapContentProps) {\n const fill = resolvedColors[name] || `var(--mantine-color-blue-${(index % 9) + 1})`;\n const labelColor = resolvedLabelColors[name] || 'var(--mantine-color-white)';\n const showLabel = width > 30 && height > 20;\n\n return (\n <g>\n <rect\n x={x}\n y={y}\n width={width}\n height={height}\n fill={depth >= 1 ? fill : 'transparent'}\n stroke=\"var(--chart-stroke-color, var(--mantine-color-body))\"\n strokeWidth={depth >= 1 ? strokeWidth : 0}\n />\n {depth >= 1 && showLabel && (\n <text\n x={x + width / 2}\n y={y + height / 2}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fill={labelColor}\n fontSize={12}\n fontFamily=\"var(--mantine-font-family)\"\n >\n {name}\n </text>\n )}\n </g>\n );\n}\n\nfunction resolveColors(\n data: TreemapData[],\n theme: MantineTheme,\n parentColor?: string\n): Record<string, string> {\n const result: Record<string, string> = {};\n for (const item of data) {\n const color = item.color || parentColor;\n if (color) {\n result[item.name] = parseThemeColor({ color, theme }).value;\n }\n if (item.children) {\n Object.assign(result, resolveColors(item.children, theme, color));\n }\n }\n return result;\n}\n\nfunction resolveLabelColors(\n resolvedColors: Record<string, string>,\n autoContrast: boolean,\n luminanceThreshold: number,\n textColor?: string\n): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [name, color] of Object.entries(resolvedColors)) {\n if (textColor) {\n result[name] = textColor;\n } else if (autoContrast) {\n result[name] = isLightColor(color, luminanceThreshold)\n ? 'var(--mantine-color-black)'\n : 'var(--mantine-color-white)';\n }\n }\n return result;\n}\n\nexport const Treemap = factory<TreemapFactory>((_props) => {\n const props = useProps('Treemap', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n data,\n dataKey,\n aspectRatio,\n withTooltip,\n tooltipAnimationDuration,\n tooltipProps,\n treemapProps,\n strokeColor,\n textColor,\n height: chartHeight,\n strokeWidth,\n valueFormatter,\n autoContrast,\n children,\n attributes,\n ...others\n } = props;\n\n const theme = useMantineTheme();\n const resolvedColors = resolveColors(data, theme);\n const _autoContrast = getAutoContrastValue(autoContrast, theme);\n const _textColor = textColor ? getThemeColor(textColor, theme) : undefined;\n const resolvedLabelColors = resolveLabelColors(\n resolvedColors,\n _autoContrast,\n theme.luminanceThreshold,\n _textColor\n );\n\n const getStyles = useStyles<TreemapFactory>({\n name: 'Treemap',\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<TreemapFactory>({\n classNames,\n styles,\n props,\n });\n\n return (\n <Box {...getStyles('root')} {...others}>\n <ResponsiveContainer height={chartHeight}>\n <RechartsTreemap\n data={data as any}\n dataKey={dataKey as any}\n aspectRatio={aspectRatio}\n isAnimationActive={false}\n content={(nodeProps: any) => (\n <TreemapContent\n {...nodeProps}\n resolvedColors={resolvedColors}\n resolvedLabelColors={resolvedLabelColors}\n strokeWidth={strokeWidth!}\n />\n )}\n {...treemapProps}\n >\n {withTooltip && (\n <Tooltip\n animationDuration={tooltipAnimationDuration}\n isAnimationActive={false}\n content={({ payload }) => (\n <ChartTooltip\n payload={\n payload?.map((item) => ({\n name: item.name as string,\n value: item.value as number,\n color: resolvedColors[item.name as string] || 'var(--mantine-color-blue-6)',\n })) || []\n }\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n type=\"radial\"\n valueFormatter={valueFormatter}\n attributes={attributes}\n />\n )}\n {...tooltipProps}\n />\n )}\n\n {children}\n </RechartsTreemap>\n </ResponsiveContainer>\n </Box>\n );\n});\n\nTreemap.displayName = '@mantine/charts/Treemap';\nTreemap.classes = classes;\nTreemap.varsResolver = varsResolver;\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Treemap.module.cjs","names":[],"sources":["../../src/Treemap/Treemap.module.css"],"sourcesContent":[".root {\n min-height: var(--chart-height, auto);\n\n & :where(*) {\n outline: 0;\n }\n}\n"],"mappings":""}
|
package/cjs/index.cjs
CHANGED
|
@@ -17,6 +17,7 @@ const require_RadialBarChart = require("./RadialBarChart/RadialBarChart.cjs");
|
|
|
17
17
|
const require_FunnelChart = require("./FunnelChart/FunnelChart.cjs");
|
|
18
18
|
const require_Heatmap = require("./Heatmap/Heatmap.cjs");
|
|
19
19
|
const require_BarsList = require("./BarsList/BarsList.cjs");
|
|
20
|
+
const require_Treemap = require("./Treemap/Treemap.cjs");
|
|
20
21
|
exports.AreaChart = require_AreaChart.AreaChart;
|
|
21
22
|
exports.AreaGradient = require_AreaGradient.AreaGradient;
|
|
22
23
|
exports.BarChart = require_BarChart.BarChart;
|
|
@@ -34,6 +35,7 @@ exports.RadarChart = require_RadarChart.RadarChart;
|
|
|
34
35
|
exports.RadialBarChart = require_RadialBarChart.RadialBarChart;
|
|
35
36
|
exports.ScatterChart = require_ScatterChart.ScatterChart;
|
|
36
37
|
exports.Sparkline = require_Sparkline.Sparkline;
|
|
38
|
+
exports.Treemap = require_Treemap.Treemap;
|
|
37
39
|
exports.getFilteredChartLegendPayload = require_ChartLegend.getFilteredChartLegendPayload;
|
|
38
40
|
exports.getFilteredChartTooltipPayload = require_ChartTooltip.getFilteredChartTooltipPayload;
|
|
39
41
|
exports.getSplitOffset = require_get_split_offset.getSplitOffset;
|
package/esm/Heatmap/Heatmap.mjs
CHANGED
|
@@ -48,11 +48,12 @@ const defaultProps = {
|
|
|
48
48
|
"var(--heatmap-level-2)",
|
|
49
49
|
"var(--heatmap-level-3)",
|
|
50
50
|
"var(--heatmap-level-4)"
|
|
51
|
-
]
|
|
51
|
+
],
|
|
52
|
+
legendLabels: ["Less", "More"]
|
|
52
53
|
};
|
|
53
54
|
const Heatmap = factory((_props) => {
|
|
54
55
|
const props = useProps("Heatmap", defaultProps, _props);
|
|
55
|
-
const { classNames, className, style, styles, unstyled, vars, data, startDate, endDate, withMonthLabels, withWeekdayLabels, weekdayLabels, withOutsideDates, monthLabels, firstDayOfWeek, rectSize = 10, gap = 1, rectRadius, domain, colors, weekdaysLabelsWidth, monthsLabelsHeight, fontSize, getTooltipLabel, withTooltip, tooltipProps, getRectProps, splitMonths, attributes, ...others } = props;
|
|
56
|
+
const { classNames, className, style, styles, unstyled, vars, data, startDate, endDate, withMonthLabels, withWeekdayLabels, weekdayLabels, withOutsideDates, monthLabels, firstDayOfWeek, rectSize = 10, gap = 1, rectRadius, domain, colors, weekdaysLabelsWidth, monthsLabelsHeight, fontSize, getTooltipLabel, withTooltip, tooltipProps, getRectProps, splitMonths, withLegend, legendLabels, attributes, ...others } = props;
|
|
56
57
|
const getStyles = useStyles({
|
|
57
58
|
name: "Heatmap",
|
|
58
59
|
classes: Heatmap_module_default,
|
|
@@ -125,10 +126,56 @@ const Heatmap = factory((_props) => {
|
|
|
125
126
|
children: weekdayLabel
|
|
126
127
|
}, dayIndex)) : null;
|
|
127
128
|
const label = getTooltipLabel && hoveredRect && withTooltip ? getTooltipLabel(hoveredRect) : null;
|
|
129
|
+
const legendPadding = 10;
|
|
130
|
+
const legendHeight = withLegend ? legendPadding + rectSize : 0;
|
|
131
|
+
const svgWidth = rectSizeWithGap * totalColumns + gap + weekdaysOffset;
|
|
132
|
+
const legendNode = withLegend ? (() => {
|
|
133
|
+
const lessLabel = legendLabels[0];
|
|
134
|
+
const moreLabel = legendLabels[1];
|
|
135
|
+
const textGap = 6;
|
|
136
|
+
const charWidth = fontSize * .6;
|
|
137
|
+
const lessWidth = lessLabel.length * charWidth;
|
|
138
|
+
const allColors = [void 0, ...colors || []];
|
|
139
|
+
const rectsWidth = allColors.length * rectSize + (allColors.length - 1) * gap;
|
|
140
|
+
const moreWidth = moreLabel.length * charWidth;
|
|
141
|
+
return /* @__PURE__ */ jsxs("g", {
|
|
142
|
+
transform: `translate(${svgWidth - (lessWidth + textGap + rectsWidth + textGap + moreWidth)}, ${rectSizeWithGap * 7 + gap + monthsOffset + legendPadding})`,
|
|
143
|
+
"data-id": "legend",
|
|
144
|
+
...getStyles("legend"),
|
|
145
|
+
children: [
|
|
146
|
+
/* @__PURE__ */ jsx("text", {
|
|
147
|
+
x: 0,
|
|
148
|
+
y: rectSize / 2,
|
|
149
|
+
fontSize,
|
|
150
|
+
dominantBaseline: "central",
|
|
151
|
+
...getStyles("legendLabel"),
|
|
152
|
+
children: lessLabel
|
|
153
|
+
}),
|
|
154
|
+
allColors.map((color, i) => /* @__PURE__ */ jsx("rect", {
|
|
155
|
+
x: lessWidth + textGap + i * (rectSize + gap),
|
|
156
|
+
y: 0,
|
|
157
|
+
width: rectSize,
|
|
158
|
+
height: rectSize,
|
|
159
|
+
rx: rectRadius,
|
|
160
|
+
fill: color,
|
|
161
|
+
"data-empty": color === void 0 || void 0,
|
|
162
|
+
...getStyles("legendRect")
|
|
163
|
+
}, i)),
|
|
164
|
+
/* @__PURE__ */ jsx("text", {
|
|
165
|
+
x: lessWidth + textGap + rectsWidth + textGap,
|
|
166
|
+
y: rectSize / 2,
|
|
167
|
+
fontSize,
|
|
168
|
+
dominantBaseline: "central",
|
|
169
|
+
...getStyles("legendLabel"),
|
|
170
|
+
children: moreLabel
|
|
171
|
+
})
|
|
172
|
+
]
|
|
173
|
+
});
|
|
174
|
+
})() : null;
|
|
128
175
|
return /* @__PURE__ */ jsxs(Box, {
|
|
129
176
|
component: "svg",
|
|
130
|
-
width:
|
|
131
|
-
height: rectSizeWithGap * 7 + gap + monthsOffset,
|
|
177
|
+
width: svgWidth,
|
|
178
|
+
height: rectSizeWithGap * 7 + gap + monthsOffset + legendHeight,
|
|
132
179
|
...getStyles("root"),
|
|
133
180
|
...others,
|
|
134
181
|
children: [
|
|
@@ -148,7 +195,8 @@ const Heatmap = factory((_props) => {
|
|
|
148
195
|
})
|
|
149
196
|
}),
|
|
150
197
|
weekdayLabelsNodes,
|
|
151
|
-
monthsLabelsNodes
|
|
198
|
+
monthsLabelsNodes,
|
|
199
|
+
legendNode
|
|
152
200
|
]
|
|
153
201
|
});
|
|
154
202
|
});
|
|
@@ -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 = 'root' | 'rect' | 'weekdayLabel' | 'monthLabel';\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, 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\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 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} 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 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 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 monthsOffset = withMonthLabels ? 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 return (\n <text\n key={monthIndex}\n x={computeMonthLabelX(month.position, monthIndex)}\n y={monthsLabelsHeight - 4}\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 return (\n <Box\n component=\"svg\"\n width={rectSizeWithGap * totalColumns + gap + weekdaysOffset}\n height={rectSizeWithGap * 7 + gap + monthsOffset}\n {...getStyles('root')}\n {...others}\n >\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 </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, 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 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 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 monthsOffset = withMonthLabels ? 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 return (\n <text\n key={monthIndex}\n x={computeMonthLabelX(month.position, monthIndex)}\n y={monthsLabelsHeight - 4}\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\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 = rectSizeWithGap * 7 + gap + monthsOffset + 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\n component=\"svg\"\n width={svgWidth}\n height={rectSizeWithGap * 7 + gap + monthsOffset + legendHeight}\n {...getStyles('root')}\n {...others}\n >\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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"}
|
|
@@ -4,7 +4,9 @@ var Heatmap_module_default = {
|
|
|
4
4
|
"root": "m_2ef228c3",
|
|
5
5
|
"rect": "m_2ef201c5",
|
|
6
6
|
"monthLabel": "m_7e977775",
|
|
7
|
-
"weekdayLabel": "m_c4b68f8d"
|
|
7
|
+
"weekdayLabel": "m_c4b68f8d",
|
|
8
|
+
"legendLabel": "m_75b4f3e6",
|
|
9
|
+
"legendRect": "m_da847eb2"
|
|
8
10
|
};
|
|
9
11
|
//#endregion
|
|
10
12
|
export { Heatmap_module_default as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Heatmap.module.mjs","names":[],"sources":["../../src/Heatmap/Heatmap.module.css"],"sourcesContent":[".root {\n display: block;\n width: fit-content;\n\n @mixin where-light {\n --heatmap-level-1: rgba(81, 207, 102, 0.3);\n --heatmap-level-2: rgba(64, 192, 87, 0.45);\n --heatmap-level-3: rgba(55, 178, 77, 0.75);\n --heatmap-level-4: rgba(43, 138, 62, 1);\n }\n\n @mixin where-dark {\n --heatmap-level-1: rgba(43, 138, 62, 0.3);\n --heatmap-level-2: rgba(47, 158, 68, 0.45);\n --heatmap-level-3: rgba(55, 178, 77, 0.75);\n --heatmap-level-4: rgba(81, 207, 102, 1);\n
|
|
1
|
+
{"version":3,"file":"Heatmap.module.mjs","names":[],"sources":["../../src/Heatmap/Heatmap.module.css"],"sourcesContent":[".root {\n display: block;\n width: fit-content;\n\n @mixin where-light {\n --heatmap-level-1: rgba(81, 207, 102, 0.3);\n --heatmap-level-2: rgba(64, 192, 87, 0.45);\n --heatmap-level-3: rgba(55, 178, 77, 0.75);\n --heatmap-level-4: rgba(43, 138, 62, 1);\n --heatmap-empty-rect-bg: var(--mantine-color-gray-2);\n }\n\n @mixin where-dark {\n --heatmap-level-1: rgba(43, 138, 62, 0.3);\n --heatmap-level-2: rgba(47, 158, 68, 0.45);\n --heatmap-level-3: rgba(55, 178, 77, 0.75);\n --heatmap-level-4: rgba(81, 207, 102, 1);\n --heatmap-empty-rect-bg: var(--mantine-color-dark-5);\n }\n}\n\n.rect {\n stroke-width: 1px;\n\n &:where([data-empty]) {\n fill: var(--heatmap-empty-rect-bg);\n }\n}\n\n.monthLabel,\n.weekdayLabel,\n.legendLabel {\n cursor: default;\n user-select: none;\n fill: var(--mantine-color-dimmed);\n}\n\n.legendRect {\n &:where([data-empty]) {\n fill: var(--heatmap-empty-rect-bg);\n }\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { ChartTooltip } from "../ChartTooltip/ChartTooltip.mjs";
|
|
3
|
+
import Treemap_module_default from "./Treemap.module.mjs";
|
|
4
|
+
import { Box, createVarsResolver, factory, getAutoContrastValue, getThemeColor, isLightColor, parseThemeColor, rem, useMantineTheme, useProps, useResolvedStylesApi, useStyles } from "@mantine/core";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import "react";
|
|
7
|
+
import { ResponsiveContainer, Tooltip as Tooltip$1, Treemap } from "recharts";
|
|
8
|
+
//#region packages/@mantine/charts/src/Treemap/Treemap.tsx
|
|
9
|
+
const defaultProps = {
|
|
10
|
+
dataKey: "value",
|
|
11
|
+
withTooltip: true,
|
|
12
|
+
tooltipAnimationDuration: 0,
|
|
13
|
+
height: 300,
|
|
14
|
+
strokeWidth: 1,
|
|
15
|
+
aspectRatio: .5 * (1 + Math.sqrt(5))
|
|
16
|
+
};
|
|
17
|
+
const varsResolver = createVarsResolver((theme, { strokeColor, height }) => ({ root: {
|
|
18
|
+
"--chart-stroke-color": strokeColor ? getThemeColor(strokeColor, theme) : void 0,
|
|
19
|
+
"--chart-height": rem(height)
|
|
20
|
+
} }));
|
|
21
|
+
function TreemapContent({ x, y, width, height, depth, name, resolvedColors, resolvedLabelColors, index, strokeWidth }) {
|
|
22
|
+
const fill = resolvedColors[name] || `var(--mantine-color-blue-${index % 9 + 1})`;
|
|
23
|
+
const labelColor = resolvedLabelColors[name] || "var(--mantine-color-white)";
|
|
24
|
+
return /* @__PURE__ */ jsxs("g", { children: [/* @__PURE__ */ jsx("rect", {
|
|
25
|
+
x,
|
|
26
|
+
y,
|
|
27
|
+
width,
|
|
28
|
+
height,
|
|
29
|
+
fill: depth >= 1 ? fill : "transparent",
|
|
30
|
+
stroke: "var(--chart-stroke-color, var(--mantine-color-body))",
|
|
31
|
+
strokeWidth: depth >= 1 ? strokeWidth : 0
|
|
32
|
+
}), depth >= 1 && width > 30 && height > 20 && /* @__PURE__ */ jsx("text", {
|
|
33
|
+
x: x + width / 2,
|
|
34
|
+
y: y + height / 2,
|
|
35
|
+
textAnchor: "middle",
|
|
36
|
+
dominantBaseline: "central",
|
|
37
|
+
fill: labelColor,
|
|
38
|
+
fontSize: 12,
|
|
39
|
+
fontFamily: "var(--mantine-font-family)",
|
|
40
|
+
children: name
|
|
41
|
+
})] });
|
|
42
|
+
}
|
|
43
|
+
function resolveColors(data, theme, parentColor) {
|
|
44
|
+
const result = {};
|
|
45
|
+
for (const item of data) {
|
|
46
|
+
const color = item.color || parentColor;
|
|
47
|
+
if (color) result[item.name] = parseThemeColor({
|
|
48
|
+
color,
|
|
49
|
+
theme
|
|
50
|
+
}).value;
|
|
51
|
+
if (item.children) Object.assign(result, resolveColors(item.children, theme, color));
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
function resolveLabelColors(resolvedColors, autoContrast, luminanceThreshold, textColor) {
|
|
56
|
+
const result = {};
|
|
57
|
+
for (const [name, color] of Object.entries(resolvedColors)) if (textColor) result[name] = textColor;
|
|
58
|
+
else if (autoContrast) result[name] = isLightColor(color, luminanceThreshold) ? "var(--mantine-color-black)" : "var(--mantine-color-white)";
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
const Treemap$1 = factory((_props) => {
|
|
62
|
+
const props = useProps("Treemap", defaultProps, _props);
|
|
63
|
+
const { classNames, className, style, styles, unstyled, vars, data, dataKey, aspectRatio, withTooltip, tooltipAnimationDuration, tooltipProps, treemapProps, strokeColor, textColor, height: chartHeight, strokeWidth, valueFormatter, autoContrast, children, attributes, ...others } = props;
|
|
64
|
+
const theme = useMantineTheme();
|
|
65
|
+
const resolvedColors = resolveColors(data, theme);
|
|
66
|
+
const _autoContrast = getAutoContrastValue(autoContrast, theme);
|
|
67
|
+
const _textColor = textColor ? getThemeColor(textColor, theme) : void 0;
|
|
68
|
+
const resolvedLabelColors = resolveLabelColors(resolvedColors, _autoContrast, theme.luminanceThreshold, _textColor);
|
|
69
|
+
const getStyles = useStyles({
|
|
70
|
+
name: "Treemap",
|
|
71
|
+
classes: Treemap_module_default,
|
|
72
|
+
props,
|
|
73
|
+
className,
|
|
74
|
+
style,
|
|
75
|
+
classNames,
|
|
76
|
+
styles,
|
|
77
|
+
unstyled,
|
|
78
|
+
attributes,
|
|
79
|
+
vars,
|
|
80
|
+
varsResolver
|
|
81
|
+
});
|
|
82
|
+
const { resolvedClassNames, resolvedStyles } = useResolvedStylesApi({
|
|
83
|
+
classNames,
|
|
84
|
+
styles,
|
|
85
|
+
props
|
|
86
|
+
});
|
|
87
|
+
return /* @__PURE__ */ jsx(Box, {
|
|
88
|
+
...getStyles("root"),
|
|
89
|
+
...others,
|
|
90
|
+
children: /* @__PURE__ */ jsx(ResponsiveContainer, {
|
|
91
|
+
height: chartHeight,
|
|
92
|
+
children: /* @__PURE__ */ jsxs(Treemap, {
|
|
93
|
+
data,
|
|
94
|
+
dataKey,
|
|
95
|
+
aspectRatio,
|
|
96
|
+
isAnimationActive: false,
|
|
97
|
+
content: (nodeProps) => /* @__PURE__ */ jsx(TreemapContent, {
|
|
98
|
+
...nodeProps,
|
|
99
|
+
resolvedColors,
|
|
100
|
+
resolvedLabelColors,
|
|
101
|
+
strokeWidth
|
|
102
|
+
}),
|
|
103
|
+
...treemapProps,
|
|
104
|
+
children: [withTooltip && /* @__PURE__ */ jsx(Tooltip$1, {
|
|
105
|
+
animationDuration: tooltipAnimationDuration,
|
|
106
|
+
isAnimationActive: false,
|
|
107
|
+
content: ({ payload }) => /* @__PURE__ */ jsx(ChartTooltip, {
|
|
108
|
+
payload: payload?.map((item) => ({
|
|
109
|
+
name: item.name,
|
|
110
|
+
value: item.value,
|
|
111
|
+
color: resolvedColors[item.name] || "var(--mantine-color-blue-6)"
|
|
112
|
+
})) || [],
|
|
113
|
+
classNames: resolvedClassNames,
|
|
114
|
+
styles: resolvedStyles,
|
|
115
|
+
type: "radial",
|
|
116
|
+
valueFormatter,
|
|
117
|
+
attributes
|
|
118
|
+
}),
|
|
119
|
+
...tooltipProps
|
|
120
|
+
}), children]
|
|
121
|
+
})
|
|
122
|
+
})
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
Treemap$1.displayName = "@mantine/charts/Treemap";
|
|
126
|
+
Treemap$1.classes = Treemap_module_default;
|
|
127
|
+
Treemap$1.varsResolver = varsResolver;
|
|
128
|
+
//#endregion
|
|
129
|
+
export { Treemap$1 as Treemap };
|
|
130
|
+
|
|
131
|
+
//# sourceMappingURL=Treemap.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Treemap.mjs","names":["Treemap","RechartsTreemap","Tooltip","classes"],"sources":["../../src/Treemap/Treemap.tsx"],"sourcesContent":["import React from 'react';\nimport {\n Treemap as RechartsTreemap,\n TreemapProps as RechartsTreemapProps,\n ResponsiveContainer,\n Tooltip,\n TooltipProps,\n} from 'recharts';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getAutoContrastValue,\n getThemeColor,\n isLightColor,\n MantineColor,\n MantineTheme,\n parseThemeColor,\n rem,\n StylesApiProps,\n useMantineTheme,\n useProps,\n useResolvedStylesApi,\n useStyles,\n} from '@mantine/core';\nimport { ChartTooltip, ChartTooltipStylesNames } from '../ChartTooltip/ChartTooltip';\nimport classes from './Treemap.module.css';\n\nexport interface TreemapData {\n name: string;\n value?: number;\n color?: MantineColor;\n children?: TreemapData[];\n [key: string]: unknown;\n}\n\nexport type TreemapStylesNames = 'root' | ChartTooltipStylesNames;\nexport type TreemapCssVariables = {\n root: '--chart-stroke-color' | '--chart-height';\n};\n\nexport interface TreemapProps\n extends BoxProps, StylesApiProps<TreemapFactory>, ElementProps<'div'> {\n /** Data used to render chart */\n data: TreemapData[];\n\n /** Key in data object for the value @default 'value' */\n dataKey?: string;\n\n /** The treemap will try to keep every single rectangle's aspect ratio near the aspectRatio given @default 1.618033988749895 */\n aspectRatio?: number;\n\n /** Determines whether the tooltip should be displayed when a node is hovered @default true */\n withTooltip?: boolean;\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 `Treemap` component */\n treemapProps?: Partial<Omit<RechartsTreemapProps, 'ref' | 'data' | 'dataKey'>>;\n\n /** Controls color of the node stroke, by default depends on color scheme */\n strokeColor?: MantineColor;\n\n /** Controls text color of labels @default dimmed */\n textColor?: MantineColor;\n\n /** Controls chart height @default 300 */\n height?: number;\n\n /** Controls width of node stroke @default 1 */\n strokeWidth?: number;\n\n /** A function to format values inside the tooltip */\n valueFormatter?: (value: number) => string;\n\n /** Determines whether text color should be adjusted based on background color to improve contrast */\n autoContrast?: boolean;\n\n /** Additional elements rendered inside `Treemap` component */\n children?: React.ReactNode;\n}\n\nexport type TreemapFactory = Factory<{\n props: TreemapProps;\n ref: HTMLDivElement;\n stylesNames: TreemapStylesNames;\n vars: TreemapCssVariables;\n}>;\n\nconst defaultProps = {\n dataKey: 'value',\n withTooltip: true,\n tooltipAnimationDuration: 0,\n height: 300,\n strokeWidth: 1,\n aspectRatio: 0.5 * (1 + Math.sqrt(5)),\n} satisfies Partial<TreemapProps>;\n\nconst varsResolver = createVarsResolver<TreemapFactory>((theme, { strokeColor, height }) => ({\n root: {\n '--chart-stroke-color': strokeColor ? getThemeColor(strokeColor, theme) : undefined,\n '--chart-height': rem(height),\n },\n}));\n\ninterface TreemapContentProps {\n x: number;\n y: number;\n width: number;\n height: number;\n depth: number;\n name: string;\n resolvedColors: Record<string, string>;\n resolvedLabelColors: Record<string, string>;\n index: number;\n strokeWidth: number;\n}\n\nfunction TreemapContent({\n x,\n y,\n width,\n height,\n depth,\n name,\n resolvedColors,\n resolvedLabelColors,\n index,\n strokeWidth,\n}: TreemapContentProps) {\n const fill = resolvedColors[name] || `var(--mantine-color-blue-${(index % 9) + 1})`;\n const labelColor = resolvedLabelColors[name] || 'var(--mantine-color-white)';\n const showLabel = width > 30 && height > 20;\n\n return (\n <g>\n <rect\n x={x}\n y={y}\n width={width}\n height={height}\n fill={depth >= 1 ? fill : 'transparent'}\n stroke=\"var(--chart-stroke-color, var(--mantine-color-body))\"\n strokeWidth={depth >= 1 ? strokeWidth : 0}\n />\n {depth >= 1 && showLabel && (\n <text\n x={x + width / 2}\n y={y + height / 2}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fill={labelColor}\n fontSize={12}\n fontFamily=\"var(--mantine-font-family)\"\n >\n {name}\n </text>\n )}\n </g>\n );\n}\n\nfunction resolveColors(\n data: TreemapData[],\n theme: MantineTheme,\n parentColor?: string\n): Record<string, string> {\n const result: Record<string, string> = {};\n for (const item of data) {\n const color = item.color || parentColor;\n if (color) {\n result[item.name] = parseThemeColor({ color, theme }).value;\n }\n if (item.children) {\n Object.assign(result, resolveColors(item.children, theme, color));\n }\n }\n return result;\n}\n\nfunction resolveLabelColors(\n resolvedColors: Record<string, string>,\n autoContrast: boolean,\n luminanceThreshold: number,\n textColor?: string\n): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [name, color] of Object.entries(resolvedColors)) {\n if (textColor) {\n result[name] = textColor;\n } else if (autoContrast) {\n result[name] = isLightColor(color, luminanceThreshold)\n ? 'var(--mantine-color-black)'\n : 'var(--mantine-color-white)';\n }\n }\n return result;\n}\n\nexport const Treemap = factory<TreemapFactory>((_props) => {\n const props = useProps('Treemap', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n data,\n dataKey,\n aspectRatio,\n withTooltip,\n tooltipAnimationDuration,\n tooltipProps,\n treemapProps,\n strokeColor,\n textColor,\n height: chartHeight,\n strokeWidth,\n valueFormatter,\n autoContrast,\n children,\n attributes,\n ...others\n } = props;\n\n const theme = useMantineTheme();\n const resolvedColors = resolveColors(data, theme);\n const _autoContrast = getAutoContrastValue(autoContrast, theme);\n const _textColor = textColor ? getThemeColor(textColor, theme) : undefined;\n const resolvedLabelColors = resolveLabelColors(\n resolvedColors,\n _autoContrast,\n theme.luminanceThreshold,\n _textColor\n );\n\n const getStyles = useStyles<TreemapFactory>({\n name: 'Treemap',\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<TreemapFactory>({\n classNames,\n styles,\n props,\n });\n\n return (\n <Box {...getStyles('root')} {...others}>\n <ResponsiveContainer height={chartHeight}>\n <RechartsTreemap\n data={data as any}\n dataKey={dataKey as any}\n aspectRatio={aspectRatio}\n isAnimationActive={false}\n content={(nodeProps: any) => (\n <TreemapContent\n {...nodeProps}\n resolvedColors={resolvedColors}\n resolvedLabelColors={resolvedLabelColors}\n strokeWidth={strokeWidth!}\n />\n )}\n {...treemapProps}\n >\n {withTooltip && (\n <Tooltip\n animationDuration={tooltipAnimationDuration}\n isAnimationActive={false}\n content={({ payload }) => (\n <ChartTooltip\n payload={\n payload?.map((item) => ({\n name: item.name as string,\n value: item.value as number,\n color: resolvedColors[item.name as string] || 'var(--mantine-color-blue-6)',\n })) || []\n }\n classNames={resolvedClassNames}\n styles={resolvedStyles}\n type=\"radial\"\n valueFormatter={valueFormatter}\n attributes={attributes}\n />\n )}\n {...tooltipProps}\n />\n )}\n\n {children}\n </RechartsTreemap>\n </ResponsiveContainer>\n </Box>\n );\n});\n\nTreemap.displayName = '@mantine/charts/Treemap';\nTreemap.classes = classes;\nTreemap.varsResolver = varsResolver;\n"],"mappings":";;;;;;;;AAgGA,MAAM,eAAe;CACnB,SAAS;CACT,aAAa;CACb,0BAA0B;CAC1B,QAAQ;CACR,aAAa;CACb,aAAa,MAAO,IAAI,KAAK,KAAK,EAAE;CACrC;AAED,MAAM,eAAe,oBAAoC,OAAO,EAAE,aAAa,cAAc,EAC3F,MAAM;CACJ,wBAAwB,cAAc,cAAc,aAAa,MAAM,GAAG,KAAA;CAC1E,kBAAkB,IAAI,OAAO;CAC9B,EACF,EAAE;AAeH,SAAS,eAAe,EACtB,GACA,GACA,OACA,QACA,OACA,MACA,gBACA,qBACA,OACA,eACsB;CACtB,MAAM,OAAO,eAAe,SAAS,4BAA6B,QAAQ,IAAK,EAAE;CACjF,MAAM,aAAa,oBAAoB,SAAS;AAGhD,QACE,qBAAC,KAAD,EAAA,UAAA,CACE,oBAAC,QAAD;EACK;EACA;EACI;EACC;EACR,MAAM,SAAS,IAAI,OAAO;EAC1B,QAAO;EACP,aAAa,SAAS,IAAI,cAAc;EACxC,CAAA,EACD,SAAS,KAbI,QAAQ,MAAM,SAAS,MAcnC,oBAAC,QAAD;EACE,GAAG,IAAI,QAAQ;EACf,GAAG,IAAI,SAAS;EAChB,YAAW;EACX,kBAAiB;EACjB,MAAM;EACN,UAAU;EACV,YAAW;YAEV;EACI,CAAA,CAEP,EAAA,CAAA;;AAIR,SAAS,cACP,MACA,OACA,aACwB;CACxB,MAAM,SAAiC,EAAE;AACzC,MAAK,MAAM,QAAQ,MAAM;EACvB,MAAM,QAAQ,KAAK,SAAS;AAC5B,MAAI,MACF,QAAO,KAAK,QAAQ,gBAAgB;GAAE;GAAO;GAAO,CAAC,CAAC;AAExD,MAAI,KAAK,SACP,QAAO,OAAO,QAAQ,cAAc,KAAK,UAAU,OAAO,MAAM,CAAC;;AAGrE,QAAO;;AAGT,SAAS,mBACP,gBACA,cACA,oBACA,WACwB;CACxB,MAAM,SAAiC,EAAE;AACzC,MAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,eAAe,CACxD,KAAI,UACF,QAAO,QAAQ;UACN,aACT,QAAO,QAAQ,aAAa,OAAO,mBAAmB,GAClD,+BACA;AAGR,QAAO;;AAGT,MAAaA,YAAU,SAAyB,WAAW;CACzD,MAAM,QAAQ,SAAS,WAAW,cAAc,OAAO;CACvD,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,MACA,MACA,SACA,aACA,aACA,0BACA,cACA,cACA,aACA,WACA,QAAQ,aACR,aACA,gBACA,cACA,UACA,YACA,GAAG,WACD;CAEJ,MAAM,QAAQ,iBAAiB;CAC/B,MAAM,iBAAiB,cAAc,MAAM,MAAM;CACjD,MAAM,gBAAgB,qBAAqB,cAAc,MAAM;CAC/D,MAAM,aAAa,YAAY,cAAc,WAAW,MAAM,GAAG,KAAA;CACjE,MAAM,sBAAsB,mBAC1B,gBACA,eACA,MAAM,oBACN,WACD;CAED,MAAM,YAAY,UAA0B;EAC1C,MAAM;EACN,SAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,EAAE,oBAAoB,mBAAmB,qBAAqC;EAClF;EACA;EACA;EACD,CAAC;AAEF,QACE,oBAAC,KAAD;EAAK,GAAI,UAAU,OAAO;EAAE,GAAI;YAC9B,oBAAC,qBAAD;GAAqB,QAAQ;aAC3B,qBAACC,SAAD;IACQ;IACG;IACI;IACb,mBAAmB;IACnB,UAAU,cACR,oBAAC,gBAAD;KACE,GAAI;KACY;KACK;KACR;KACb,CAAA;IAEJ,GAAI;cAbN,CAeG,eACC,oBAACC,WAAD;KACE,mBAAmB;KACnB,mBAAmB;KACnB,UAAU,EAAE,cACV,oBAAC,cAAD;MACE,SACE,SAAS,KAAK,UAAU;OACtB,MAAM,KAAK;OACX,OAAO,KAAK;OACZ,OAAO,eAAe,KAAK,SAAmB;OAC/C,EAAE,IAAI,EAAE;MAEX,YAAY;MACZ,QAAQ;MACR,MAAK;MACW;MACJ;MACZ,CAAA;KAEJ,GAAI;KACJ,CAAA,EAGH,SACe;;GACE,CAAA;EAClB,CAAA;EAER;AAEF,UAAQ,cAAc;AACtB,UAAQ,UAAUC;AAClB,UAAQ,eAAe"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Treemap.module.mjs","names":[],"sources":["../../src/Treemap/Treemap.module.css"],"sourcesContent":[".root {\n min-height: var(--chart-height, auto);\n\n & :where(*) {\n outline: 0;\n }\n}\n"],"mappings":""}
|
package/esm/index.mjs
CHANGED
|
@@ -16,4 +16,5 @@ import { RadialBarChart } from "./RadialBarChart/RadialBarChart.mjs";
|
|
|
16
16
|
import { FunnelChart } from "./FunnelChart/FunnelChart.mjs";
|
|
17
17
|
import { Heatmap } from "./Heatmap/Heatmap.mjs";
|
|
18
18
|
import { BarsList } from "./BarsList/BarsList.mjs";
|
|
19
|
-
|
|
19
|
+
import { Treemap } from "./Treemap/Treemap.mjs";
|
|
20
|
+
export { AreaChart, AreaGradient, BarChart, BarsList, BubbleChart, ChartLegend, ChartTooltip, CompositeChart, DonutChart, FunnelChart, Heatmap, LineChart, PieChart, RadarChart, RadialBarChart, ScatterChart, Sparkline, Treemap, getFilteredChartLegendPayload, getFilteredChartTooltipPayload, getSplitOffset };
|
package/lib/Heatmap/Heatmap.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BoxProps, ElementProps, Factory, StylesApiProps, TooltipFloatingProps } from '@mantine/core';
|
|
2
|
-
export type HeatmapStylesNames = 'root' | 'rect' | 'weekdayLabel' | 'monthLabel';
|
|
2
|
+
export type HeatmapStylesNames = 'root' | 'rect' | 'weekdayLabel' | 'monthLabel' | 'legend' | 'legendLabel' | 'legendRect';
|
|
3
3
|
interface HeatmapRectData {
|
|
4
4
|
date: string;
|
|
5
5
|
value: number | null;
|
|
@@ -49,6 +49,10 @@ export interface HeatmapProps extends BoxProps, StylesApiProps<HeatmapFactory>,
|
|
|
49
49
|
getRectProps?: (input: HeatmapRectData) => React.ComponentProps<'rect'>;
|
|
50
50
|
/** If set, inserts a spacer column between months @default false */
|
|
51
51
|
splitMonths?: boolean;
|
|
52
|
+
/** If set, legend with color levels is displayed below the heatmap @default false */
|
|
53
|
+
withLegend?: boolean;
|
|
54
|
+
/** Legend labels, array of 2 elements: [min label, max label] @default ['Less', 'More'] */
|
|
55
|
+
legendLabels?: [string, string];
|
|
52
56
|
}
|
|
53
57
|
export type HeatmapFactory = Factory<{
|
|
54
58
|
props: HeatmapProps;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { TreemapProps as RechartsTreemapProps, TooltipProps } from 'recharts';
|
|
3
|
+
import { BoxProps, ElementProps, Factory, MantineColor, StylesApiProps } from '@mantine/core';
|
|
4
|
+
import { ChartTooltipStylesNames } from '../ChartTooltip/ChartTooltip';
|
|
5
|
+
export interface TreemapData {
|
|
6
|
+
name: string;
|
|
7
|
+
value?: number;
|
|
8
|
+
color?: MantineColor;
|
|
9
|
+
children?: TreemapData[];
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
export type TreemapStylesNames = 'root' | ChartTooltipStylesNames;
|
|
13
|
+
export type TreemapCssVariables = {
|
|
14
|
+
root: '--chart-stroke-color' | '--chart-height';
|
|
15
|
+
};
|
|
16
|
+
export interface TreemapProps extends BoxProps, StylesApiProps<TreemapFactory>, ElementProps<'div'> {
|
|
17
|
+
/** Data used to render chart */
|
|
18
|
+
data: TreemapData[];
|
|
19
|
+
/** Key in data object for the value @default 'value' */
|
|
20
|
+
dataKey?: string;
|
|
21
|
+
/** The treemap will try to keep every single rectangle's aspect ratio near the aspectRatio given @default 1.618033988749895 */
|
|
22
|
+
aspectRatio?: number;
|
|
23
|
+
/** Determines whether the tooltip should be displayed when a node is hovered @default true */
|
|
24
|
+
withTooltip?: boolean;
|
|
25
|
+
/** Tooltip animation duration in ms @default 0 */
|
|
26
|
+
tooltipAnimationDuration?: number;
|
|
27
|
+
/** Props passed down to `Tooltip` recharts component */
|
|
28
|
+
tooltipProps?: Omit<TooltipProps<any, any>, 'ref'>;
|
|
29
|
+
/** Props passed down to recharts `Treemap` component */
|
|
30
|
+
treemapProps?: Partial<Omit<RechartsTreemapProps, 'ref' | 'data' | 'dataKey'>>;
|
|
31
|
+
/** Controls color of the node stroke, by default depends on color scheme */
|
|
32
|
+
strokeColor?: MantineColor;
|
|
33
|
+
/** Controls text color of labels @default dimmed */
|
|
34
|
+
textColor?: MantineColor;
|
|
35
|
+
/** Controls chart height @default 300 */
|
|
36
|
+
height?: number;
|
|
37
|
+
/** Controls width of node stroke @default 1 */
|
|
38
|
+
strokeWidth?: number;
|
|
39
|
+
/** A function to format values inside the tooltip */
|
|
40
|
+
valueFormatter?: (value: number) => string;
|
|
41
|
+
/** Determines whether text color should be adjusted based on background color to improve contrast */
|
|
42
|
+
autoContrast?: boolean;
|
|
43
|
+
/** Additional elements rendered inside `Treemap` component */
|
|
44
|
+
children?: React.ReactNode;
|
|
45
|
+
}
|
|
46
|
+
export type TreemapFactory = Factory<{
|
|
47
|
+
props: TreemapProps;
|
|
48
|
+
ref: HTMLDivElement;
|
|
49
|
+
stylesNames: TreemapStylesNames;
|
|
50
|
+
vars: TreemapCssVariables;
|
|
51
|
+
}>;
|
|
52
|
+
export declare const Treemap: import("@mantine/core").MantineComponent<{
|
|
53
|
+
props: TreemapProps;
|
|
54
|
+
ref: HTMLDivElement;
|
|
55
|
+
stylesNames: TreemapStylesNames;
|
|
56
|
+
vars: TreemapCssVariables;
|
|
57
|
+
}>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TreemapCssVariables, TreemapData, TreemapFactory, TreemapProps, TreemapStylesNames } from './Treemap';
|
|
2
|
+
export { Treemap } from './Treemap';
|
|
3
|
+
export type { TreemapProps, TreemapStylesNames, TreemapCssVariables, TreemapFactory, TreemapData };
|
|
4
|
+
export declare namespace Treemap {
|
|
5
|
+
type Props = TreemapProps;
|
|
6
|
+
type StylesNames = TreemapStylesNames;
|
|
7
|
+
type CssVariables = TreemapCssVariables;
|
|
8
|
+
type Factory = TreemapFactory;
|
|
9
|
+
type Data = TreemapData;
|
|
10
|
+
}
|
package/lib/index.d.mts
CHANGED
package/lib/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mantine/charts",
|
|
3
|
-
"version": "9.0
|
|
3
|
+
"version": "9.1.0",
|
|
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.0
|
|
39
|
-
"@mantine/hooks": "9.0
|
|
38
|
+
"@mantine/core": "9.1.0",
|
|
39
|
+
"@mantine/hooks": "9.1.0",
|
|
40
40
|
"react": "^19.2.0",
|
|
41
41
|
"react-dom": "^19.2.0",
|
|
42
42
|
"recharts": ">=3.2.1"
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@mantine-tests/core": "workspace:*",
|
|
46
46
|
"@mantine/core": "workspace:*",
|
|
47
47
|
"@mantine/hooks": "workspace:*",
|
|
48
|
-
"react": "19.2.
|
|
49
|
-
"react-dom": "19.2.
|
|
48
|
+
"react": "19.2.5",
|
|
49
|
+
"react-dom": "19.2.5"
|
|
50
50
|
}
|
|
51
51
|
}
|
package/styles.css
CHANGED
|
@@ -293,6 +293,7 @@
|
|
|
293
293
|
--heatmap-level-2: rgba(64, 192, 87, 0.45);
|
|
294
294
|
--heatmap-level-3: rgba(55, 178, 77, 0.75);
|
|
295
295
|
--heatmap-level-4: rgba(43, 138, 62, 1);
|
|
296
|
+
--heatmap-empty-rect-bg: var(--mantine-color-gray-2);
|
|
296
297
|
}
|
|
297
298
|
|
|
298
299
|
:where([data-mantine-color-scheme='dark']) .m_2ef228c3 {
|
|
@@ -300,31 +301,29 @@
|
|
|
300
301
|
--heatmap-level-2: rgba(47, 158, 68, 0.45);
|
|
301
302
|
--heatmap-level-3: rgba(55, 178, 77, 0.75);
|
|
302
303
|
--heatmap-level-4: rgba(81, 207, 102, 1);
|
|
304
|
+
--heatmap-empty-rect-bg: var(--mantine-color-dark-5);
|
|
303
305
|
}
|
|
304
306
|
|
|
305
307
|
.m_2ef201c5 {
|
|
306
308
|
stroke-width: calc(0.0625rem * var(--mantine-scale));
|
|
307
309
|
}
|
|
308
310
|
|
|
309
|
-
:where([data-mantine-color-scheme='light']) .m_2ef201c5 {
|
|
310
|
-
--heatmap-empty-rect-bg: var(--mantine-color-gray-2);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
:where([data-mantine-color-scheme='dark']) .m_2ef201c5 {
|
|
314
|
-
--heatmap-empty-rect-bg: var(--mantine-color-dark-5);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
311
|
.m_2ef201c5:where([data-empty]) {
|
|
318
312
|
fill: var(--heatmap-empty-rect-bg);
|
|
319
313
|
}
|
|
320
314
|
|
|
321
315
|
.m_7e977775,
|
|
322
|
-
.m_c4b68f8d
|
|
316
|
+
.m_c4b68f8d,
|
|
317
|
+
.m_75b4f3e6 {
|
|
323
318
|
cursor: default;
|
|
324
319
|
user-select: none;
|
|
325
320
|
fill: var(--mantine-color-dimmed);
|
|
326
321
|
}
|
|
327
322
|
|
|
323
|
+
.m_da847eb2:where([data-empty]) {
|
|
324
|
+
fill: var(--heatmap-empty-rect-bg);
|
|
325
|
+
}
|
|
326
|
+
|
|
328
327
|
.m_1ea785b1 {
|
|
329
328
|
display: flex;
|
|
330
329
|
flex-direction: column;
|
|
@@ -374,3 +373,11 @@
|
|
|
374
373
|
white-space: nowrap;
|
|
375
374
|
color: var(--mantine-color-text);
|
|
376
375
|
}
|
|
376
|
+
|
|
377
|
+
.m_3c064071 {
|
|
378
|
+
min-height: var(--chart-height, auto);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.m_3c064071 :where(*) {
|
|
382
|
+
outline: 0;
|
|
383
|
+
}
|
package/styles.layer.css
CHANGED
|
@@ -293,6 +293,7 @@
|
|
|
293
293
|
--heatmap-level-2: rgba(64, 192, 87, 0.45);
|
|
294
294
|
--heatmap-level-3: rgba(55, 178, 77, 0.75);
|
|
295
295
|
--heatmap-level-4: rgba(43, 138, 62, 1);
|
|
296
|
+
--heatmap-empty-rect-bg: var(--mantine-color-gray-2);
|
|
296
297
|
}
|
|
297
298
|
|
|
298
299
|
:where([data-mantine-color-scheme='dark']) .m_2ef228c3 {
|
|
@@ -300,31 +301,29 @@
|
|
|
300
301
|
--heatmap-level-2: rgba(47, 158, 68, 0.45);
|
|
301
302
|
--heatmap-level-3: rgba(55, 178, 77, 0.75);
|
|
302
303
|
--heatmap-level-4: rgba(81, 207, 102, 1);
|
|
304
|
+
--heatmap-empty-rect-bg: var(--mantine-color-dark-5);
|
|
303
305
|
}
|
|
304
306
|
|
|
305
307
|
.m_2ef201c5 {
|
|
306
308
|
stroke-width: calc(0.0625rem * var(--mantine-scale));
|
|
307
309
|
}
|
|
308
310
|
|
|
309
|
-
:where([data-mantine-color-scheme='light']) .m_2ef201c5 {
|
|
310
|
-
--heatmap-empty-rect-bg: var(--mantine-color-gray-2);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
:where([data-mantine-color-scheme='dark']) .m_2ef201c5 {
|
|
314
|
-
--heatmap-empty-rect-bg: var(--mantine-color-dark-5);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
311
|
.m_2ef201c5:where([data-empty]) {
|
|
318
312
|
fill: var(--heatmap-empty-rect-bg);
|
|
319
313
|
}
|
|
320
314
|
|
|
321
315
|
.m_7e977775,
|
|
322
|
-
.m_c4b68f8d
|
|
316
|
+
.m_c4b68f8d,
|
|
317
|
+
.m_75b4f3e6 {
|
|
323
318
|
cursor: default;
|
|
324
319
|
user-select: none;
|
|
325
320
|
fill: var(--mantine-color-dimmed);
|
|
326
321
|
}
|
|
327
322
|
|
|
323
|
+
.m_da847eb2:where([data-empty]) {
|
|
324
|
+
fill: var(--heatmap-empty-rect-bg);
|
|
325
|
+
}
|
|
326
|
+
|
|
328
327
|
.m_1ea785b1 {
|
|
329
328
|
display: flex;
|
|
330
329
|
flex-direction: column;
|
|
@@ -374,4 +373,12 @@
|
|
|
374
373
|
white-space: nowrap;
|
|
375
374
|
color: var(--mantine-color-text);
|
|
376
375
|
}
|
|
376
|
+
|
|
377
|
+
.m_3c064071 {
|
|
378
|
+
min-height: var(--chart-height, auto);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.m_3c064071 :where(*) {
|
|
382
|
+
outline: 0;
|
|
383
|
+
}
|
|
377
384
|
}
|