@apptane/react-ui-charts
Version:
Chart components in Apptane React UI framework
199 lines (172 loc) • 7.11 kB
JavaScript
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
const _excluded = ["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; }
import { useComponentId, warning } from "@apptane/react-ui-core";
import { useCallback, useContext } from "react";
import { ChartOrdinalDataContext } from "../parts/ChartDataContext.js";
import { ChartDatumContext } from "../parts/ChartDatumContext.js";
import { findValue } from "./common.js";
import { formatNumericTooltip, useXYPaneData } from "./commonXY.js";
import { XYChartPane } from "./XYChartPane.js";
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
import { jsxs as _jsxs } from "@emotion/react/jsx-runtime";
const BAR_GAP = 1;
function XYBarLayer(_ref) {
let {
componentId,
data,
offset,
stacked,
width,
baseline = 0,
background
} = _ref;
const selectedDatumId = useContext(ChartDatumContext);
const barWidth = stacked ? width : Math.max(1, Math.round((width - (data.length - 1) * BAR_GAP) / data.length));
const barStart = width * 0.5;
const bars = [];
data.forEach(_ref2 => {
let {
id,
index,
color,
hiColor,
loColor,
pri,
sec
} = _ref2;
const unselected = selectedDatumId != null && id !== selectedDatumId;
const key = id !== null && id !== void 0 ? id : "_".concat(index);
[pri, sec].forEach((_, i) => {
if (_ != null && _.length > 0) {
const strokeProps = i === 1 ? {
stroke: color,
strokeWidth: 1,
strokeDasharray: "3"
} : {};
_.forEach(p => {
if (p.c != null) {
bars.push(_jsx("rect", _objectSpread({
transform: "translate(".concat(p.c.x - barStart, ",").concat(p.c.y, ")"),
x: stacked ? 0 : index * (barWidth + BAR_GAP),
y: 0,
width: barWidth,
height: stacked ? Math.max(0, baseline - p.c.v) : baseline - p.c.y,
fill: unselected ? loColor : i === 1 ? hiColor : color
}, strokeProps), "".concat(key, "-").concat(i, "-").concat(p.index)));
}
});
}
});
});
return _jsx("g", {
transform: "translate(".concat(offset, ",0)"),
strokeWidth: stacked ? 1 : 0,
stroke: background,
clipPath: "url(#".concat(componentId, "-main-clip)"),
children: bars
});
}
function findNearestDatum(cx, cy, data, domainX, domainY, x, y, ix, iy, context, baseline, stacked) {
if (domainX == null || x == null) {
return undefined;
}
const _domainX = domainX;
const _x = x;
function testDatum(d) {
const p = findValue(d, p => _domainX.isEqual(p.x, _x));
if (p != null) {
const _p = p;
if (_p.c != null) {
if (stacked) {
if (cy >= _p.c.y && cy <= _p.c.y + baseline - _p.c.v) {
return true;
}
} else {
if (cy >= _p.c.y) {
return true;
}
}
}
}
return false;
}
if (context.bandwidth == null) {
return undefined;
}
let x0 = context.scaleX(x);
if (x0 == null) {
return undefined;
}
const barStart = context.bandwidth * 0.5;
if (!stacked) {
const barWidth = Math.max(1, Math.round((context.bandwidth - (data.length - 1) * BAR_GAP) / data.length));
x0 -= barStart; // determine the applicable index of datum
const datumIndex = Math.floor((cx - x0) / (barWidth + BAR_GAP));
if (datumIndex < 0 || datumIndex >= data.length) {
return undefined;
}
const d = data[datumIndex];
return testDatum(d) ? d : undefined;
} else {
if (cx < x0 - barStart || cx > x0 + barStart) {
return undefined;
}
}
for (let i = 0; i < data.length; ++i) {
const d = data[i];
if (testDatum(d)) {
return d;
}
}
return undefined;
}
export function XYBarChartPane(props) {
var _context$bandwidth, _props$formatYTooltip, _p$background;
const componentId = useComponentId("--apptane-chart");
const _ref3 = props,
{
axisYVisible = true,
gridYVisible = true,
legendInteractive = true,
tooltipVisible = true,
formatYTooltip = formatNumericTooltip
} = _ref3,
p = _objectWithoutProperties(_ref3, _excluded); // see XYChartPanes
const propsEx = {
componentId,
axisYVisible,
gridYVisible,
legendInteractive,
tooltipVisible,
formatYTooltip: formatYTooltip,
axisYWidth: axisYVisible ? p.axisYWidth : 0
};
const context = useContext(ChartOrdinalDataContext);
const bandwidth = (_context$bandwidth = context.bandwidth) !== null && _context$bandwidth !== void 0 ? _context$bandwidth : 0;
const [computed, domainX, scaleY, layers] = useXYPaneData(context, _objectSpread(_objectSpread({}, p), propsEx));
const offset = propsEx.axisYWidth;
const baseline = scaleY ? scaleY.range()[1] : 0;
const findDatum = useCallback((cx, cy, data, domainX, domainY, x, y, ix, iy) => findNearestDatum(cx, cy, data, domainX, domainY, x, y, ix, iy, context, baseline, props.stacked == true), [baseline, props.stacked, context]);
warning(p.domainXType === "ordinal", "Chart pane is not supported with domainXType='".concat(p.domainXType, "'"));
return _jsxs(XYChartPane, _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, p), propsEx), {}, {
computed: computed,
computedDomainX: domainX,
findDatum: props.legendInteractive ? findDatum : undefined
}, context), {}, {
tooltipOffset: bandwidth * 0.5 - p.theme.charts.xy.style.tooltip.offset,
formatTooltipValue: (_props$formatYTooltip = props.formatYTooltip) !== null && _props$formatYTooltip !== void 0 ? _props$formatYTooltip : p.formatYDomain,
children: [layers, computed && _jsx(XYBarLayer, {
componentId: componentId,
background: (_p$background = p.background) !== null && _p$background !== void 0 ? _p$background : p.theme.charts.xy.appearance(p.palette, p.colorMode, undefined, "none").back,
offset: offset,
data: computed,
stacked: !!props.stacked,
width: bandwidth,
baseline: baseline
})]
}));
}
//# sourceMappingURL=XYBarChartPane.js.map