@amaui/ui-react
Version:
UI for React
852 lines • 84.2 kB
JavaScript
"use strict";
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = __importDefault(require("react"));
const utils_1 = require("@amaui/utils");
const style_react_1 = require("@amaui/style-react");
const Surface_1 = __importDefault(require("../Surface"));
const Line_1 = __importDefault(require("../Line"));
const Type_1 = __importDefault(require("../Type"));
const Path_1 = __importDefault(require("../Path"));
const Append_1 = __importDefault(require("../Append"));
const Grow_1 = __importDefault(require("../Grow"));
const useMediaQuery_1 = __importDefault(require("../useMediaQuery"));
const utils_2 = require("../utils");
const useStyle = (0, style_react_1.style)(theme => ({
root: {
width: '100%',
'&.amaui-Surface-root': {
background: 'transparent'
}
},
additionalLines: {
pointerEvents: 'none'
},
append_wrapper: {
userSelect: 'none',
pointerEvents: 'none',
zIndex: theme.z_index.tooltip
},
wrapper: {
position: 'relative',
height: '400px',
width: '100%',
maxWidth: '1000px'
},
wrapper_label_x: {
margin: '0 0 30px 0'
},
wrapper_label_y: {
margin: '0 0 0 40px'
},
wrapper_labels: {
margin: '0 0 30px 40px'
},
wrapper_name_x: {
margin: '0 0 60px 0'
},
wrapper_name_y: {
margin: '0 0 0 70px'
},
wrapper_names: {
margin: '0 0 60px 70px'
},
legend_offset_labels_y: {
paddingLeft: theme.methods.space.value(5, 'px')
},
legend_offset_names_y: {
paddingLeft: theme.methods.space.value(9, 'px')
},
svg: {
position: 'relative',
touchAction: 'none',
userSelect: 'none',
'& path, & circle, & rect, & g': {
transition: theme.methods.transitions.make('opacity', { duration: 'xs' })
}
},
header: {
width: '100%',
marginBottom: '24px'
},
subtitle: {
opacity: '0.74'
},
append: {
padding: `${theme.methods.space.value(1.5, 'px')} ${theme.methods.space.value(2.5, 'px')}`,
borderRadius: theme.methods.shape.radius.value(1.5, 'px')
},
name: {
position: 'absolute',
userSelect: 'none'
},
name_x: {
bottom: '-61px',
left: '50%',
transform: 'translateX(-50%)'
},
name_y: {
left: '-87px',
top: '50%',
transform: 'translateY(-50%) rotate(-90deg)'
},
labels: {
position: 'absolute',
userSelect: 'none'
},
labels_x: {
top: 'calc(100% + 12px)',
left: '0',
width: '100%'
},
labels_y: {
top: '0',
right: 'calc(100% + 12px)',
height: '100%'
},
label: {
position: 'absolute',
whiteSpace: 'nowrap'
},
label_x: {
transform: 'translateX(-50%)',
top: '0'
},
label_y: {
transform: 'translateY(50%)',
right: '0'
},
marks: {
position: 'absolute'
},
marks_x: {
top: 'calc(100% + 0px)',
left: '0',
width: '100%'
},
marks_y: {
top: '0',
right: 'calc(100% + 0px)',
height: '100%'
},
mark: {
position: 'absolute'
},
mark_x: {
width: '1px',
height: '7px',
top: '0',
background: 'currentColor'
},
mark_y: {
width: '7px',
height: '1px',
right: '0',
background: 'currentColor'
},
grids: {
position: 'absolute',
width: '100%',
height: '100%'
},
grids_x: {
top: '0',
left: '0'
},
grids_y: {
top: '0',
left: '0'
},
grid: {
position: 'absolute',
width: '100%',
height: '100%',
opacity: theme.palette.light ? '0.07' : '0.14'
},
grid_x: {
width: '1px',
background: 'currentColor'
},
grid_y: {
height: '1px',
background: 'currentColor'
},
border: {
position: 'absolute',
background: 'currentColor'
},
borderX: {
height: '1px',
width: 'calc(100% + 1px)',
left: '0'
},
borderTop: {
top: '0'
},
borderBottom: {
bottom: '0'
},
borderY: {
width: '1px',
height: 'calc(100% + 1px)',
top: '-1px'
},
borderStart: {
insetInlineStart: '0'
},
borderLeft: {
left: '0'
},
borderEnd: {
insetInlineEnd: '0'
},
borderRight: {
right: '0'
},
point_visibility_hover: {
opacity: '0',
transition: theme.methods.transitions.make('opacity', { duration: 'xxs' }),
'&:hover': {
opacity: '1'
}
},
point_visibility_visible: {
opacity: '1'
},
point_active: {
opacity: '1'
},
point_visibility_hidden: {
opacity: '0',
pointerEvents: 'none'
},
// Legend
legend: {},
legend_position_top: {
marginBottom: '16px'
},
legend_position_bottom: {
marginTop: '16px'
},
legend_item: {
userSelect: 'none'
},
legend_item_manage_visibility: {
cursor: 'pointer',
transition: theme.methods.transitions.make('opacity', { duration: 'xs' })
},
legend_item_hidden: {
opacity: '0.4'
},
legend_icon: {
width: '10px',
height: '10px',
borderRadius: theme.methods.shape.radius.value(40, 'px'),
boxSizing: 'border-box'
},
append_icon: {
width: '8px',
height: '8px',
borderRadius: theme.methods.shape.radius.value(40, 'px'),
boxSizing: 'border-box'
},
// Guideline
guidelines: {
stroke: 'currentColor',
strokeDasharray: '4',
opacity: '0.44',
pointerEvents: 'none'
}
}), { name: 'amaui-Chart' });
const Chart = react_1.default.forwardRef((props_, ref) => {
var _a, _b, _c, _d;
const theme = (0, style_react_1.useAmauiTheme)();
const props = react_1.default.useMemo(() => { var _a, _b, _c, _d, _e, _f, _g, _h; return (Object.assign(Object.assign(Object.assign({}, (_d = (_c = (_b = (_a = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _a === void 0 ? void 0 : _a.elements) === null || _b === void 0 ? void 0 : _b.all) === null || _c === void 0 ? void 0 : _c.props) === null || _d === void 0 ? void 0 : _d.default), (_h = (_g = (_f = (_e = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _e === void 0 ? void 0 : _e.elements) === null || _f === void 0 ? void 0 : _f.amauiChart) === null || _g === void 0 ? void 0 : _g.props) === null || _h === void 0 ? void 0 : _h.default), props_)); }, [props_]);
const Line = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Line) || Line_1.default; }, [theme]);
const Surface = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Surface) || Surface_1.default; }, [theme]);
const Type = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Type) || Type_1.default; }, [theme]);
const Path = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Path) || Path_1.default; }, [theme]);
const Append = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Append) || Append_1.default; }, [theme]);
const Grow = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Grow) || Grow_1.default; }, [theme]);
const { tonal = true, color = 'primary', title, subtitle,
// Values
values,
// Pre
pre,
// Elements
elements,
// Names
names, nameX: nameX_, nameY: nameY_,
// Tooltip
tooltip: tooltip_, tooltipIndividually: tooltipIndividually_, tooltipCloseOnMouseLeave: tooltipCloseOnMouseLeave_, elementTooltip: elementTooltip_,
// Guideline
guidelines: guidelines_, guidelinesAppend: guidelinesAppend_, guidelinesDisplayInactive: guidelinesDisplayInactive_,
// Additional lines
additionalLines: additionalLines__,
// Legend
legend: legend___, legendManageVisibility = true, legendPosition = 'bottom',
// Animation
animate: animate_, animateTimeout: animateTimeout_,
// Labels
labels: labels___, labelsX: labelsX_, labelsY: labelsY_, labelDecimalPlaces: labelDecimalPlaces_, labelsAutoNumber: labelsAutoNumber_, labelsYAutoNumber: labelsYAutoNumber_, labelsXAutoNumber: labelsXAutoNumber_,
// Marks
marks: marks___, marksX: marksX_, marksY: marksY_, marksAutoNumber: marksAutoNumber_, marksYAutoNumber: marksYAutoNumber_, marksXAutoNumber: marksXAutoNumber_,
// Grid
grid: grid___, gridX: gridX_, gridY: gridY_, gridAutoNumber: gridAutoNumber_, gridYAutoNumber: gridYAutoNumber_, gridXAutoNumber: gridXAutoNumber_,
// Points
points: points___, pointsVisibility: pointsVisibility_,
// Borders
borders: borders_ = true, borderStart: borderStart_ = false, borderLeft: borderLeft_ = true, borderEnd: borderEnd_ = false, borderRight: borderRight_ = false, borderTop: borderTop_ = false, borderBottom: borderBottom_ = true,
// Min, max
minX: minX_, maxX: maxX_, minY: minY_, maxY: maxY_, minMaxPadding: minMaxPadding__, minPadding: minPadding__, maxPadding: maxPadding__, minPaddingX: minPaddingX__, minPaddingY: minPaddingY__, maxPaddingX: maxPaddingX__, maxPaddingY: maxPaddingY__, noMain, tooltipRender, tooltipGroupRender, labelRender, labelResolve, onUpdateRects, Component = 'div', SvgProps, TypeProps, TitleProps, SubtitleProps, PointsProps, PointProps, HeaderProps, AppendProps, AdditionalLineProps, AdditionalLinesProps, LegendProps, LegendItemProps, GuidelineProps, WrapperProps, className, children } = props, other = __rest(props, ["tonal", "color", "title", "subtitle", "values", "pre", "elements", "names", "nameX", "nameY", "tooltip", "tooltipIndividually", "tooltipCloseOnMouseLeave", "elementTooltip", "guidelines", "guidelinesAppend", "guidelinesDisplayInactive", "additionalLines", "legend", "legendManageVisibility", "legendPosition", "animate", "animateTimeout", "labels", "labelsX", "labelsY", "labelDecimalPlaces", "labelsAutoNumber", "labelsYAutoNumber", "labelsXAutoNumber", "marks", "marksX", "marksY", "marksAutoNumber", "marksYAutoNumber", "marksXAutoNumber", "grid", "gridX", "gridY", "gridAutoNumber", "gridYAutoNumber", "gridXAutoNumber", "points", "pointsVisibility", "borders", "borderStart", "borderLeft", "borderEnd", "borderRight", "borderTop", "borderBottom", "minX", "maxX", "minY", "maxY", "minMaxPadding", "minPadding", "maxPadding", "minPaddingX", "minPaddingY", "maxPaddingX", "maxPaddingY", "noMain", "tooltipRender", "tooltipGroupRender", "labelRender", "labelResolve", "onUpdateRects", "Component", "SvgProps", "TypeProps", "TitleProps", "SubtitleProps", "PointsProps", "PointProps", "HeaderProps", "AppendProps", "AdditionalLineProps", "AdditionalLinesProps", "LegendProps", "LegendItemProps", "GuidelineProps", "WrapperProps", "className", "children"]);
const { classes } = useStyle();
const refs = {
root: react_1.default.useRef(undefined),
wrapper: react_1.default.useRef(undefined),
svg: react_1.default.useRef(undefined),
defs: react_1.default.useRef(undefined),
minMax: react_1.default.useRef(undefined),
rects: react_1.default.useRef(undefined),
guidelines: react_1.default.useRef(undefined),
guidelinesIn: react_1.default.useRef(undefined),
guidelinesPosition: react_1.default.useRef(undefined),
guidelinesAppend: react_1.default.useRef(undefined),
hover: react_1.default.useRef(undefined),
allValues: react_1.default.useRef([]),
values: react_1.default.useRef([]),
visible: react_1.default.useRef([]),
appendStyle: react_1.default.useRef({}),
theme: react_1.default.useRef([])
};
const keys = react_1.default.useMemo(() => {
const result = [];
const items = [nameX_, nameY_, tooltip_, tooltipIndividually_, tooltipCloseOnMouseLeave_, elementTooltip_, guidelines_, guidelinesAppend_, guidelinesDisplayInactive_, animate_, animateTimeout_, legend___, labels___, labelsX_, labelsY_, labelDecimalPlaces_, labelsAutoNumber_, labelsYAutoNumber_, labelsXAutoNumber_, marks___, marksX_, marksY_, marksAutoNumber_, marksYAutoNumber_, marksXAutoNumber_, grid___, gridX_, gridY_, gridAutoNumber_, gridYAutoNumber_, gridXAutoNumber_, points___, pointsVisibility_,];
items.forEach(item => {
if ((0, utils_1.is)('object', item))
Object.keys(item).filter(key => theme.breakpoints.media[key]).forEach(key => result.push(key));
});
return (0, utils_1.unique)(result);
}, [nameX_, nameY_, tooltip_, tooltipIndividually_, tooltipCloseOnMouseLeave_, elementTooltip_, guidelines_, guidelinesAppend_, guidelinesDisplayInactive_, animate_, animateTimeout_, legend___, labels___, labelsX_, labelsY_, labelDecimalPlaces_, labelsAutoNumber_, labelsYAutoNumber_, labelsXAutoNumber_, marks___, marksX_, marksY_, marksAutoNumber_, marksYAutoNumber_, marksXAutoNumber_, grid___, gridX_, gridY_, gridAutoNumber_, gridYAutoNumber_, gridXAutoNumber_, points___, pointsVisibility_, borders_, borderStart_, borderLeft_, borderEnd_, borderRight_, borderTop_, borderBottom_, minX_, maxX_, minY_, maxY_, minMaxPadding__, minPadding__, maxPadding__, minPaddingX__, minPaddingY__, maxPaddingX__, maxPaddingY__]);
const breakpoints = {};
keys.forEach(key => {
breakpoints[key] = (0, useMediaQuery_1.default)(theme.breakpoints.media[key], { element: refs.root.current });
});
const nameX = (0, utils_2.valueBreakpoints)(nameX_, undefined, breakpoints, theme);
const nameY = (0, utils_2.valueBreakpoints)(nameY_, undefined, breakpoints, theme);
const tooltip = (0, utils_2.valueBreakpoints)(tooltip_, true, breakpoints, theme);
const tooltipIndividually = (0, utils_2.valueBreakpoints)(tooltipIndividually_, true, breakpoints, theme);
const tooltipCloseOnMouseLeave = (0, utils_2.valueBreakpoints)(tooltipCloseOnMouseLeave_, true, breakpoints, theme);
const elementTooltip = (0, utils_2.valueBreakpoints)(elementTooltip_, undefined, breakpoints, theme);
const guidelines = (0, utils_2.valueBreakpoints)(guidelines_, undefined, breakpoints, theme);
const guidelinesAppend = (0, utils_2.valueBreakpoints)(guidelinesAppend_, true, breakpoints, theme);
const guidelinesDisplayInactive = (0, utils_2.valueBreakpoints)(guidelinesDisplayInactive_, false, breakpoints, theme);
const animate = (0, utils_2.valueBreakpoints)(animate_, true, breakpoints, theme);
const animateTimeout = (0, utils_2.valueBreakpoints)(animateTimeout_, 140, breakpoints, theme);
const legend__ = (0, utils_2.valueBreakpoints)(legend___, 'auto', breakpoints, theme);
const labels__ = (0, utils_2.valueBreakpoints)(labels___, 'auto', breakpoints, theme);
const labelsX = (0, utils_2.valueBreakpoints)(labelsX_, true, breakpoints, theme);
const labelsY = (0, utils_2.valueBreakpoints)(labelsY_, true, breakpoints, theme);
const labelDecimalPlaces = (0, utils_2.valueBreakpoints)(labelDecimalPlaces_, 0, breakpoints, theme);
const labelsAutoNumber = (0, utils_2.valueBreakpoints)(labelsAutoNumber_, 10, breakpoints, theme);
const labelsYAutoNumber = (0, utils_2.valueBreakpoints)(labelsYAutoNumber_, undefined, breakpoints, theme);
const labelsXAutoNumber = (0, utils_2.valueBreakpoints)(labelsXAutoNumber_, undefined, breakpoints, theme);
const marks__ = (0, utils_2.valueBreakpoints)(marks___, 'auto', breakpoints, theme);
const marksX = (0, utils_2.valueBreakpoints)(marksX_, true, breakpoints, theme);
const marksY = (0, utils_2.valueBreakpoints)(marksY_, true, breakpoints, theme);
const marksAutoNumber = (0, utils_2.valueBreakpoints)(marksAutoNumber_, 10, breakpoints, theme);
const marksYAutoNumber = (0, utils_2.valueBreakpoints)(marksYAutoNumber_, undefined, breakpoints, theme);
const marksXAutoNumber = (0, utils_2.valueBreakpoints)(marksXAutoNumber_, undefined, breakpoints, theme);
const grid__ = (0, utils_2.valueBreakpoints)(grid___, undefined, breakpoints, theme);
const gridX = (0, utils_2.valueBreakpoints)(gridX_, true, breakpoints, theme);
const gridY = (0, utils_2.valueBreakpoints)(gridY_, true, breakpoints, theme);
const gridAutoNumber = (0, utils_2.valueBreakpoints)(gridAutoNumber_, 10, breakpoints, theme);
const gridYAutoNumber = (0, utils_2.valueBreakpoints)(gridYAutoNumber_, undefined, breakpoints, theme);
const gridXAutoNumber = (0, utils_2.valueBreakpoints)(gridXAutoNumber_, undefined, breakpoints, theme);
const points__ = (0, utils_2.valueBreakpoints)(points___, true, breakpoints, theme);
const pointsVisibility = (0, utils_2.valueBreakpoints)(pointsVisibility_, 'hover', breakpoints, theme);
const borders = (0, utils_2.valueBreakpoints)(borders_, true, breakpoints, theme);
const borderStart = (0, utils_2.valueBreakpoints)(borderStart_, false, breakpoints, theme);
const borderLeft = (0, utils_2.valueBreakpoints)(borderLeft_, true, breakpoints, theme);
const borderEnd = (0, utils_2.valueBreakpoints)(borderEnd_, false, breakpoints, theme);
const borderRight = (0, utils_2.valueBreakpoints)(borderRight_, false, breakpoints, theme);
const borderTop = (0, utils_2.valueBreakpoints)(borderTop_, false, breakpoints, theme);
const borderBottom = (0, utils_2.valueBreakpoints)(borderBottom_, true, breakpoints, theme);
const minX = (0, utils_2.valueBreakpoints)(minX_, undefined, breakpoints, theme);
const maxX = (0, utils_2.valueBreakpoints)(maxX_, undefined, breakpoints, theme);
const minY = (0, utils_2.valueBreakpoints)(minY_, undefined, breakpoints, theme);
const maxY = (0, utils_2.valueBreakpoints)(maxY_, undefined, breakpoints, theme);
const minMaxPadding = (0, utils_2.valueBreakpoints)(minMaxPadding__, undefined, breakpoints, theme);
const minPadding = (0, utils_2.valueBreakpoints)(minPadding__, undefined, breakpoints, theme);
const maxPadding = (0, utils_2.valueBreakpoints)(maxPadding__, undefined, breakpoints, theme);
const minPaddingX = (0, utils_2.valueBreakpoints)(minPaddingX__, undefined, breakpoints, theme);
const minPaddingY = (0, utils_2.valueBreakpoints)(minPaddingY__, undefined, breakpoints, theme);
const maxPaddingX = (0, utils_2.valueBreakpoints)(maxPaddingX__, undefined, breakpoints, theme);
const maxPaddingY = (0, utils_2.valueBreakpoints)(maxPaddingY__, undefined, breakpoints, theme);
const [rects, setRects] = react_1.default.useState();
const [points, setPoints] = react_1.default.useState();
const [labels, setLabels] = react_1.default.useState();
const [marks, setMarks] = react_1.default.useState();
const [grid, setGrid] = react_1.default.useState();
const [additionalLines, setAdditionalLines] = react_1.default.useState();
const [legend, setLegend] = react_1.default.useState([]);
const [defs, setDefs] = react_1.default.useState([]);
const [append, setAppend] = react_1.default.useState();
const [visible, setVisible] = react_1.default.useState({});
const [guidelinesIn, setGuidelineIn] = react_1.default.useState(false);
const [guidelinesPosition, setGuidelinePosition] = react_1.default.useState({});
const [hover, setHover] = react_1.default.useState(false);
refs.rects.current = rects;
refs.guidelines.current = guidelines;
refs.guidelinesIn.current = guidelinesIn;
refs.guidelinesPosition.current = guidelinesPosition;
refs.guidelinesAppend.current = guidelinesAppend;
refs.hover.current = hover;
refs.values.current = values;
refs.visible.current = visible;
refs.theme.current = theme;
const minMax = react_1.default.useMemo(() => {
const values_ = {
min: {
x: minX || Number.MAX_SAFE_INTEGER,
y: minY || Number.MAX_SAFE_INTEGER
},
max: {
x: maxX || Number.MIN_SAFE_INTEGER,
y: maxY || Number.MIN_SAFE_INTEGER
}
};
if (!noMain) {
const allItems = values.flatMap(item => (0, utils_1.is)('array', item.values[0]) ? item.values : [item.values]);
if ((0, utils_1.is)('array', values)) {
allItems.forEach((item) => {
const [x, y] = item;
if (minX === undefined)
values_.min.x = Math.min(values_.min.x, x);
if (maxX === undefined)
values_.max.x = Math.max(values_.max.x, x);
if (minY === undefined)
values_.min.y = Math.min(values_.min.y, y);
if (maxY === undefined)
values_.max.y = Math.max(values_.max.y, y);
});
}
const minPaddingY_ = minPaddingY !== undefined ? minPaddingY : minPadding !== undefined ? minPadding : minMaxPadding;
const maxPaddingY_ = maxPaddingY !== undefined ? maxPaddingY : maxPadding !== undefined ? maxPadding : minMaxPadding;
const minPaddingX_ = minPaddingX !== undefined ? minPaddingX : minPadding !== undefined ? minPadding : minMaxPadding;
const maxPaddingX_ = maxPaddingX !== undefined ? maxPaddingX : maxPadding !== undefined ? maxPadding : minMaxPadding;
const totals = {
x: values_.max.x - values_.min.x,
y: values_.max.y - values_.min.y
};
if (minPaddingY_ !== undefined)
values_.min.y -= totals.y * minPaddingY_;
if (maxPaddingY_ !== undefined)
values_.max.y += totals.y * maxPaddingY_;
if (minPaddingX_ !== undefined)
values_.min.x -= totals.x * minPaddingX_;
if (maxPaddingX_ !== undefined)
values_.max.x += totals.x * maxPaddingX_;
}
return values_;
}, [values, minX, maxX, minY, maxY, minMaxPadding, minPadding, maxPadding, minPaddingX, minPaddingY, maxPaddingX, maxPaddingY, noMain]);
refs.minMax.current = minMax;
const onWrapperMouseEnter = react_1.default.useCallback(() => {
if (!refs.guidelinesIn.current)
setGuidelineIn(true);
setHover(true);
}, []);
const onWrapperMouseLeave = react_1.default.useCallback(() => {
setHover(false);
setTimeout(() => {
if (tooltipCloseOnMouseLeave)
setAppend(values_ => (Object.assign(Object.assign({}, values_), { open: false })));
if (!guidelinesDisplayInactive)
setGuidelineIn(false);
setGuidelinePosition({});
});
}, [tooltipCloseOnMouseLeave, guidelinesDisplayInactive]);
const makeGroupTooltip = (x_, y_) => {
const items = refs.allValues.current.filter(item => item.normalized[0] === x_);
const itemsY = (0, utils_1.copy)(items).sort((a, b) => a.normalized[1] - b.normalized[1]);
const x = x_;
const y = itemsY[0].normalized[1];
const groups = {};
items.forEach(item => {
var _a;
const color_ = ((_a = item.item) === null || _a === void 0 ? void 0 : _a.color) || 'primary';
if (!groups[color_])
groups[color_] = [];
groups[color_].push(item);
});
// Group sorted by y largest, to smallest
Object.keys(groups).forEach(group => groups[group].sort((a, b) => { var _a, _b; return ((_a = a.normalized) === null || _a === void 0 ? void 0 : _a[1]) - ((_b = b.normalized) === null || _b === void 0 ? void 0 : _b[1]); }));
// Groups sorted by y largest, to smallest
const groupsSorted = Object.keys(groups).sort((a, b) => { var _a, _b, _c, _d; return ((_b = (_a = groups[a][0]) === null || _a === void 0 ? void 0 : _a.normalized) === null || _b === void 0 ? void 0 : _b[1]) - ((_d = (_c = groups[b][0]) === null || _c === void 0 ? void 0 : _c.normalized) === null || _d === void 0 ? void 0 : _d[1]); });
const element = (0, utils_1.is)('function', tooltipGroupRender) ? tooltipGroupRender(groups, groupsSorted) : ((0, jsx_runtime_1.jsx)(Line, Object.assign({ tonal: tonal, color: color, elevation: 1, gap: 0.25, direction: 'column', Component: Surface, className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Chart', theme) && [
'amaui-Chart-append'
],
classes.append
]) }, { children: (0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 1, direction: 'column', style: {
width: '100%'
} }, { children: [(0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 1, direction: 'row', align: 'center' }, { children: [(0, jsx_runtime_1.jsx)(Type, Object.assign({ version: 'b3', style: {
fontWeight: 600
} }, { children: (names === null || names === void 0 ? void 0 : names.y) || 'y' })), (0, jsx_runtime_1.jsx)(Type, Object.assign({ version: 'b3', style: {
fontWeight: 600
} }, { children: (names === null || names === void 0 ? void 0 : names.x) || 'x' }))] })), (0, jsx_runtime_1.jsx)(Line, Object.assign({ gap: 1, direction: 'column' }, { children: groupsSorted.map((group, index) => {
var _a, _b;
return ((0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 1, direction: 'column', style: {
width: '100%'
} }, { children: [(0, jsx_runtime_1.jsx)("span", { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Chart', theme) && [
'amaui-Chart-append-icon'
],
classes.append_icon
]), style: {
background: !refs.theme.current.palette.color[group] ? group : refs.theme.current.palette.color[group][((_b = (_a = groups[group][0]) === null || _a === void 0 ? void 0 : _a.item) === null || _b === void 0 ? void 0 : _b.tone) || 'main']
} }), (0, jsx_runtime_1.jsx)(Line, Object.assign({ gap: 0, direction: 'column', style: {
width: '100%'
} }, { children: groups[group].map((item, index_) => {
var _a, _b, _c, _d;
return ((0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 1, direction: 'row', style: {
width: '100%'
} }, { children: [(0, jsx_runtime_1.jsx)(Type, Object.assign({ version: 'b3' }, { children: (0, utils_1.is)('function', labelResolve) ? labelResolve((_a = item === null || item === void 0 ? void 0 : item.values) === null || _a === void 0 ? void 0 : _a[1], 'y', item, 'group') : (_b = item === null || item === void 0 ? void 0 : item.values) === null || _b === void 0 ? void 0 : _b[1] })), (0, jsx_runtime_1.jsx)(Type, Object.assign({ version: 'b3' }, { children: (0, utils_1.is)('function', labelResolve) ? labelResolve((_c = item === null || item === void 0 ? void 0 : item.values) === null || _c === void 0 ? void 0 : _c[0], 'x', item, 'group') : (_d = item === null || item === void 0 ? void 0 : item.values) === null || _d === void 0 ? void 0 : _d[0] }))] }), index_));
}) }))] }), index));
}) }))] })) })));
const rectSvg = refs.svg.current.getBoundingClientRect();
const width = 8;
const height = 8;
const rect_ = {
x: (x + rectSvg.x) - width,
y: (y + rectSvg.y) - width,
width,
height
};
rect_.top = rect_.y;
rect_.bottom = rect_.y + height;
rect_.left = rect_.x;
rect_.right = rect_.x + width;
setAppend({
open: true,
element,
rect: rect_
});
};
react_1.default.useEffect(() => {
var _a;
const onMove = (x_, y_) => {
var _a, _b, _c, _d, _e, _f;
// Only horizontal move at the moment
// ie. vertical guidelines
const rectWrapper = refs.rects.current.wrapper;
const rectSvg = refs.svg.current.getBoundingClientRect();
let x = (0, utils_1.clamp)(x_ - (rectSvg === null || rectSvg === void 0 ? void 0 : rectSvg.x), 0, rectWrapper === null || rectWrapper === void 0 ? void 0 : rectWrapper.width);
const y = (0, utils_1.clamp)(y_ - (rectSvg === null || rectSvg === void 0 ? void 0 : rectSvg.y), 0, rectWrapper === null || rectWrapper === void 0 ? void 0 : rectWrapper.height);
if (refs.guidelinesAppend.current && ['both', 'vertical'].includes(refs.guidelines.current)) {
const allValues = refs.allValues.current;
let index;
let previous;
let item;
for (let i = 0; i < allValues.length; i++) {
previous = allValues[i - 1];
item = allValues[i];
if (((_a = previous === null || previous === void 0 ? void 0 : previous.normalized) === null || _a === void 0 ? void 0 : _a[0]) <= x && x <= ((_b = item === null || item === void 0 ? void 0 : item.normalized) === null || _b === void 0 ? void 0 : _b[0])) {
index = i;
break;
}
}
if (index === undefined) {
index = x <= ((_d = (_c = allValues[0]) === null || _c === void 0 ? void 0 : _c.normalized) === null || _d === void 0 ? void 0 : _d[0]) ? 0 : allValues.length - 1;
previous = allValues[index - 1];
item = allValues[index];
}
if (previous || item) {
if (!previous)
x = (_e = item.normalized) === null || _e === void 0 ? void 0 : _e[0];
else if (!item)
x = (_f = previous.normalized) === null || _f === void 0 ? void 0 : _f[0];
else {
const len = item.normalized[0] - previous.normalized[0];
const part = len / 2;
x = x < (previous.normalized[0] + part) ? previous.normalized[0] : item.normalized[0];
}
}
makeGroupTooltip(x, y);
}
setGuidelinePosition(value_ => (Object.assign(Object.assign({}, value_), { x,
y })));
};
const onMouseMove = (event) => {
if (refs.hover.current) {
const x = event.clientX;
const y = event.clientY;
onMove(x, y);
}
};
const onTouchMove = (event) => {
if (refs.hover.current) {
const x = event.touches[0].clientX;
const y = event.touches[0].clientY;
onMove(x, y);
}
};
const method = () => {
if (refs.wrapper.current) {
const rectWrapper = refs.wrapper.current.getBoundingClientRect();
const rectSvg = refs.svg.current.getBoundingClientRect();
const rects_ = {
wrapper: rectWrapper,
svg: rectSvg
};
setRects(rects_);
if ((0, utils_1.is)('function', onUpdateRects))
onUpdateRects(rects_);
}
};
method();
const observer = new ResizeObserver(method);
observer.observe(refs.root.current);
const rootDocument = (0, utils_1.isEnvironment)('browser') ? (((_a = refs.root.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) || window.document) : undefined;
rootDocument.addEventListener('mousemove', onMouseMove);
rootDocument.addEventListener('touchmove', onTouchMove);
rootDocument.addEventListener('touchend', onWrapperMouseLeave);
return () => {
observer.disconnect();
rootDocument.removeEventListener('mousemove', onMouseMove);
rootDocument.removeEventListener('touchmove', onTouchMove);
rootDocument.removeEventListener('touchend', onWrapperMouseLeave);
};
}, []);
react_1.default.useEffect(() => {
make();
}, [values, labels__, marks__, grid__, additionalLines__, legend__, visible, (guidelinesAppend && guidelinesPosition), rects, theme]);
const onPointMouseEnter = react_1.default.useCallback((values_) => {
if (tooltipIndividually) {
setAppend(Object.assign(Object.assign({}, ((0, utils_1.is)('function', tooltipRender) ? tooltipRender(values_) : values_)), { rect: values_.rect, open: true }));
}
}, [tooltipRender, tooltipIndividually]);
const onPointMouseLeave = react_1.default.useCallback(() => {
setAppend(append_ => (Object.assign(Object.assign({}, append_), { open: false })));
}, []);
const onLegendClick = (value) => {
if (value !== undefined && legendManageVisibility) {
setVisible((visible_) => (Object.assign(Object.assign({}, visible_), { [value]: ![undefined, true].includes(visible_[value]) })));
}
};
const LegendItem = react_1.default.useCallback((props__) => {
const { item = {}, className: className_ } = props__, other_ = __rest(props__, ["item", "className"]);
const { color: color_, tone = 'main', name = 'No name' } = item;
return ((0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 1, direction: 'row', align: 'center' }, LegendItemProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Chart', theme) && [
'amaui-Chart-legend-item'
],
className_,
LegendItemProps === null || LegendItemProps === void 0 ? void 0 : LegendItemProps.className,
classes.legend_item
]) }, other_, { children: [(0, jsx_runtime_1.jsx)("span", { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Chart', theme) && [
'amaui-Chart-legend-icon'
],
classes.legend_icon
]), style: {
color: !theme.palette.color[color_] ? color_ : theme.palette.color[color_][tone],
background: !theme.palette.color[color_] ? color_ : theme.palette.color[color_][tone]
} }), (0, jsx_runtime_1.jsx)(Type, Object.assign({ version: 'b2' }, { children: name }))] })));
}, [theme]);
const make = (valueNew = refs.values.current) => {
// Make values into x, y, coordinates
// normalized in rect width, height values
// invert y so 0, 0 is at bottom left
if (refs.rects.current && valueNew && !noMain) {
const { width, height } = refs.rects.current.wrapper;
// Labels
const labels_ = {
x: (0, utils_1.is)('array', labels__ === null || labels__ === void 0 ? void 0 : labels__.x) ? labels__.x : (0, utils_2.minMaxBetweenNumbers)(labelsXAutoNumber !== undefined ? labelsXAutoNumber : labelsAutoNumber !== undefined ? labelsAutoNumber : 10, refs.minMax.current.min.x, refs.minMax.current.max.x).map(item => ({
value: item,
label: (0, utils_1.castParam)((item).toFixed(labelDecimalPlaces || 0))
})),
y: (0, utils_1.is)('array', labels__ === null || labels__ === void 0 ? void 0 : labels__.y) ? labels__.y : (0, utils_2.minMaxBetweenNumbers)(labelsYAutoNumber !== undefined ? labelsYAutoNumber : labelsAutoNumber !== undefined ? labelsAutoNumber : 10, refs.minMax.current.min.y, refs.minMax.current.max.y).map(item => ({
value: item,
label: (0, utils_1.castParam)((item).toFixed(labelDecimalPlaces || 0))
}))
};
labels_.x = labels_.x.map(item => (Object.assign(Object.assign({}, item), { percentage: (0, utils_1.percentageFromValueWithinRange)(item.value, refs.minMax.current.min.x, refs.minMax.current.max.x) })));
labels_.y = labels_.y.map(item => (Object.assign(Object.assign({}, item), { percentage: (0, utils_1.percentageFromValueWithinRange)(item.value, refs.minMax.current.min.y, refs.minMax.current.max.y) })));
// Marks
const marks_ = {
x: (0, utils_1.is)('array', marks__ === null || marks__ === void 0 ? void 0 : marks__.x) ? marks__.x : (0, utils_2.minMaxBetweenNumbers)(marksXAutoNumber !== undefined ? marksXAutoNumber : marksAutoNumber !== undefined ? marksAutoNumber : 10, refs.minMax.current.min.x, refs.minMax.current.max.x).map(item => ({
value: item
})),
y: (0, utils_1.is)('array', marks__ === null || marks__ === void 0 ? void 0 : marks__.y) ? marks__.y : (0, utils_2.minMaxBetweenNumbers)(marksYAutoNumber !== undefined ? marksYAutoNumber : marksAutoNumber !== undefined ? marksAutoNumber : 10, refs.minMax.current.min.y, refs.minMax.current.max.y).map(item => ({
value: item
}))
};
marks_.x = marks_.x.map(item => (Object.assign(Object.assign({}, item), { percentage: (0, utils_1.percentageFromValueWithinRange)(item.value, refs.minMax.current.min.x, refs.minMax.current.max.x) })));
marks_.y = marks_.y.map(item => (Object.assign(Object.assign({}, item), { percentage: (0, utils_1.percentageFromValueWithinRange)(item.value, refs.minMax.current.min.y, refs.minMax.current.max.y) })));
// Grid
const grid_ = {
x: (0, utils_1.is)('array', grid__ === null || grid__ === void 0 ? void 0 : grid__.x) ? grid__.x : (0, utils_2.minMaxBetweenNumbers)(gridXAutoNumber !== undefined ? gridXAutoNumber : gridAutoNumber !== undefined ? gridAutoNumber : 10, refs.minMax.current.min.x, refs.minMax.current.max.x).map(item => ({
value: item
})),
y: (0, utils_1.is)('array', grid__ === null || grid__ === void 0 ? void 0 : grid__.y) ? grid__.y : (0, utils_2.minMaxBetweenNumbers)(gridYAutoNumber !== undefined ? gridYAutoNumber : gridAutoNumber !== undefined ? gridAutoNumber : 10, refs.minMax.current.min.y, refs.minMax.current.max.y).map(item => ({
value: item
}))
};
grid_.x = grid_.x.map(item => (Object.assign(Object.assign({}, item), { percentage: (0, utils_1.percentageFromValueWithinRange)(item.value, refs.minMax.current.min.x, refs.minMax.current.max.x) })));
grid_.y = grid_.y.map(item => (Object.assign(Object.assign({}, item), { percentage: (0, utils_1.percentageFromValueWithinRange)(item.value, refs.minMax.current.min.y, refs.minMax.current.max.y) })));
refs.allValues.current = [];
// Points
const points_ = (0, utils_1.copy)(valueNew).flatMap(item => {
var _a;
const { color: color_, tone = 'main', name } = item;
const itemValues = ([x, y, ...args]) => {
const values__ = {
x: (0, utils_1.percentageFromValueWithinRange)(x, refs.minMax.current.min.x, refs.minMax.current.max.x),
y: (0, utils_1.percentageFromValueWithinRange)(y, refs.minMax.current.min.y, refs.minMax.current.max.y)
};
values__.x = (0, utils_1.valueFromPercentageWithinRange)(values__.x, 0, width);
values__.y = (0, utils_1.valueFromPercentageWithinRange)(values__.y, 0, height);
if (refs.visible.current[name] !== false) {
refs.allValues.current.push({
item,
values: [x, y, ...args],
normalized: [values__.x, height - values__.y].map(item_ => Math.abs(item_))
});
}
return {
values: [x, y, ...args],
normalized: [values__.x, height - values__.y].map(item_ => Math.abs(item_))
};
};
const itemArrayNested = (0, utils_1.is)('array', (_a = item.values) === null || _a === void 0 ? void 0 : _a[0]);
const values_ = itemArrayNested ? (0, utils_1.copy)(item.values)
// Sort for x from smallest to largest
.sort((a, b) => a[0] - b[0])
.map(itemValues) : [itemValues(item.values)];
return values_.map((item_, index) => ((0, jsx_runtime_1.jsx)(Path, Object.assign({ Component: 'circle', r: 4, cx: item_.normalized[0], cy: item_.normalized[1], fill: !theme.palette.color[color_] ? color_ : theme.palette.color[color_][tone], stroke: 'none' }, (!elementTooltip ? {
onMouseEnter: event => {
const rect_ = event.target.getBoundingClientRect();
onPointMouseEnter({
values: item_.values,
rect: rect_
});
},
onMouseLeave: onPointMouseLeave
} : undefined), PointProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Chart', theme) && [
'amaui-Chart-point'
],
PointProps === null || PointProps === void 0 ? void 0 : PointProps.className,
classes.point,
classes[`point_visibility_${pointsVisibility}`],
(refs.guidelinesAppend.current && refs.guidelinesPosition.current.x === item_.normalized[0]) && classes.point_active
]), style: Object.assign(Object.assign({}, (refs.visible.current[name] === false ? {
opacity: 0,
pointerEvents: 'none'
} : undefined)), PointProps === null || PointProps === void 0 ? void 0 : PointProps.style) }), index)));
});
refs.allValues.current.sort((a, b) => (a === null || a === void 0 ? void 0 : a.normalized[0]) - (b === null || b === void 0 ? void 0 : b.normalized[0]));
// Guidelines
const additionalLines_ = additionalLines__ && additionalLines__.map((item, index) => {
const { color: color_, tone = 'main', style } = item;
const values_ = {
x1: (0, utils_1.percentageFromValueWithinRange)(item.x1, refs.minMax.current.min.x, refs.minMax.current.max.x),
y1: (0, utils_1.percentageFromValueWithinRange)(item.y1, refs.minMax.current.min.y, refs.minMax.current.max.y),
x2: (0, utils_1.percentageFromValueWithinRange)(item.x2, refs.minMax.current.min.x, refs.minMax.current.max.x),
y2: (0, utils_1.percentageFromValueWithinRange)(item.y2, refs.minMax.current.min.y, refs.minMax.current.max.y),
};
values_.x1 = (0, utils_1.valueFromPercentageWithinRange)(values_.x1, 0, width);
values_.y1 = (0, utils_1.valueFromPercentageWithinRange)(values_.y1, 0, height);
values_.x2 = (0, utils_1.valueFromPercentageWithinRange)(values_.x2, 0, width);
values_.y2 = (0, utils_1.valueFromPercentageWithinRange)(values_.y2, 0, height);
return ((0, jsx_runtime_1.jsx)(Path, Object.assign({ d: `M ${values_.x1} ${height - values_.y1} L ${values_.x2} ${height - values_.y2}`, fill: 'none', stroke: !theme.palette.color[color_] ? color_ : theme.palette.color[color_][tone] }, AdditionalLineProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Chart', theme) && [
'amaui-Chart-additional-lines'
],
AdditionalLineProps === null || AdditionalLineProps === void 0 ? void 0 : AdditionalLineProps.className,
classes.additionalLines
]), style: Object.assign(Object.assign({}, style), AdditionalLineProps === null || AdditionalLineProps === void 0 ? void 0 : AdditionalLineProps.style) }), index));
});
// Labels
setLabels(labels_);
// Marks
setMarks(marks_);
// Grid
setGrid(grid_);
// Guidelines
setAdditionalLines(additionalLines_);
// Update children value
setPoints(points_);
}
// Legend
const legend_ = legend__ !== 'auto' ? legend__ : [];
if (legend__ === 'auto') {
const map = {};
values.forEach((item) => {
const name = (item === null || item === void 0 ? void 0 : item.name) || '';
if (!map[name]) {
legend_.push({
item,
element: ((0, jsx_runtime_1.jsx)(LegendItem, { item: item }))
});
map[name] = true;
}
});
}
// Legend
if ((0, utils_1.is)('array', legend_))
setLegend(legend_);
};
return ((0, jsx_runtime_1.jsxs)(Surface, Object.assign({ ref: item => {
if (ref) {
if ((0, utils_1.is)('function', ref))
ref(item);
else
ref.current = item;
}
refs.root.current = item;
}, tonal: tonal, color: color, gap: 0, direction: 'column', align: 'center', Component: Line, AdditionalProps: {
Component
}, className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Chart', theme) && [
'amaui-Chart-root'
],
className,
classes.root
]) }, other, { children: [(title || subtitle) && ((0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 0.5, align: 'center', justify: 'center' }, HeaderProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Chart', theme) && [
'amaui-Chart-header'
],
HeaderProps === null || HeaderProps === void 0 ? void 0 : HeaderProps.className,
classes.header,
((labels === null || labels === void 0 ? void 0 : labels.y) && labelsY) && classes.legend_offset_labels_y,
((names === null || names === void 0 ? void 0 : names.y) && nameY) && classes.legend_offset_names_y
]) }, { children: [(0, utils_1.is)('simple', title) ? ((0, jsx_runtime_1.jsx)(Type, Object.assign({ version: 't2' }, TypeProps, TitleProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Chart', theme) && [
'amaui-Chart-title'
],
TypeProps === null || TypeProps === void 0 ? void 0 : TypeProps.className,
TitleProps === null || TitleProps === void 0 ? void 0 : TitleProps.className,
classes.title
]) }, { children: title }))) : title, (0, utils_1.is)('simple', subtitle) ? ((0, jsx_runtime_1.jsx)(Type, Object.assign({ version: 'b3' }, TypeProps, SubtitleProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Chart', theme) && [
'amaui-Chart-title'
],
TypeProps === null || TypeProps === void 0 ? void 0 : TypeProps.className,
SubtitleProps === null || SubtitleProps === void 0 ? void 0 : SubtitleProps.className,
classes.subtitle
]) }, {