analytica-frontend-lib
Version:
Repositório público dos componentes utilizados nas plataformas da Analytica Ensino
303 lines (285 loc) • 10.8 kB
JavaScript
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
var _chunkYCIBW5F4js = require('./chunk-YCIBW5F4.js');
var _chunkANT66KVKjs = require('./chunk-ANT66KVK.js');
var _chunkTN3AYOMVjs = require('./chunk-TN3AYOMV.js');
// src/components/shared/ChartComponents.tsx
var _react = require('react');
var _jsxruntime = require('react/jsx-runtime');
var calculateYAxisTicks = (maxValue) => {
if (maxValue <= 0) return [0];
const niceMax = Math.ceil(maxValue / 10) * 10;
const step = niceMax / 4;
return [
niceMax,
Math.round(step * 3),
Math.round(step * 2),
Math.round(step),
0
];
};
var LegendItem = ({
color,
label
}) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-row items-center gap-2", children: [
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkTN3AYOMVjs.cn.call(void 0, "w-2 h-2 rounded-full", color) }),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkANT66KVKjs.Text_default, { size: "xs", weight: "medium", className: "text-text-600", children: label })
] });
var DataBar = ({
label,
value,
maxValue,
colorClass,
chartHeight
}) => {
const percentage = maxValue === 0 ? 0 : value / maxValue * 100;
const barHeight = percentage / 100 * chartHeight;
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center gap-2 flex-1", children: [
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"div",
{
className: "w-full flex items-end justify-center",
style: { height: chartHeight },
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"div",
{
className: _chunkTN3AYOMVjs.cn.call(void 0,
"w-16 rounded-lg transition-all duration-300",
colorClass
),
style: { height: `${barHeight}px` }
}
)
}
),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkANT66KVKjs.Text_default, { size: "xs", weight: "medium", className: "text-text-600 text-center", children: label })
] });
};
var GridLines = ({
ticks,
chartHeight
}) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"div",
{
className: "absolute inset-0 flex flex-col justify-between pointer-events-none",
style: { height: chartHeight },
children: ticks.map((tick, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"div",
{
className: "w-full border-t border-dashed border-border-200",
style: { marginTop: index === 0 ? 0 : void 0 }
},
`${tick}-${index}`
))
}
);
var YAxis = ({
ticks,
chartHeight
}) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"div",
{
className: "flex flex-col justify-between items-end pr-3",
style: { height: chartHeight },
"aria-hidden": "true",
children: ticks.map((tick, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunkANT66KVKjs.Text_default,
{
size: "xs",
weight: "medium",
className: "text-text-500",
children: tick
},
`${tick}-${index}`
))
}
);
var PIE_RADIUS_RATIO = 0.44;
var PIE_LABEL_RADIUS_RATIO = 0.62;
var PIE_MIN_PERCENTAGE_FOR_LABEL = 5;
var PIE_WHOLE_THRESHOLD = 99.9999;
var SimplePieChart = ({
slices,
size = 130,
emptyText,
minPercentageForLabel = PIE_MIN_PERCENTAGE_FOR_LABEL,
labelRadiusRatio = PIE_LABEL_RADIUS_RATIO,
labelColor = "var(--color-text-950)",
labelFontWeight = 500,
labelTextShadow,
hoverOpacity = 0.4,
hoveredSlice: externalHovered,
onSliceHover
}) => {
const [internalHovered, setInternalHovered] = _react.useState.call(void 0, null);
const isControlled = externalHovered !== void 0;
const hovered = isControlled ? externalHovered : internalHovered;
const handleSliceHover = (label) => {
if (!isControlled) {
setInternalHovered(label);
}
_optionalChain([onSliceHover, 'optionalCall', _ => _(label)]);
};
const total = slices.reduce((sum, s) => sum + s.value, 0);
const radius = size * PIE_RADIUS_RATIO;
const center = size / 2;
if (total === 0) {
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
"svg",
{
width: size,
height: size,
viewBox: `0 0 ${size} ${size}`,
"aria-hidden": !emptyText,
"aria-label": emptyText || void 0,
children: [
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"circle",
{
cx: center,
cy: center,
r: radius,
className: "fill-background-200"
}
),
emptyText && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"text",
{
x: center,
y: center,
textAnchor: "middle",
dominantBaseline: "central",
fill: "var(--color-text-400)",
style: {
fontSize: 12,
fontWeight: 500,
fontFamily: "Roboto, sans-serif"
},
children: emptyText
}
)
]
}
);
}
let cumAngle = 0;
const computed = slices.map((s) => {
const pct = s.value / total * 100;
const startAngle = cumAngle;
cumAngle += pct / 100 * 360;
const endAngle = cumAngle;
const midAngle = startAngle + (endAngle - startAngle) / 2;
return { ...s, pct, startAngle, endAngle, midAngle };
}).filter((s) => s.pct > 0);
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"svg",
{
width: size,
height: size,
viewBox: `0 0 ${size} ${size}`,
"aria-hidden": "true",
onMouseLeave: () => handleSliceHover(null),
children: computed.map((slice) => {
const sliceKey = _nullishCoalesce(slice.key, () => ( slice.label));
const isHovered = hovered === sliceKey;
const isWhole = slice.pct >= PIE_WHOLE_THRESHOLD;
const arcPath = isWhole ? void 0 : _chunkYCIBW5F4js.describeArc.call(void 0,
center,
center,
radius,
slice.startAngle,
slice.endAngle
);
const labelPos = _chunkYCIBW5F4js.polarToCartesian.call(void 0,
center,
center,
radius * labelRadiusRatio,
slice.midAngle
);
const fill = _nullishCoalesce(slice.color, () => ( _chunkYCIBW5F4js.bgClassToCssVar.call(void 0, slice.colorClass)));
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
"g",
{
onMouseEnter: () => handleSliceHover(sliceKey),
className: "cursor-pointer",
children: [
isWhole ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: center, cy: center, r: radius, fill }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: arcPath, fill }),
isHovered && (isWhole ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"circle",
{
cx: center,
cy: center,
r: radius,
fill: "white",
opacity: hoverOpacity,
style: { pointerEvents: "none" }
}
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"path",
{
d: arcPath,
fill: "white",
opacity: hoverOpacity,
style: { pointerEvents: "none" }
}
)),
slice.pct >= minPercentageForLabel && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"text",
{
x: labelPos.x,
y: labelPos.y,
textAnchor: "middle",
dominantBaseline: "central",
fill: labelColor,
style: {
fontSize: 14,
fontWeight: labelFontWeight,
fontFamily: "Roboto, sans-serif",
lineHeight: 1,
letterSpacing: 0,
pointerEvents: "none",
textShadow: labelTextShadow
},
children: `${Math.round(slice.pct)}%`
}
)
]
},
sliceKey
);
})
}
);
};
var LegendRow = ({
colorClass,
color,
label,
value,
displayValue
}) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"div",
{
className: _chunkTN3AYOMVjs.cn.call(void 0, "w-2 h-2 rounded-full shrink-0", !color && colorClass),
style: color ? { backgroundColor: color } : void 0
}
),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkANT66KVKjs.Text_default, { size: "sm", weight: "medium", className: "text-text-950 flex-1", children: label }),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkANT66KVKjs.Text_default, { size: "sm", weight: "medium", className: "text-text-600 ml-3", children: _nullishCoalesce(displayValue, () => ( value)) })
] });
var LegendPieCard = ({ slices }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between gap-4 p-4 bg-background border border-border-50 rounded-xl", children: [
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-col gap-2", children: slices.map((s) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
LegendRow,
{
colorClass: s.colorClass,
color: s.color,
label: s.label,
value: s.value,
displayValue: s.displayValue
},
_nullishCoalesce(s.key, () => ( s.label))
)) }),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, SimplePieChart, { slices })
] });
exports.calculateYAxisTicks = calculateYAxisTicks; exports.LegendItem = LegendItem; exports.DataBar = DataBar; exports.GridLines = GridLines; exports.YAxis = YAxis; exports.SimplePieChart = SimplePieChart; exports.LegendRow = LegendRow; exports.LegendPieCard = LegendPieCard;
//# sourceMappingURL=chunk-FCCPBAAQ.js.map