@monolith-forensics/monolith-ui 1.7.1 → 1.8.1-dev.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/dist/BarChart/BarChart.d.ts +3 -0
- package/dist/BarChart/BarChart.js +511 -0
- package/dist/BarChart/BarChart.lib.d.ts +31 -0
- package/dist/BarChart/BarChart.lib.js +136 -0
- package/dist/BarChart/BarChart.styled.d.ts +49 -0
- package/dist/BarChart/BarChart.styled.js +111 -0
- package/dist/BarChart/BarChart.types.d.ts +170 -0
- package/dist/BarChart/BarChart.types.js +1 -0
- package/dist/BarChart/index.d.ts +3 -0
- package/dist/BarChart/index.js +2 -0
- package/dist/Button/Button.js +9 -58
- package/dist/Calendar/Calendar.d.ts +3 -1
- package/dist/Calendar/Calendar.js +134 -33
- package/dist/Calendar/CalendarStyles.d.ts +3 -0
- package/dist/Calendar/CalendarStyles.js +92 -14
- package/dist/Calendar/calendarHelpers.d.ts +5 -1
- package/dist/Calendar/calendarHelpers.js +13 -5
- package/dist/ChartPrimitives/chartLegend.styled.d.ts +12 -0
- package/dist/ChartPrimitives/chartLegend.styled.js +52 -0
- package/dist/ChartPrimitives/chartTooltip.styled.d.ts +19 -0
- package/dist/ChartPrimitives/chartTooltip.styled.js +61 -0
- package/dist/ChartPrimitives/index.d.ts +2 -0
- package/dist/ChartPrimitives/index.js +2 -0
- package/dist/ChartUtils/chartColors.d.ts +8 -0
- package/dist/ChartUtils/chartColors.js +65 -0
- package/dist/ChartUtils/chartMath.d.ts +3 -0
- package/dist/ChartUtils/chartMath.js +3 -0
- package/dist/ChartUtils/index.d.ts +2 -0
- package/dist/ChartUtils/index.js +2 -0
- package/dist/Charts/BarChart/BarChart.d.ts +5 -0
- package/dist/Charts/BarChart/BarChart.js +549 -0
- package/dist/Charts/BarChart/BarChart.lib.d.ts +31 -0
- package/dist/Charts/BarChart/BarChart.lib.js +136 -0
- package/dist/Charts/BarChart/BarChart.styled.d.ts +51 -0
- package/dist/Charts/BarChart/BarChart.styled.js +115 -0
- package/dist/Charts/BarChart/BarChart.types.d.ts +171 -0
- package/dist/Charts/BarChart/BarChart.types.js +1 -0
- package/dist/Charts/BarChart/index.d.ts +3 -0
- package/dist/Charts/BarChart/index.js +2 -0
- package/dist/Charts/ChartPrimitives/ChartExportControl.d.ts +11 -0
- package/dist/Charts/ChartPrimitives/ChartExportControl.js +29 -0
- package/dist/Charts/ChartPrimitives/chartActions.styled.d.ts +1 -0
- package/dist/Charts/ChartPrimitives/chartActions.styled.js +8 -0
- package/dist/Charts/ChartPrimitives/chartLegend.styled.d.ts +12 -0
- package/dist/Charts/ChartPrimitives/chartLegend.styled.js +52 -0
- package/dist/Charts/ChartPrimitives/chartTooltip.styled.d.ts +19 -0
- package/dist/Charts/ChartPrimitives/chartTooltip.styled.js +61 -0
- package/dist/Charts/ChartPrimitives/index.d.ts +4 -0
- package/dist/Charts/ChartPrimitives/index.js +4 -0
- package/dist/Charts/ChartUtils/chartColors.d.ts +8 -0
- package/dist/Charts/ChartUtils/chartColors.js +65 -0
- package/dist/Charts/ChartUtils/chartExport.d.ts +47 -0
- package/dist/Charts/ChartUtils/chartExport.js +311 -0
- package/dist/Charts/ChartUtils/chartMath.d.ts +3 -0
- package/dist/Charts/ChartUtils/chartMath.js +3 -0
- package/dist/Charts/ChartUtils/index.d.ts +3 -0
- package/dist/Charts/ChartUtils/index.js +3 -0
- package/dist/Charts/HeatMap/HeatMap.d.ts +5 -0
- package/dist/Charts/HeatMap/HeatMap.js +212 -0
- package/dist/Charts/HeatMap/HeatMap.lib.d.ts +30 -0
- package/dist/Charts/HeatMap/HeatMap.lib.js +115 -0
- package/dist/Charts/HeatMap/HeatMap.styled.d.ts +37 -0
- package/dist/Charts/HeatMap/HeatMap.styled.js +91 -0
- package/dist/Charts/HeatMap/HeatMap.types.d.ts +80 -0
- package/dist/Charts/HeatMap/HeatMap.types.js +1 -0
- package/dist/Charts/HeatMap/index.d.ts +3 -0
- package/dist/Charts/HeatMap/index.js +2 -0
- package/dist/Charts/LineChart/LineChart.d.ts +5 -0
- package/dist/Charts/LineChart/LineChart.js +529 -0
- package/dist/Charts/LineChart/LineChart.lib.d.ts +24 -0
- package/dist/Charts/LineChart/LineChart.lib.js +132 -0
- package/dist/Charts/LineChart/LineChart.styled.d.ts +59 -0
- package/dist/Charts/LineChart/LineChart.styled.js +147 -0
- package/dist/Charts/LineChart/LineChart.types.d.ts +193 -0
- package/dist/Charts/LineChart/LineChart.types.js +1 -0
- package/dist/Charts/LineChart/index.d.ts +3 -0
- package/dist/Charts/LineChart/index.js +2 -0
- package/dist/Charts/PieChart/PieChart.d.ts +4 -0
- package/dist/Charts/PieChart/PieChart.js +199 -0
- package/dist/Charts/PieChart/PieChart.lib.d.ts +5 -0
- package/dist/Charts/PieChart/PieChart.lib.js +19 -0
- package/dist/Charts/PieChart/PieChart.styled.d.ts +51 -0
- package/dist/Charts/PieChart/PieChart.styled.js +163 -0
- package/dist/Charts/PieChart/PieChart.types.d.ts +100 -0
- package/dist/Charts/PieChart/PieChart.types.js +1 -0
- package/dist/Charts/PieChart/index.d.ts +2 -0
- package/dist/Charts/PieChart/index.js +1 -0
- package/dist/Charts/index.d.ts +5 -0
- package/dist/Charts/index.js +4 -0
- package/dist/CheckBox/CheckBox.js +2 -16
- package/dist/DateInput/DateInput.js +198 -143
- package/dist/DropDownMenu/components/MenuComponent.js +2 -1
- package/dist/DropDownMenu/components/MenuItem.js +5 -14
- package/dist/DropDownMenu/components/MenuItemList.js +7 -24
- package/dist/DropDownMenu/components/StyledFloatContainer.js +1 -1
- package/dist/FieldLabel/FieldLabel.js +4 -12
- package/dist/FileInputField/FileInputField.js +4 -23
- package/dist/FormSection/FormSection.js +5 -25
- package/dist/HeatMap/HeatMap.d.ts +3 -0
- package/dist/HeatMap/HeatMap.js +174 -0
- package/dist/HeatMap/HeatMap.lib.d.ts +30 -0
- package/dist/HeatMap/HeatMap.lib.js +115 -0
- package/dist/HeatMap/HeatMap.styled.d.ts +34 -0
- package/dist/HeatMap/HeatMap.styled.js +83 -0
- package/dist/HeatMap/HeatMap.types.d.ts +79 -0
- package/dist/HeatMap/HeatMap.types.js +1 -0
- package/dist/HeatMap/index.d.ts +3 -0
- package/dist/HeatMap/index.js +2 -0
- package/dist/IconButton/IconButton.js +2 -16
- package/dist/Input/Input.js +7 -56
- package/dist/LineChart/LineChart.d.ts +3 -0
- package/dist/LineChart/LineChart.js +491 -0
- package/dist/LineChart/LineChart.lib.d.ts +24 -0
- package/dist/LineChart/LineChart.lib.js +132 -0
- package/dist/LineChart/LineChart.styled.d.ts +57 -0
- package/dist/LineChart/LineChart.styled.js +150 -0
- package/dist/LineChart/LineChart.types.d.ts +192 -0
- package/dist/LineChart/LineChart.types.js +1 -0
- package/dist/LineChart/index.d.ts +3 -0
- package/dist/LineChart/index.js +2 -0
- package/dist/PieChart/PieChart.d.ts +2 -0
- package/dist/PieChart/PieChart.js +161 -0
- package/dist/PieChart/PieChart.lib.d.ts +5 -0
- package/dist/PieChart/PieChart.lib.js +19 -0
- package/dist/PieChart/PieChart.styled.d.ts +49 -0
- package/dist/PieChart/PieChart.styled.js +161 -0
- package/dist/PieChart/PieChart.types.d.ts +99 -0
- package/dist/PieChart/PieChart.types.js +1 -0
- package/dist/PieChart/index.d.ts +2 -0
- package/dist/PieChart/index.js +1 -0
- package/dist/Pill/Pill.js +8 -79
- package/dist/Popover/Popover.context.d.ts +2 -1
- package/dist/Popover/Popover.js +5 -2
- package/dist/Popover/Popover.styles.d.ts +1 -6
- package/dist/Popover/Popover.styles.js +11 -28
- package/dist/Popover/Popover.transitions.d.ts +4 -2
- package/dist/Popover/Popover.transitions.js +23 -49
- package/dist/Popover/PopoverDropdown.js +6 -8
- package/dist/Popover/PopoverTarget.js +6 -3
- package/dist/SegmentedControl/SegmentedControl.utils.d.ts +2 -2
- package/dist/SegmentedControl/SegmentedControl.utils.js +3 -30
- package/dist/SelectBox/SelectBox.js +3 -3
- package/dist/SelectBox/select-box.styled-components.d.ts +3 -1
- package/dist/SelectBox/select-box.styled-components.js +10 -48
- package/dist/SuperDatePicker/SuperDatePicker.d.ts +74 -0
- package/dist/SuperDatePicker/SuperDatePicker.js +557 -0
- package/dist/SuperDatePicker/index.d.ts +2 -0
- package/dist/SuperDatePicker/index.js +2 -0
- package/dist/Switch/Switch.d.ts +2 -2
- package/dist/Switch/Switch.js +18 -83
- package/dist/Table/StateStorage.d.ts +4 -0
- package/dist/Table/StateStorage.js +13 -0
- package/dist/Table/Table.js +160 -12
- package/dist/Table/TableComponents.d.ts +10 -0
- package/dist/Table/TableComponents.js +57 -0
- package/dist/Table/TableDefaults.d.ts +7 -0
- package/dist/Table/TableDefaults.js +7 -0
- package/dist/Table/TableProvider.js +263 -71
- package/dist/Table/TableRow.js +15 -10
- package/dist/Table/types.d.ts +64 -0
- package/dist/Tabs/Tab.js +8 -0
- package/dist/TagBox/TagBox.js +18 -76
- package/dist/TextArea/TextArea.js +4 -23
- package/dist/TextInput/TextInput.js +12 -6
- package/dist/Utilities/parseTimestamp.js +11 -6
- package/dist/core/ArrowButton.d.ts +2 -0
- package/dist/core/ArrowButton.js +7 -3
- package/dist/core/ClearButton.d.ts +2 -0
- package/dist/core/ClearButton.js +7 -3
- package/dist/core/controlSizes.d.ts +34 -0
- package/dist/core/controlSizes.js +190 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
export const StyledChartTooltip = styled.div `
|
|
3
|
+
position: absolute;
|
|
4
|
+
z-index: 1;
|
|
5
|
+
min-width: ${({ $minWidth = 120 }) => $minWidth}px;
|
|
6
|
+
max-width: ${({ $maxWidth = 220 }) => $maxWidth}px;
|
|
7
|
+
padding: 7px 9px;
|
|
8
|
+
border: 1px solid ${({ theme }) => theme.palette.divider};
|
|
9
|
+
border-radius: 4px;
|
|
10
|
+
background: ${({ theme }) => theme.palette.background.paper};
|
|
11
|
+
color: ${({ theme }) => theme.palette.text.primary};
|
|
12
|
+
box-shadow: 0 10px 24px rgba(0, 0, 0, 0.18);
|
|
13
|
+
font-size: 12px;
|
|
14
|
+
line-height: 1.35;
|
|
15
|
+
pointer-events: none;
|
|
16
|
+
transform: ${({ $transform = "translate(10px, -50%)" }) => $transform};
|
|
17
|
+
`;
|
|
18
|
+
export const StyledChartTooltipHeader = styled.div `
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
gap: 7px;
|
|
22
|
+
min-width: 0;
|
|
23
|
+
font-weight: 600;
|
|
24
|
+
`;
|
|
25
|
+
export const StyledChartTooltipSwatch = styled.span `
|
|
26
|
+
width: 8px;
|
|
27
|
+
height: 8px;
|
|
28
|
+
flex: 0 0 auto;
|
|
29
|
+
border-radius: ${({ $radius = "2px" }) => $radius};
|
|
30
|
+
background: ${({ $color }) => $color};
|
|
31
|
+
`;
|
|
32
|
+
export const StyledChartTooltipLabel = styled.span `
|
|
33
|
+
overflow: hidden;
|
|
34
|
+
text-overflow: ellipsis;
|
|
35
|
+
white-space: nowrap;
|
|
36
|
+
`;
|
|
37
|
+
export const StyledChartTooltipMeta = styled.div `
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: ${({ $direction = "row" }) => $direction};
|
|
40
|
+
gap: ${({ $gap = 8 }) => $gap}px;
|
|
41
|
+
margin-top: ${({ $marginTop = 3 }) => $marginTop}px;
|
|
42
|
+
color: ${({ theme }) => theme.palette.text.secondary};
|
|
43
|
+
font-variant-numeric: tabular-nums;
|
|
44
|
+
`;
|
|
45
|
+
export const StyledChartTooltipList = styled.div `
|
|
46
|
+
display: flex;
|
|
47
|
+
flex-direction: column;
|
|
48
|
+
gap: 5px;
|
|
49
|
+
margin-top: 8px;
|
|
50
|
+
`;
|
|
51
|
+
export const StyledChartTooltipRow = styled.div `
|
|
52
|
+
display: grid;
|
|
53
|
+
grid-template-columns: 8px minmax(0, 1fr) auto;
|
|
54
|
+
align-items: center;
|
|
55
|
+
gap: 7px;
|
|
56
|
+
`;
|
|
57
|
+
export const StyledChartTooltipValue = styled.span `
|
|
58
|
+
color: ${({ theme }) => theme.palette.text.primary};
|
|
59
|
+
font-variant-numeric: tabular-nums;
|
|
60
|
+
white-space: nowrap;
|
|
61
|
+
`;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type ChartColorGradientInput = string[] | {
|
|
2
|
+
from: string;
|
|
3
|
+
to: string;
|
|
4
|
+
} | null | undefined;
|
|
5
|
+
export declare const mixColors: (from: string, to: string, amount: number) => string;
|
|
6
|
+
export declare const getGradientStops: (colorGradient?: ChartColorGradientInput) => string[] | null;
|
|
7
|
+
export declare const getGradientColorFromStops: (stops: string[] | null | undefined, index: number, total: number) => string | undefined;
|
|
8
|
+
export declare const getGradientColor: (colorGradient: ChartColorGradientInput, index: number, total: number) => string | undefined;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { clamp } from "./chartMath";
|
|
2
|
+
const parseColor = (color) => {
|
|
3
|
+
const trimmedColor = color.trim();
|
|
4
|
+
const hexMatch = trimmedColor.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);
|
|
5
|
+
if (hexMatch) {
|
|
6
|
+
const normalizedHex = hexMatch[1].length === 3
|
|
7
|
+
? hexMatch[1]
|
|
8
|
+
.split("")
|
|
9
|
+
.map((character) => character + character)
|
|
10
|
+
.join("")
|
|
11
|
+
: hexMatch[1];
|
|
12
|
+
return {
|
|
13
|
+
r: parseInt(normalizedHex.slice(0, 2), 16),
|
|
14
|
+
g: parseInt(normalizedHex.slice(2, 4), 16),
|
|
15
|
+
b: parseInt(normalizedHex.slice(4, 6), 16),
|
|
16
|
+
a: 1,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const rgbMatch = trimmedColor.match(/^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*(0|1|0?\.\d+))?\s*\)$/i);
|
|
20
|
+
if (!rgbMatch) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
r: clamp(Number(rgbMatch[1]), 0, 255),
|
|
25
|
+
g: clamp(Number(rgbMatch[2]), 0, 255),
|
|
26
|
+
b: clamp(Number(rgbMatch[3]), 0, 255),
|
|
27
|
+
a: rgbMatch[4] ? clamp(Number(rgbMatch[4]), 0, 1) : 1,
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export const mixColors = (from, to, amount) => {
|
|
31
|
+
const normalizedAmount = clamp(amount, 0, 1);
|
|
32
|
+
if (normalizedAmount === 0)
|
|
33
|
+
return from;
|
|
34
|
+
if (normalizedAmount === 1)
|
|
35
|
+
return to;
|
|
36
|
+
const fromColor = parseColor(from);
|
|
37
|
+
const toColor = parseColor(to);
|
|
38
|
+
if (!fromColor || !toColor) {
|
|
39
|
+
return `color-mix(in srgb, ${from} ${(1 - normalizedAmount) * 100}%, ${to})`;
|
|
40
|
+
}
|
|
41
|
+
const r = Math.round(fromColor.r + (toColor.r - fromColor.r) * normalizedAmount);
|
|
42
|
+
const g = Math.round(fromColor.g + (toColor.g - fromColor.g) * normalizedAmount);
|
|
43
|
+
const b = Math.round(fromColor.b + (toColor.b - fromColor.b) * normalizedAmount);
|
|
44
|
+
const a = fromColor.a + (toColor.a - fromColor.a) * normalizedAmount;
|
|
45
|
+
return a === 1 ? `rgb(${r}, ${g}, ${b})` : `rgba(${r}, ${g}, ${b}, ${a})`;
|
|
46
|
+
};
|
|
47
|
+
export const getGradientStops = (colorGradient) => {
|
|
48
|
+
if (!colorGradient)
|
|
49
|
+
return null;
|
|
50
|
+
return Array.isArray(colorGradient)
|
|
51
|
+
? colorGradient.filter(Boolean)
|
|
52
|
+
: [colorGradient.from, colorGradient.to].filter(Boolean);
|
|
53
|
+
};
|
|
54
|
+
export const getGradientColorFromStops = (stops, index, total) => {
|
|
55
|
+
if (!(stops === null || stops === void 0 ? void 0 : stops.length))
|
|
56
|
+
return undefined;
|
|
57
|
+
if (stops.length === 1 || total <= 1)
|
|
58
|
+
return stops[0];
|
|
59
|
+
const progress = index / (total - 1);
|
|
60
|
+
const scaledProgress = progress * (stops.length - 1);
|
|
61
|
+
const stopIndex = Math.min(Math.floor(scaledProgress), stops.length - 2);
|
|
62
|
+
const stopProgress = scaledProgress - stopIndex;
|
|
63
|
+
return mixColors(stops[stopIndex], stops[stopIndex + 1], stopProgress);
|
|
64
|
+
};
|
|
65
|
+
export const getGradientColor = (colorGradient, index, total) => getGradientColorFromStops(getGradientStops(colorGradient), index, total);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export type ChartExportFormat = "svg" | "png" | "jpg";
|
|
2
|
+
export type ChartImageExportRequest = {
|
|
3
|
+
/** Output format for the exported image. Defaults to "svg". */
|
|
4
|
+
format?: ChartExportFormat;
|
|
5
|
+
/** Base file name used for the downloaded chart image. */
|
|
6
|
+
fileName?: string;
|
|
7
|
+
/** Output scale used for raster exports like png and jpg. */
|
|
8
|
+
scale?: number;
|
|
9
|
+
/** Background color applied to jpg exports. */
|
|
10
|
+
backgroundColor?: string;
|
|
11
|
+
};
|
|
12
|
+
export type ChartHandle = {
|
|
13
|
+
/** Returns the live SVG element rendered by the chart. */
|
|
14
|
+
getSvgElement: () => SVGSVGElement | null;
|
|
15
|
+
/** Downloads the current chart image using the provided or default export options. */
|
|
16
|
+
downloadImage: (request?: ChartImageExportRequest) => Promise<void>;
|
|
17
|
+
/** Copies the current chart image to the clipboard. Defaults to png for broad paste compatibility. */
|
|
18
|
+
copyImage: (request?: ChartImageExportRequest) => Promise<boolean>;
|
|
19
|
+
};
|
|
20
|
+
export type ChartExportOptions = {
|
|
21
|
+
/** Shows a download button that can export the current chart image. Defaults to false. */
|
|
22
|
+
showExportButton?: boolean;
|
|
23
|
+
/** Base file name used for downloaded chart images. */
|
|
24
|
+
exportFileName?: string;
|
|
25
|
+
/** Image formats offered in the export menu. Defaults to svg, png, and jpg. */
|
|
26
|
+
exportFormats?: ChartExportFormat[];
|
|
27
|
+
/** Output scale used for raster exports like png and jpg. Defaults to 2. */
|
|
28
|
+
exportScale?: number;
|
|
29
|
+
/** Background color applied to jpg exports. Defaults to the theme paper color. */
|
|
30
|
+
exportBackgroundColor?: string;
|
|
31
|
+
};
|
|
32
|
+
export declare const DEFAULT_CHART_EXPORT_FORMATS: ChartExportFormat[];
|
|
33
|
+
export declare const downloadChartImage: ({ rootElement, svg, format, fileName, scale, backgroundColor, }: {
|
|
34
|
+
rootElement?: HTMLElement | null;
|
|
35
|
+
svg: SVGSVGElement | null;
|
|
36
|
+
format: ChartExportFormat;
|
|
37
|
+
fileName: string;
|
|
38
|
+
scale?: number;
|
|
39
|
+
backgroundColor?: string;
|
|
40
|
+
}) => Promise<void>;
|
|
41
|
+
export declare const copyChartImage: ({ rootElement, svg, format, scale, backgroundColor, }: {
|
|
42
|
+
rootElement?: HTMLElement | null;
|
|
43
|
+
svg: SVGSVGElement | null;
|
|
44
|
+
format?: ChartExportFormat;
|
|
45
|
+
scale?: number;
|
|
46
|
+
backgroundColor?: string;
|
|
47
|
+
}) => Promise<boolean>;
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
export const DEFAULT_CHART_EXPORT_FORMATS = [
|
|
11
|
+
"svg",
|
|
12
|
+
"png",
|
|
13
|
+
"jpg",
|
|
14
|
+
];
|
|
15
|
+
const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
16
|
+
const XML_NAMESPACE = "http://www.w3.org/2000/xmlns/";
|
|
17
|
+
const XLINK_NAMESPACE = "http://www.w3.org/1999/xlink";
|
|
18
|
+
const getSvgDimensions = (svg) => {
|
|
19
|
+
const viewBox = svg.viewBox.baseVal;
|
|
20
|
+
if (viewBox && viewBox.width > 0 && viewBox.height > 0) {
|
|
21
|
+
return {
|
|
22
|
+
width: viewBox.width,
|
|
23
|
+
height: viewBox.height,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const widthAttr = Number(svg.getAttribute("width"));
|
|
27
|
+
const heightAttr = Number(svg.getAttribute("height"));
|
|
28
|
+
if (Number.isFinite(widthAttr) && Number.isFinite(heightAttr)) {
|
|
29
|
+
return {
|
|
30
|
+
width: widthAttr,
|
|
31
|
+
height: heightAttr,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const rect = svg.getBoundingClientRect();
|
|
35
|
+
return {
|
|
36
|
+
width: Math.max(Math.round(rect.width), 1),
|
|
37
|
+
height: Math.max(Math.round(rect.height), 1),
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
const copyComputedStyles = (source, target) => {
|
|
41
|
+
const computedStyle = window.getComputedStyle(source);
|
|
42
|
+
let inlineStyle = "";
|
|
43
|
+
for (let index = 0; index < computedStyle.length; index += 1) {
|
|
44
|
+
const propertyName = computedStyle[index];
|
|
45
|
+
inlineStyle += `${propertyName}:${computedStyle.getPropertyValue(propertyName)};`;
|
|
46
|
+
}
|
|
47
|
+
if (inlineStyle) {
|
|
48
|
+
target.setAttribute("style", inlineStyle);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const inlineNodeStyles = (sourceRoot, targetRoot) => {
|
|
52
|
+
const sourceElements = [sourceRoot, ...Array.from(sourceRoot.querySelectorAll("*"))];
|
|
53
|
+
const targetElements = [targetRoot, ...Array.from(targetRoot.querySelectorAll("*"))];
|
|
54
|
+
sourceElements.forEach((sourceElement, index) => {
|
|
55
|
+
const targetElement = targetElements[index];
|
|
56
|
+
if (!targetElement)
|
|
57
|
+
return;
|
|
58
|
+
copyComputedStyles(sourceElement, targetElement);
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
const removeIgnoredNodes = (root) => {
|
|
62
|
+
root
|
|
63
|
+
.querySelectorAll('[data-chart-export-ignore="true"]')
|
|
64
|
+
.forEach((element) => element.remove());
|
|
65
|
+
};
|
|
66
|
+
const serializeSvg = (svg) => {
|
|
67
|
+
const clone = svg.cloneNode(true);
|
|
68
|
+
const { width, height } = getSvgDimensions(svg);
|
|
69
|
+
clone.setAttribute("version", "1.1");
|
|
70
|
+
clone.setAttribute("xmlns", SVG_NAMESPACE);
|
|
71
|
+
clone.setAttributeNS(XML_NAMESPACE, "xmlns:xlink", XLINK_NAMESPACE);
|
|
72
|
+
clone.setAttribute("width", String(width));
|
|
73
|
+
clone.setAttribute("height", String(height));
|
|
74
|
+
if (!clone.getAttribute("viewBox")) {
|
|
75
|
+
clone.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
|
76
|
+
}
|
|
77
|
+
inlineNodeStyles(svg, clone);
|
|
78
|
+
const serializer = new XMLSerializer();
|
|
79
|
+
return `<?xml version="1.0" encoding="UTF-8"?>${serializer.serializeToString(clone)}`;
|
|
80
|
+
};
|
|
81
|
+
const getElementDimensions = (element) => {
|
|
82
|
+
const rect = element.getBoundingClientRect();
|
|
83
|
+
return {
|
|
84
|
+
width: Math.max(Math.round(rect.width || element.offsetWidth || element.clientWidth || 1), 1),
|
|
85
|
+
height: Math.max(Math.round(rect.height || element.offsetHeight || element.clientHeight || 1), 1),
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
const isExportIgnored = (element) => element.closest('[data-chart-export-ignore="true"]') != null;
|
|
89
|
+
const isVisibleElement = (element) => {
|
|
90
|
+
const computedStyle = window.getComputedStyle(element);
|
|
91
|
+
return (computedStyle.display !== "none" &&
|
|
92
|
+
computedStyle.visibility !== "hidden" &&
|
|
93
|
+
computedStyle.opacity !== "0");
|
|
94
|
+
};
|
|
95
|
+
const getElementText = (element) => {
|
|
96
|
+
var _a, _b;
|
|
97
|
+
const hasElementChildren = Array.from(element.childNodes).some((node) => node.nodeType === Node.ELEMENT_NODE);
|
|
98
|
+
if (hasElementChildren)
|
|
99
|
+
return "";
|
|
100
|
+
return (_b = (_a = element.textContent) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : "";
|
|
101
|
+
};
|
|
102
|
+
const isRenderableColor = (color) => color !== "" && color !== "transparent" && color !== "rgba(0, 0, 0, 0)";
|
|
103
|
+
const appendElementBox = (targetSvg, element, rootRect) => {
|
|
104
|
+
const computedStyle = window.getComputedStyle(element);
|
|
105
|
+
const backgroundColor = computedStyle.backgroundColor;
|
|
106
|
+
const borderColor = computedStyle.borderColor;
|
|
107
|
+
const borderWidth = Number.parseFloat(computedStyle.borderWidth) || 0;
|
|
108
|
+
const hasBackground = isRenderableColor(backgroundColor);
|
|
109
|
+
const hasBorder = borderWidth > 0 && isRenderableColor(borderColor);
|
|
110
|
+
if (!hasBackground && !hasBorder)
|
|
111
|
+
return;
|
|
112
|
+
const rect = element.getBoundingClientRect();
|
|
113
|
+
const radius = Number.parseFloat(computedStyle.borderRadius) || 0;
|
|
114
|
+
const box = document.createElementNS(SVG_NAMESPACE, "rect");
|
|
115
|
+
box.setAttribute("x", String(rect.left - rootRect.left));
|
|
116
|
+
box.setAttribute("y", String(rect.top - rootRect.top));
|
|
117
|
+
box.setAttribute("width", String(Math.max(rect.width, 0)));
|
|
118
|
+
box.setAttribute("height", String(Math.max(rect.height, 0)));
|
|
119
|
+
box.setAttribute("rx", String(radius));
|
|
120
|
+
box.setAttribute("ry", String(radius));
|
|
121
|
+
box.setAttribute("fill", hasBackground ? backgroundColor : "none");
|
|
122
|
+
if (hasBorder) {
|
|
123
|
+
box.setAttribute("stroke", borderColor);
|
|
124
|
+
box.setAttribute("stroke-width", String(borderWidth));
|
|
125
|
+
}
|
|
126
|
+
targetSvg.appendChild(box);
|
|
127
|
+
};
|
|
128
|
+
const appendElementText = (targetSvg, element, rootRect) => {
|
|
129
|
+
const text = getElementText(element);
|
|
130
|
+
if (!text)
|
|
131
|
+
return;
|
|
132
|
+
const computedStyle = window.getComputedStyle(element);
|
|
133
|
+
const rect = element.getBoundingClientRect();
|
|
134
|
+
const textNode = document.createElementNS(SVG_NAMESPACE, "text");
|
|
135
|
+
const fontSize = Number.parseFloat(computedStyle.fontSize) || 12;
|
|
136
|
+
const fontWeight = computedStyle.fontWeight;
|
|
137
|
+
const textAlign = computedStyle.textAlign;
|
|
138
|
+
const isRightAligned = textAlign === "right" || textAlign === "end";
|
|
139
|
+
const isCenterAligned = textAlign === "center";
|
|
140
|
+
const x = isRightAligned
|
|
141
|
+
? rect.right - rootRect.left
|
|
142
|
+
: isCenterAligned
|
|
143
|
+
? rect.left - rootRect.left + rect.width / 2
|
|
144
|
+
: rect.left - rootRect.left;
|
|
145
|
+
textNode.textContent = text;
|
|
146
|
+
textNode.setAttribute("x", String(x));
|
|
147
|
+
textNode.setAttribute("y", String(rect.top - rootRect.top + rect.height / 2));
|
|
148
|
+
textNode.setAttribute("text-anchor", isRightAligned ? "end" : isCenterAligned ? "middle" : "start");
|
|
149
|
+
textNode.setAttribute("dominant-baseline", "central");
|
|
150
|
+
textNode.setAttribute("fill", computedStyle.color);
|
|
151
|
+
textNode.setAttribute("font-family", computedStyle.fontFamily);
|
|
152
|
+
textNode.setAttribute("font-size", `${fontSize}px`);
|
|
153
|
+
textNode.setAttribute("font-weight", fontWeight);
|
|
154
|
+
if (computedStyle.fontVariantNumeric) {
|
|
155
|
+
textNode.setAttribute("font-variant-numeric", computedStyle.fontVariantNumeric);
|
|
156
|
+
}
|
|
157
|
+
targetSvg.appendChild(textNode);
|
|
158
|
+
};
|
|
159
|
+
const appendNestedSvg = (targetSvg, svg, rootRect) => {
|
|
160
|
+
const clone = svg.cloneNode(true);
|
|
161
|
+
const rect = svg.getBoundingClientRect();
|
|
162
|
+
inlineNodeStyles(svg, clone);
|
|
163
|
+
removeIgnoredNodes(clone);
|
|
164
|
+
clone.setAttribute("x", String(rect.left - rootRect.left));
|
|
165
|
+
clone.setAttribute("y", String(rect.top - rootRect.top));
|
|
166
|
+
clone.setAttribute("width", String(Math.max(rect.width, 1)));
|
|
167
|
+
clone.setAttribute("height", String(Math.max(rect.height, 1)));
|
|
168
|
+
targetSvg.appendChild(clone);
|
|
169
|
+
};
|
|
170
|
+
const serializeElement = (element) => {
|
|
171
|
+
const { width, height } = getElementDimensions(element);
|
|
172
|
+
const rootRect = element.getBoundingClientRect();
|
|
173
|
+
const wrapperSvg = document.createElementNS(SVG_NAMESPACE, "svg");
|
|
174
|
+
wrapperSvg.setAttribute("version", "1.1");
|
|
175
|
+
wrapperSvg.setAttribute("xmlns", SVG_NAMESPACE);
|
|
176
|
+
wrapperSvg.setAttributeNS(XML_NAMESPACE, "xmlns:xlink", XLINK_NAMESPACE);
|
|
177
|
+
wrapperSvg.setAttribute("width", String(width));
|
|
178
|
+
wrapperSvg.setAttribute("height", String(height));
|
|
179
|
+
wrapperSvg.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
|
180
|
+
const appendElement = (currentElement) => {
|
|
181
|
+
if (currentElement !== element && isExportIgnored(currentElement))
|
|
182
|
+
return;
|
|
183
|
+
if (!isVisibleElement(currentElement))
|
|
184
|
+
return;
|
|
185
|
+
if (currentElement instanceof SVGSVGElement) {
|
|
186
|
+
appendNestedSvg(wrapperSvg, currentElement, rootRect);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
appendElementBox(wrapperSvg, currentElement, rootRect);
|
|
190
|
+
appendElementText(wrapperSvg, currentElement, rootRect);
|
|
191
|
+
Array.from(currentElement.children).forEach(appendElement);
|
|
192
|
+
};
|
|
193
|
+
appendElement(element);
|
|
194
|
+
const serializer = new XMLSerializer();
|
|
195
|
+
return `<?xml version="1.0" encoding="UTF-8"?>${serializer.serializeToString(wrapperSvg)}`;
|
|
196
|
+
};
|
|
197
|
+
const triggerDownload = (blob, fileName) => {
|
|
198
|
+
const objectUrl = URL.createObjectURL(blob);
|
|
199
|
+
const anchor = document.createElement("a");
|
|
200
|
+
anchor.href = objectUrl;
|
|
201
|
+
anchor.download = fileName;
|
|
202
|
+
document.body.appendChild(anchor);
|
|
203
|
+
anchor.click();
|
|
204
|
+
document.body.removeChild(anchor);
|
|
205
|
+
window.setTimeout(() => {
|
|
206
|
+
URL.revokeObjectURL(objectUrl);
|
|
207
|
+
}, 0);
|
|
208
|
+
};
|
|
209
|
+
const rasterizeSvg = (_a) => __awaiter(void 0, [_a], void 0, function* ({ svgMarkup, format, width, height, scale, backgroundColor, }) {
|
|
210
|
+
if (typeof window !== "undefined" && "fonts" in document) {
|
|
211
|
+
yield document.fonts.ready;
|
|
212
|
+
}
|
|
213
|
+
const svgBlob = new Blob([svgMarkup], {
|
|
214
|
+
type: "image/svg+xml;charset=utf-8",
|
|
215
|
+
});
|
|
216
|
+
const svgUrl = URL.createObjectURL(svgBlob);
|
|
217
|
+
try {
|
|
218
|
+
const image = yield new Promise((resolve, reject) => {
|
|
219
|
+
const nextImage = new Image();
|
|
220
|
+
nextImage.onload = () => resolve(nextImage);
|
|
221
|
+
nextImage.onerror = () => reject(new Error("Unable to render the chart image."));
|
|
222
|
+
nextImage.src = svgUrl;
|
|
223
|
+
});
|
|
224
|
+
const canvas = document.createElement("canvas");
|
|
225
|
+
canvas.width = Math.max(Math.round(width * scale), 1);
|
|
226
|
+
canvas.height = Math.max(Math.round(height * scale), 1);
|
|
227
|
+
const context = canvas.getContext("2d");
|
|
228
|
+
if (!context) {
|
|
229
|
+
throw new Error("Unable to create a canvas for chart export.");
|
|
230
|
+
}
|
|
231
|
+
context.setTransform(scale, 0, 0, scale, 0, 0);
|
|
232
|
+
if (format === "jpg") {
|
|
233
|
+
context.fillStyle = backgroundColor !== null && backgroundColor !== void 0 ? backgroundColor : "#ffffff";
|
|
234
|
+
context.fillRect(0, 0, width, height);
|
|
235
|
+
}
|
|
236
|
+
context.drawImage(image, 0, 0, width, height);
|
|
237
|
+
const mimeType = format === "png" ? "image/png" : "image/jpeg";
|
|
238
|
+
return yield new Promise((resolve, reject) => {
|
|
239
|
+
canvas.toBlob((blob) => {
|
|
240
|
+
if (!blob) {
|
|
241
|
+
reject(new Error("Unable to generate the exported chart image."));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
resolve(blob);
|
|
245
|
+
}, mimeType, format === "jpg" ? 0.92 : undefined);
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
finally {
|
|
249
|
+
URL.revokeObjectURL(svgUrl);
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
const getChartImageBlob = (_a) => __awaiter(void 0, [_a], void 0, function* ({ rootElement, svg, format, scale = 2, backgroundColor, }) {
|
|
253
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
if (!rootElement && !svg)
|
|
257
|
+
return null;
|
|
258
|
+
const safeScale = Number.isFinite(scale) ? Math.max(scale, 1) : 2;
|
|
259
|
+
const svgMarkup = rootElement ? serializeElement(rootElement) : serializeSvg(svg);
|
|
260
|
+
const { width, height } = rootElement
|
|
261
|
+
? getElementDimensions(rootElement)
|
|
262
|
+
: getSvgDimensions(svg);
|
|
263
|
+
if (format === "svg") {
|
|
264
|
+
return new Blob([svgMarkup], {
|
|
265
|
+
type: "image/svg+xml;charset=utf-8",
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
return yield rasterizeSvg({
|
|
269
|
+
svgMarkup,
|
|
270
|
+
format,
|
|
271
|
+
width,
|
|
272
|
+
height,
|
|
273
|
+
scale: safeScale,
|
|
274
|
+
backgroundColor,
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
export const downloadChartImage = (_a) => __awaiter(void 0, [_a], void 0, function* ({ rootElement, svg, format, fileName, scale = 2, backgroundColor, }) {
|
|
278
|
+
const blob = yield getChartImageBlob({
|
|
279
|
+
rootElement,
|
|
280
|
+
svg,
|
|
281
|
+
format,
|
|
282
|
+
scale,
|
|
283
|
+
backgroundColor,
|
|
284
|
+
});
|
|
285
|
+
if (!blob)
|
|
286
|
+
return;
|
|
287
|
+
triggerDownload(blob, `${fileName}.${format}`);
|
|
288
|
+
});
|
|
289
|
+
export const copyChartImage = (_a) => __awaiter(void 0, [_a], void 0, function* ({ rootElement, svg, format = "png", scale = 2, backgroundColor, }) {
|
|
290
|
+
var _b;
|
|
291
|
+
if (typeof window === "undefined" ||
|
|
292
|
+
typeof navigator === "undefined" ||
|
|
293
|
+
typeof ClipboardItem === "undefined" ||
|
|
294
|
+
!((_b = navigator.clipboard) === null || _b === void 0 ? void 0 : _b.write)) {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
const blob = yield getChartImageBlob({
|
|
298
|
+
rootElement,
|
|
299
|
+
svg,
|
|
300
|
+
format,
|
|
301
|
+
scale,
|
|
302
|
+
backgroundColor,
|
|
303
|
+
});
|
|
304
|
+
if (!blob)
|
|
305
|
+
return false;
|
|
306
|
+
const clipboardItem = new ClipboardItem({
|
|
307
|
+
[blob.type]: blob,
|
|
308
|
+
});
|
|
309
|
+
yield navigator.clipboard.write([clipboardItem]);
|
|
310
|
+
return true;
|
|
311
|
+
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ReactElement, RefAttributes } from "react";
|
|
2
|
+
import { ChartHandle } from "../ChartUtils";
|
|
3
|
+
import { HeatMapProps } from "./HeatMap.types";
|
|
4
|
+
declare const HeatMap: <TData>(props: HeatMapProps<TData> & RefAttributes<ChartHandle>) => ReactElement | null;
|
|
5
|
+
export default HeatMap;
|