UNPKG

@apptane/react-ui-charts

Version:
319 lines (278 loc) 10.5 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; const _excluded = ["context"], _excluded2 = ["axisYVisible", "gridYVisible", "legendInteractive", "tooltipVisible", "formatYTooltip"]; 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; } /* eslint-disable @typescript-eslint/no-non-null-assertion */ import { useComponentId, warning } from "@apptane/react-ui-core"; import { useContext, useMemo } from "react"; import { area, curveBumpX, curveCatmullRom, curveLinear, curveMonotoneX, curveNatural, curveStep, line } from "d3-shape"; import { ChartNumericDataContext, ChartOrdinalDataContext, ChartTimeDataContext } from "../parts/ChartDataContext.js"; import { ChartDatumContext } from "../parts/ChartDatumContext.js"; import { findValue } from "./common.js"; import { formatNumericTooltip, useXYPaneData } from "./commonXY.js"; import { useGradientDefs } from "./gradients.js"; import { XYChartPane } from "./XYChartPane.js"; import { XYTooltipLayer } from "./XYTooltipLayer.js"; import { jsx as _jsx } from "@emotion/react/jsx-runtime"; import { jsxs as _jsxs } from "@emotion/react/jsx-runtime"; function curveFn(curve) { switch (curve) { case "linear": return curveLinear; case "bump": return curveBumpX; case "catmullRom": return curveCatmullRom.alpha(0.5); case "monotone": return curveMonotoneX; case "natural": return curveNatural; case "step": return curveStep; } } const createLineGenerator = curve => line().defined(d => d.c != null).x(d => d.c.x).y(d => d.c.y).curve(curveFn(curve)); const lineGenerator = { linear: createLineGenerator("linear"), bump: createLineGenerator("bump"), catmullRom: createLineGenerator("catmullRom"), monotone: createLineGenerator("monotone"), natural: createLineGenerator("natural"), step: createLineGenerator("step") }; const createAreaGenerator = curve => area().defined(d => d.c != null).x(d => d.c.x).y1(d => d.c.y).curve(curveFn(curve)); const createBandGenerator = curve => area().defined(d => d.c != null).x(d => d.c.x).y0(d => d.c.y0).y1(d => d.c.y1).curve(curveFn(curve)); function XYLineLayer(_ref) { let { componentId, data, curve, offset } = _ref; const selectedDatumId = useContext(ChartDatumContext); const generator = lineGenerator[curve]; const lines = []; data.forEach(_ref2 => { let { id, index, color, pri, sec } = _ref2; const selected = id === selectedDatumId; const key = id !== null && id !== void 0 ? id : "_".concat(index); [pri, sec].forEach((_, i) => { if (_ != null && _.length > 0) { var _generator; lines.push(_jsx("path", { d: (_generator = generator(_)) !== null && _generator !== void 0 ? _generator : undefined, fill: "none", stroke: color, strokeDasharray: i === 1 ? "2" : undefined, strokeWidth: selected ? 2 : undefined }, "".concat(key, "-").concat(i))); } }); }); return _jsx("g", { transform: "translate(".concat(offset, ",0)"), strokeWidth: 1.5, clipPath: "url(#".concat(componentId, "-main-clip)"), children: lines }); } function XYBandLayer(_ref3) { let { componentId, data, curve, offset } = _ref3; const selectedDatumId = useContext(ChartDatumContext); const generator = useMemo(() => createBandGenerator(curve), [curve]); return _jsx("g", { transform: "translate(".concat(offset, ",0)"), clipPath: "url(#".concat(componentId, "-main-clip)"), children: data.map(_ref4 => { var _generator2; let { id, index, loColor, bands } = _ref4; return bands && bands.length > 0 && _jsx("path", { d: (_generator2 = generator(bands)) !== null && _generator2 !== void 0 ? _generator2 : undefined, fill: loColor, opacity: selectedDatumId != null ? id !== selectedDatumId ? 0.5 : undefined : 0.65 }, id !== null && id !== void 0 ? id : "_".concat(index)); }) }); } function XYAreaLayer(_ref5) { let { componentId, data, curve, offset, stacked, gradient, baseline = 0 } = _ref5; const selectedDatumId = useContext(ChartDatumContext); // no gradient in stacked mode since areas are overlapping const gradientEnabled = gradient && !stacked; const generator = useMemo(() => createAreaGenerator(curve).y0(baseline), [curve, baseline]); const areas = []; for (let i = stacked ? data.length - 1 : 0; stacked ? i >= 0 : i < data.length; stacked ? --i : ++i) { const { id, index, hiColor, loColor, gradientId, pri, sec } = data[i]; const selected = selectedDatumId != null && id === selectedDatumId; const key = id !== null && id !== void 0 ? id : "_".concat(index); [pri, sec].forEach((_, i) => { if (_ != null && _.length > 0) { var _generator3; areas.push(_jsx("path", { d: (_generator3 = generator(_)) !== null && _generator3 !== void 0 ? _generator3 : undefined, fill: gradientEnabled ? "url(#".concat(selected ? gradientId + "-active" : gradientId, ")") : selected ? hiColor : loColor }, "".concat(key, "-").concat(i))); } }); } return _jsx("g", { transform: "translate(".concat(offset, ",0)"), strokeWidth: 0, clipPath: "url(#".concat(componentId, "-main-clip)"), children: areas }); } function findNearestDatum(cx, cy, data, domainX, domainY, x) { if (domainX == null || x == null) { return undefined; } let datum; let distance = Infinity; data.forEach(d => { const p = findValue(d, p => domainX.isEqual(p.x, x)); if (p != null) { const _p = p; if (_p.c != null) { const m = Math.abs(_p.c.y - cy); if (isFinite(m) && m < distance) { datum = d; distance = m; } } } }); return datum; } function XYLineChartPaneBase(_ref6) { var _props$formatYTooltip; let { context } = _ref6, props = _objectWithoutProperties(_ref6, _excluded); const p = props; const [computed, domainX, scaleY, layers] = useXYPaneData(context, p); const offset = props.axisYWidth; const baseline = scaleY ? scaleY.range()[1] : 0; return _jsxs(XYChartPane, _objectSpread(_objectSpread(_objectSpread({}, p), {}, { defs: useGradientDefs(computed, props.gradient == true && props.stacked != true), computed: computed, computedDomainX: domainX, findDatum: props.legendInteractive ? findNearestDatum : undefined }, context), {}, { invertY: scaleY === null || scaleY === void 0 ? void 0 : scaleY.invert, tooltipOffset: props.theme.charts.xy.style.tooltip.offset, formatTooltipValue: (_props$formatYTooltip = props.formatYTooltip) !== null && _props$formatYTooltip !== void 0 ? _props$formatYTooltip : p.formatYDomain, children: [layers, computed && props.area && _jsx(XYAreaLayer, { componentId: props.componentId, offset: offset, curve: props.curve, data: computed, stacked: !!props.stacked, gradient: !!props.gradient, baseline: baseline }), computed && !props.area && _jsx(XYBandLayer, { componentId: props.componentId, offset: offset, curve: props.curve, data: computed }), computed && _jsx(XYLineLayer, { componentId: props.componentId, offset: offset, curve: props.curve, data: computed }), computed && domainX && props.tooltipVisible && _jsx(XYTooltipLayer, { theme: props.theme, colorMode: props.colorMode, offset: offset, data: computed, domainX: domainX, baseline: baseline })] })); } function XYTimeLineChartPane(props) { const context = useContext(ChartTimeDataContext); return _jsx(XYLineChartPaneBase, _objectSpread(_objectSpread({}, props), {}, { context: context })); } function XYNumericLineChartPane(props) { const context = useContext(ChartNumericDataContext); return _jsx(XYLineChartPaneBase, _objectSpread(_objectSpread({}, props), {}, { context: context })); } function XYOrdinalLineChartPane(props) { const context = useContext(ChartOrdinalDataContext); return _jsx(XYLineChartPaneBase, _objectSpread(_objectSpread({}, props), {}, { context: context })); } export function XYLineChartPane(props) { const componentId = useComponentId("--apptane-chart"); const _ref7 = props, { axisYVisible = true, gridYVisible = true, legendInteractive = true, tooltipVisible = true, formatYTooltip = formatNumericTooltip } = _ref7, p = _objectWithoutProperties(_ref7, _excluded2); // see XYChartPanes const curve = p.curve === true ? "monotone" : typeof p.curve === "string" ? p.curve : "linear"; const propsEx = { componentId, axisYVisible, gridYVisible, legendInteractive, tooltipVisible, formatYTooltip: formatYTooltip, curve: curve, axisYWidth: axisYVisible ? p.axisYWidth : 0 }; switch (p.domainXType) { case "time": return _jsx(XYTimeLineChartPane, _objectSpread(_objectSpread({}, p), propsEx)); case "numeric": return _jsx(XYNumericLineChartPane, _objectSpread(_objectSpread({}, p), propsEx)); case "ordinal": return _jsx(XYOrdinalLineChartPane, _objectSpread(_objectSpread({}, p), propsEx)); default: warning(false, "Chart pane does not have 'domainXType' specified"); return null; } } //# sourceMappingURL=XYLineChartPane.js.map