@apptane/react-ui-charts
Version:
Chart components in Apptane React UI framework
175 lines (157 loc) • 7.02 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
const _excluded = ["theme", "colorMode", "slice", "computed", "domainX", "domainY", "format", "tooltipTotalVisible", "width", "offset"];
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
import { Pane } from "@apptane/react-ui-pane";
import { Tooltip } from "@apptane/react-ui-tooltip";
import { Text } from "@apptane/react-ui-typography";
import { useLayoutEffect, useRef, useState } from "react";
import { ChartMarker } from "../parts/ChartMarker.js";
import { findValue } from "./common.js";
import { formatNumericTooltip } from "./commonXY.js";
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
import { jsxs as _jsxs } from "@emotion/react/jsx-runtime";
export function XYChartTooltip(_ref) {
var _slice$x;
let {
theme,
colorMode,
slice,
computed,
domainX,
domainY,
format,
tooltipTotalVisible,
width,
offset = 0
} = _ref,
other = _objectWithoutProperties(_ref, _excluded);
const visualAppearance = theme.charts.xy.appearance(theme.palette[colorMode], colorMode, undefined, "none");
const visualStyle = theme.charts.xy.style;
const formatter = format !== null && format !== void 0 ? format : formatNumericTooltip;
const containerRef = useRef(null);
let hasValues = false;
let total = 0;
const items = [];
if (computed != null && domainX != null && slice.domainXIndex != null) {
// use domain index to locate the corresponding value
const dx = domainX.values[slice.domainXIndex];
const dy = domainY != null && slice.domainYIndex != null ? domainY.values[slice.domainYIndex] : undefined;
if (dx != null) {
computed.forEach((d, index) => {
var _d$color;
let formattedValue = "—"; // indicates XYZ situation
if (domainY != null) {
if (dy != null) {
const p = findValue(d, p => domainX.isEqual(p.x, dx) && domainY.isEqual(p.y, dy));
if (p != null && typeof p.z === "number" && isFinite(p.z)) {
total += p.z;
formattedValue = formatter(p.z);
hasValues = true;
}
}
} else {
const p = findValue(d, p => domainX.isEqual(p.x, dx));
if (p != null && typeof p.y === "number" && isFinite(p.y)) {
total += p.y;
let lb;
let ub;
if (d.bands != null) {
const band = d.bands.find(p => domainX.isEqual(p.x, dx));
if (band != null && typeof band.y0 === "number" && isFinite(band.y0) && typeof band.y1 === "number" && isFinite(band.y1)) {
lb = band.y0;
ub = band.y1;
}
}
formattedValue = formatter(p.y, lb, ub);
hasValues = true;
}
}
items.push(_jsxs(Pane, {
verticalAlignment: "center",
orientation: "horizontal",
overflow: "hidden",
children: [_jsx(ChartMarker, _objectSpread({
theme: theme,
colorMode: colorMode,
color: (_d$color = d.color) !== null && _d$color !== void 0 ? _d$color : ""
}, other)), _jsx(Text, _objectSpread(_objectSpread({
color: visualAppearance.tooltip.label
}, visualStyle.font.tooltip.label), {}, {
marginLeft: visualStyle.tooltip.markerSpacing,
nowrap: true,
ellipsis: true,
children: d.label
})), _jsx(Pane, {
grow: 1,
verticalAlignment: "center",
horizontalAlignment: "right",
orientation: "horizontal",
children: _jsx(Text, _objectSpread(_objectSpread({
alignment: "right",
color: visualAppearance.tooltip.value
}, visualStyle.font.tooltip.value), {}, {
marginLeft: visualStyle.tooltip.valueSpacing,
nowrap: true,
children: formattedValue
}))
})]
}, "_".concat(index)));
});
}
}
const top = slice.y != null ? Math.max(0, slice.y) : 0;
const position = Math.max(0, (_slice$x = slice.x) !== null && _slice$x !== void 0 ? _slice$x : 0);
const [left, setLeft] = useState(position);
useLayoutEffect(() => {
if (containerRef.current != null) {
const containerWidth = Math.round(containerRef.current.getBoundingClientRect().width);
setLeft(position >= width - offset - containerWidth ? Math.max(0, position - offset - containerWidth) : position + offset);
}
}, [position, offset, width]);
if (items.length === 0 || !hasValues) {
return null;
}
return _jsx("div", {
ref: containerRef,
style: {
left: Math.round(left),
top: Math.round(top),
transform: slice.y != null ? "translateY(-50%)" : undefined
},
children: _jsxs(Tooltip, {
colorMode: colorMode,
maxWidth: Math.min(350, width),
children: [slice.label && _jsx(Text, _objectSpread(_objectSpread({
color: visualAppearance.tooltip.header
}, visualStyle.font.tooltip.header), {}, {
marginBottom: visualStyle.tooltip.headerSpacing,
children: slice.label
})), tooltipTotalVisible && items.length > 1 && _jsxs(Pane, {
verticalAlignment: "center",
orientation: "horizontal",
children: [_jsx(Text, _objectSpread(_objectSpread({
color: visualAppearance.tooltip.label
}, visualStyle.font.tooltip.label), {}, {
nowrap: true,
children: "Total"
})), _jsx(Pane, {
grow: 1,
verticalAlignment: "center",
horizontalAlignment: "right",
orientation: "horizontal",
children: _jsx(Text, _objectSpread(_objectSpread({
alignment: "right",
color: visualAppearance.tooltip.value
}, visualStyle.font.tooltip.value), {}, {
marginLeft: visualStyle.tooltip.valueSpacing,
nowrap: true,
children: formatter(total)
}))
})]
}), items]
})
});
}
//# sourceMappingURL=XYChartTooltip.js.map