@marcoschwartz/lite-ui 0.15.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +543 -187
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +543 -187
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -459,11 +459,23 @@ var Navbar = ({
|
|
|
459
459
|
logo,
|
|
460
460
|
children,
|
|
461
461
|
className = "",
|
|
462
|
-
sticky = false
|
|
462
|
+
sticky = false,
|
|
463
|
+
variant = "solid"
|
|
463
464
|
}) => {
|
|
464
465
|
const { theme } = useTheme();
|
|
465
466
|
const baseClasses = sticky ? "sticky top-0 z-40" : "";
|
|
466
|
-
|
|
467
|
+
const getVariantClasses = () => {
|
|
468
|
+
switch (variant) {
|
|
469
|
+
case "glass":
|
|
470
|
+
return "bg-transparent backdrop-blur-xl";
|
|
471
|
+
case "transparent":
|
|
472
|
+
return "bg-transparent";
|
|
473
|
+
case "solid":
|
|
474
|
+
default:
|
|
475
|
+
return "bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700";
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
return /* @__PURE__ */ jsx5("nav", { className: `${getVariantClasses()} ${baseClasses} ${className}`, children: /* @__PURE__ */ jsx5("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxs4("div", { className: "flex justify-between items-center h-16", children: [
|
|
467
479
|
logo && /* @__PURE__ */ jsx5("div", { className: "flex items-center", children: logo }),
|
|
468
480
|
children && /* @__PURE__ */ jsx5("div", { className: "flex items-center gap-6", children })
|
|
469
481
|
] }) }) });
|
|
@@ -5149,14 +5161,32 @@ var LineChart = ({
|
|
|
5149
5161
|
strokeWidth = 2,
|
|
5150
5162
|
className = "",
|
|
5151
5163
|
xAxisLabel,
|
|
5152
|
-
yAxisLabel
|
|
5164
|
+
yAxisLabel,
|
|
5165
|
+
baseFontSize = 14
|
|
5153
5166
|
}) => {
|
|
5154
|
-
const
|
|
5155
|
-
const
|
|
5167
|
+
const viewBoxWidth = 1e3;
|
|
5168
|
+
const viewBoxHeight = 600;
|
|
5169
|
+
const containerRef = React26.useRef(null);
|
|
5170
|
+
const svgRef = React26.useRef(null);
|
|
5171
|
+
const [tooltipPosition, setTooltipPosition] = React26.useState(null);
|
|
5156
5172
|
const [hoveredPoint, setHoveredPoint] = React26.useState(null);
|
|
5157
|
-
const
|
|
5158
|
-
const
|
|
5159
|
-
const
|
|
5173
|
+
const chartId = React26.useId();
|
|
5174
|
+
const wrapperClass = `chart-svg-wrapper-${chartId.replace(/:/g, "-")}`;
|
|
5175
|
+
const gridLabelClass = `chart-grid-label-${chartId.replace(/:/g, "-")}`;
|
|
5176
|
+
const axisLabelClass = `chart-axis-label-${chartId.replace(/:/g, "-")}`;
|
|
5177
|
+
const lineClass = `chart-line-${chartId.replace(/:/g, "-")}`;
|
|
5178
|
+
const pointClass = `chart-point-${chartId.replace(/:/g, "-")}`;
|
|
5179
|
+
const padding = {
|
|
5180
|
+
top: 50,
|
|
5181
|
+
right: 50,
|
|
5182
|
+
bottom: showXAxis ? 120 : 50,
|
|
5183
|
+
left: showYAxis ? 130 : 50
|
|
5184
|
+
};
|
|
5185
|
+
const chartWidth = viewBoxWidth - padding.left - padding.right;
|
|
5186
|
+
const chartHeight = viewBoxHeight - padding.top - padding.bottom;
|
|
5187
|
+
const gridLabelFontSize = viewBoxWidth * 0.045;
|
|
5188
|
+
const axisLabelFontSize = viewBoxWidth * 0.05;
|
|
5189
|
+
const titleFontSize = viewBoxWidth * 0.055;
|
|
5160
5190
|
const allPoints = data.flatMap((series) => series.data);
|
|
5161
5191
|
const allYValues = allPoints.map((p) => p.y);
|
|
5162
5192
|
const firstXValue = data[0]?.data[0]?.x;
|
|
@@ -5169,7 +5199,7 @@ var LineChart = ({
|
|
|
5169
5199
|
const minY = Math.min(0, ...allYValues);
|
|
5170
5200
|
const maxY = Math.max(...allYValues);
|
|
5171
5201
|
const yRange = maxY - minY;
|
|
5172
|
-
const yMin = minY - yRange * 0.1;
|
|
5202
|
+
const yMin = Math.max(0, minY - yRange * 0.1);
|
|
5173
5203
|
const yMax = maxY + yRange * 0.1;
|
|
5174
5204
|
const scaleX = (x, index) => {
|
|
5175
5205
|
const numX = isStringX ? index : x;
|
|
@@ -5216,29 +5246,32 @@ var LineChart = ({
|
|
|
5216
5246
|
x2: chartWidth,
|
|
5217
5247
|
y2: y,
|
|
5218
5248
|
stroke: "currentColor",
|
|
5219
|
-
strokeWidth: "
|
|
5249
|
+
strokeWidth: "0.5",
|
|
5220
5250
|
className: "text-gray-200 dark:text-gray-700",
|
|
5221
|
-
strokeDasharray: "
|
|
5251
|
+
strokeDasharray: "4,4"
|
|
5222
5252
|
}
|
|
5223
5253
|
),
|
|
5224
5254
|
showYAxis && /* @__PURE__ */ jsx108(
|
|
5225
5255
|
"text",
|
|
5226
5256
|
{
|
|
5227
|
-
x: -
|
|
5228
|
-
y
|
|
5257
|
+
x: -25,
|
|
5258
|
+
y,
|
|
5229
5259
|
textAnchor: "end",
|
|
5230
|
-
|
|
5231
|
-
|
|
5260
|
+
dominantBaseline: "middle",
|
|
5261
|
+
fontSize: gridLabelFontSize,
|
|
5262
|
+
className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
|
|
5232
5263
|
children: yValue.toFixed(1)
|
|
5233
5264
|
}
|
|
5234
5265
|
)
|
|
5235
5266
|
] }, `grid-h-${i}`)
|
|
5236
5267
|
);
|
|
5237
5268
|
}
|
|
5238
|
-
const numXGridLines = Math.min(allPoints.length, 6);
|
|
5269
|
+
const numXGridLines = Math.max(2, Math.min(allPoints.length, 6));
|
|
5270
|
+
const xGridStep = numXGridLines > 1 ? 1 / (numXGridLines - 1) : 0;
|
|
5239
5271
|
for (let i = 0; i < numXGridLines; i++) {
|
|
5240
|
-
const x = chartWidth
|
|
5241
|
-
const
|
|
5272
|
+
const x = chartWidth * (i * xGridStep);
|
|
5273
|
+
const dataIndex = Math.floor((data[0]?.data.length - 1) * (i * xGridStep));
|
|
5274
|
+
const xValue = data[0]?.data[Math.max(0, Math.min(dataIndex, data[0].data.length - 1))]?.x || "";
|
|
5242
5275
|
gridLines.push(
|
|
5243
5276
|
/* @__PURE__ */ jsxs35("g", { children: [
|
|
5244
5277
|
/* @__PURE__ */ jsx108(
|
|
@@ -5249,19 +5282,20 @@ var LineChart = ({
|
|
|
5249
5282
|
x2: x,
|
|
5250
5283
|
y2: chartHeight,
|
|
5251
5284
|
stroke: "currentColor",
|
|
5252
|
-
strokeWidth: "
|
|
5285
|
+
strokeWidth: "0.5",
|
|
5253
5286
|
className: "text-gray-200 dark:text-gray-700",
|
|
5254
|
-
strokeDasharray: "
|
|
5287
|
+
strokeDasharray: "4,4"
|
|
5255
5288
|
}
|
|
5256
5289
|
),
|
|
5257
5290
|
showXAxis && /* @__PURE__ */ jsx108(
|
|
5258
5291
|
"text",
|
|
5259
5292
|
{
|
|
5260
5293
|
x,
|
|
5261
|
-
y: chartHeight +
|
|
5294
|
+
y: chartHeight + 35,
|
|
5262
5295
|
textAnchor: "middle",
|
|
5263
|
-
|
|
5264
|
-
|
|
5296
|
+
dominantBaseline: "hanging",
|
|
5297
|
+
fontSize: gridLabelFontSize,
|
|
5298
|
+
className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
|
|
5265
5299
|
children: xValue
|
|
5266
5300
|
}
|
|
5267
5301
|
)
|
|
@@ -5269,21 +5303,74 @@ var LineChart = ({
|
|
|
5269
5303
|
);
|
|
5270
5304
|
}
|
|
5271
5305
|
}
|
|
5306
|
+
const getTooltipPosition = React26.useCallback((x, y) => {
|
|
5307
|
+
if (!containerRef.current) return { x, y };
|
|
5308
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
5309
|
+
const tooltipWidth = 120;
|
|
5310
|
+
const tooltipHeight = 80;
|
|
5311
|
+
let tooltipX = x + 10;
|
|
5312
|
+
let tooltipY = y - 30;
|
|
5313
|
+
if (tooltipX + tooltipWidth > rect.width) {
|
|
5314
|
+
tooltipX = x - tooltipWidth - 10;
|
|
5315
|
+
}
|
|
5316
|
+
if (tooltipY + tooltipHeight > rect.height) {
|
|
5317
|
+
tooltipY = y + 30;
|
|
5318
|
+
}
|
|
5319
|
+
return { x: tooltipX, y: tooltipY };
|
|
5320
|
+
}, []);
|
|
5321
|
+
const containerStyle = {
|
|
5322
|
+
"--font-size-base": `${baseFontSize}px`,
|
|
5323
|
+
"--font-size-lg": `calc(var(--font-size-base) * 1.125)`,
|
|
5324
|
+
"--font-size-sm": `calc(var(--font-size-base) * 0.875)`,
|
|
5325
|
+
"--font-size-xs": `calc(var(--font-size-base) * 0.75)`
|
|
5326
|
+
};
|
|
5272
5327
|
return /* @__PURE__ */ jsxs35(
|
|
5273
5328
|
"div",
|
|
5274
5329
|
{
|
|
5275
|
-
|
|
5276
|
-
|
|
5330
|
+
ref: containerRef,
|
|
5331
|
+
className: `relative flex flex-col gap-4 ${responsive ? "w-full" : "inline-block"} ${className}`,
|
|
5332
|
+
style: {
|
|
5333
|
+
...containerStyle
|
|
5334
|
+
},
|
|
5277
5335
|
children: [
|
|
5336
|
+
/* @__PURE__ */ jsx108("style", { children: `
|
|
5337
|
+
/* Mobile: Large fonts, hidden axis titles, thicker lines (default) */
|
|
5338
|
+
.${gridLabelClass} { font-size: ${gridLabelFontSize}px !important; }
|
|
5339
|
+
.${axisLabelClass} { display: none; }
|
|
5340
|
+
.${lineClass} { stroke-width: ${strokeWidth * 2.5} !important; }
|
|
5341
|
+
.${pointClass} { r: 6 !important; stroke-width: 3 !important; }
|
|
5342
|
+
|
|
5343
|
+
/* Tablet: Medium fonts, show axis titles, medium lines */
|
|
5344
|
+
@media (min-width: 640px) {
|
|
5345
|
+
.${gridLabelClass} { font-size: ${gridLabelFontSize * 0.7}px !important; }
|
|
5346
|
+
.${axisLabelClass} {
|
|
5347
|
+
font-size: ${axisLabelFontSize * 0.7}px !important;
|
|
5348
|
+
display: block;
|
|
5349
|
+
}
|
|
5350
|
+
.${lineClass} { stroke-width: ${strokeWidth * 1.5} !important; }
|
|
5351
|
+
.${pointClass} { r: 4 !important; stroke-width: 2 !important; }
|
|
5352
|
+
}
|
|
5353
|
+
|
|
5354
|
+
/* Desktop: Small fonts, show axis titles, normal lines */
|
|
5355
|
+
@media (min-width: 1024px) {
|
|
5356
|
+
.${gridLabelClass} { font-size: ${gridLabelFontSize * 0.4}px !important; }
|
|
5357
|
+
.${axisLabelClass} {
|
|
5358
|
+
font-size: ${axisLabelFontSize * 0.4}px !important;
|
|
5359
|
+
display: block;
|
|
5360
|
+
}
|
|
5361
|
+
.${lineClass} { stroke-width: ${strokeWidth} !important; }
|
|
5362
|
+
.${pointClass} { r: 3 !important; stroke-width: 1.5 !important; }
|
|
5363
|
+
}
|
|
5364
|
+
` }),
|
|
5278
5365
|
/* @__PURE__ */ jsx108(
|
|
5279
5366
|
"svg",
|
|
5280
5367
|
{
|
|
5368
|
+
ref: svgRef,
|
|
5281
5369
|
width: "100%",
|
|
5282
|
-
|
|
5283
|
-
viewBox: `0 0 ${width} ${height}`,
|
|
5370
|
+
viewBox: `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
|
|
5284
5371
|
preserveAspectRatio: "xMidYMid meet",
|
|
5285
|
-
className: "bg-white dark:bg-gray-800 block",
|
|
5286
|
-
style: { overflow: "visible" },
|
|
5372
|
+
className: "bg-white dark:bg-gray-800 block w-full",
|
|
5373
|
+
style: { height: "auto", overflow: "visible" },
|
|
5287
5374
|
children: /* @__PURE__ */ jsxs35("g", { transform: `translate(${padding.left}, ${padding.top})`, children: [
|
|
5288
5375
|
gridLines,
|
|
5289
5376
|
data.map((series, seriesIndex) => /* @__PURE__ */ jsx108(
|
|
@@ -5294,7 +5381,8 @@ var LineChart = ({
|
|
|
5294
5381
|
stroke: series.color || defaultColors[seriesIndex % defaultColors.length],
|
|
5295
5382
|
strokeWidth,
|
|
5296
5383
|
strokeLinecap: "round",
|
|
5297
|
-
strokeLinejoin: "round"
|
|
5384
|
+
strokeLinejoin: "round",
|
|
5385
|
+
className: lineClass
|
|
5298
5386
|
},
|
|
5299
5387
|
`line-${seriesIndex}`
|
|
5300
5388
|
)),
|
|
@@ -5308,13 +5396,32 @@ var LineChart = ({
|
|
|
5308
5396
|
{
|
|
5309
5397
|
cx: x,
|
|
5310
5398
|
cy: y,
|
|
5311
|
-
r: isHovered ?
|
|
5399
|
+
r: isHovered ? 5 : 3,
|
|
5312
5400
|
fill: series.color || defaultColors[seriesIndex % defaultColors.length],
|
|
5313
5401
|
stroke: "white",
|
|
5314
|
-
strokeWidth: "
|
|
5315
|
-
className:
|
|
5316
|
-
onMouseEnter: () =>
|
|
5317
|
-
|
|
5402
|
+
strokeWidth: "1.5",
|
|
5403
|
+
className: `cursor-pointer transition-all ${pointClass}`,
|
|
5404
|
+
onMouseEnter: (e) => {
|
|
5405
|
+
if (showTooltip && containerRef.current) {
|
|
5406
|
+
setHoveredPoint({ seriesIndex, pointIndex, x, y });
|
|
5407
|
+
const containerRect = containerRef.current.getBoundingClientRect();
|
|
5408
|
+
const mouseX = e.clientX - containerRect.left;
|
|
5409
|
+
const mouseY = e.clientY - containerRect.top;
|
|
5410
|
+
setTooltipPosition(getTooltipPosition(mouseX, mouseY));
|
|
5411
|
+
}
|
|
5412
|
+
},
|
|
5413
|
+
onMouseMove: (e) => {
|
|
5414
|
+
if (showTooltip && hoveredPoint?.seriesIndex === seriesIndex && hoveredPoint?.pointIndex === pointIndex && containerRef.current) {
|
|
5415
|
+
const containerRect = containerRef.current.getBoundingClientRect();
|
|
5416
|
+
const mouseX = e.clientX - containerRect.left;
|
|
5417
|
+
const mouseY = e.clientY - containerRect.top;
|
|
5418
|
+
setTooltipPosition(getTooltipPosition(mouseX, mouseY));
|
|
5419
|
+
}
|
|
5420
|
+
},
|
|
5421
|
+
onMouseLeave: () => {
|
|
5422
|
+
setHoveredPoint(null);
|
|
5423
|
+
setTooltipPosition(null);
|
|
5424
|
+
}
|
|
5318
5425
|
},
|
|
5319
5426
|
`point-${seriesIndex}-${pointIndex}`
|
|
5320
5427
|
);
|
|
@@ -5324,11 +5431,12 @@ var LineChart = ({
|
|
|
5324
5431
|
"text",
|
|
5325
5432
|
{
|
|
5326
5433
|
x: chartWidth / 2,
|
|
5327
|
-
y: chartHeight +
|
|
5434
|
+
y: chartHeight + 80,
|
|
5328
5435
|
textAnchor: "middle",
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5436
|
+
dominantBaseline: "hanging",
|
|
5437
|
+
fontSize: axisLabelFontSize,
|
|
5438
|
+
fontWeight: "600",
|
|
5439
|
+
className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
|
|
5332
5440
|
children: xAxisLabel
|
|
5333
5441
|
}
|
|
5334
5442
|
),
|
|
@@ -5336,45 +5444,47 @@ var LineChart = ({
|
|
|
5336
5444
|
"text",
|
|
5337
5445
|
{
|
|
5338
5446
|
x: -chartHeight / 2,
|
|
5339
|
-
y: -
|
|
5447
|
+
y: -100,
|
|
5340
5448
|
textAnchor: "middle",
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5449
|
+
dominantBaseline: "middle",
|
|
5450
|
+
fontSize: axisLabelFontSize,
|
|
5451
|
+
fontWeight: "600",
|
|
5452
|
+
transform: "rotate(-90)",
|
|
5453
|
+
className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
|
|
5345
5454
|
children: yAxisLabel
|
|
5346
5455
|
}
|
|
5347
5456
|
)
|
|
5348
5457
|
] })
|
|
5349
5458
|
}
|
|
5350
5459
|
),
|
|
5351
|
-
showLegend && /* @__PURE__ */ jsx108("div", { className: "flex flex-wrap gap-
|
|
5460
|
+
showLegend && /* @__PURE__ */ jsx108("div", { className: "flex flex-wrap gap-3 justify-center px-4", children: data.map((series, index) => /* @__PURE__ */ jsxs35("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
5352
5461
|
/* @__PURE__ */ jsx108(
|
|
5353
5462
|
"div",
|
|
5354
5463
|
{
|
|
5355
|
-
className: "w-
|
|
5464
|
+
className: "w-3 h-3 rounded-sm flex-shrink-0",
|
|
5356
5465
|
style: {
|
|
5357
5466
|
backgroundColor: series.color || defaultColors[index % defaultColors.length]
|
|
5358
5467
|
}
|
|
5359
5468
|
}
|
|
5360
5469
|
),
|
|
5361
|
-
/* @__PURE__ */ jsx108("span", { className: "text-
|
|
5470
|
+
/* @__PURE__ */ jsx108("span", { className: "text-gray-700 dark:text-gray-300", children: series.name })
|
|
5362
5471
|
] }, `legend-${index}`)) }),
|
|
5363
|
-
showTooltip && hoveredPoint && /* @__PURE__ */ jsxs35(
|
|
5472
|
+
showTooltip && hoveredPoint && tooltipPosition && /* @__PURE__ */ jsxs35(
|
|
5364
5473
|
"div",
|
|
5365
5474
|
{
|
|
5366
|
-
className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg
|
|
5475
|
+
className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg pointer-events-none z-50 text-sm whitespace-nowrap",
|
|
5367
5476
|
style: {
|
|
5368
|
-
left: `${
|
|
5369
|
-
top: `${
|
|
5477
|
+
left: `${tooltipPosition.x}px`,
|
|
5478
|
+
top: `${tooltipPosition.y}px`,
|
|
5479
|
+
transform: "translateZ(0)"
|
|
5370
5480
|
},
|
|
5371
5481
|
children: [
|
|
5372
5482
|
/* @__PURE__ */ jsx108("div", { className: "font-semibold", children: data[hoveredPoint.seriesIndex].name }),
|
|
5373
|
-
/* @__PURE__ */ jsxs35("div", { children: [
|
|
5483
|
+
/* @__PURE__ */ jsxs35("div", { className: "text-xs opacity-90", children: [
|
|
5374
5484
|
"x: ",
|
|
5375
5485
|
data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].x
|
|
5376
5486
|
] }),
|
|
5377
|
-
/* @__PURE__ */ jsxs35("div", { children: [
|
|
5487
|
+
/* @__PURE__ */ jsxs35("div", { className: "text-xs opacity-90", children: [
|
|
5378
5488
|
"y: ",
|
|
5379
5489
|
data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].y
|
|
5380
5490
|
] })
|
|
@@ -5420,26 +5530,38 @@ var BarChart = ({
|
|
|
5420
5530
|
barWidth = 0.8,
|
|
5421
5531
|
className = "",
|
|
5422
5532
|
xAxisLabel,
|
|
5423
|
-
yAxisLabel
|
|
5533
|
+
yAxisLabel,
|
|
5534
|
+
baseFontSize = 14,
|
|
5535
|
+
colors = defaultColors2
|
|
5424
5536
|
}) => {
|
|
5425
|
-
const
|
|
5426
|
-
const
|
|
5537
|
+
const viewBoxWidth = 1e3;
|
|
5538
|
+
const viewBoxHeight = 600;
|
|
5539
|
+
const containerRef = React27.useRef(null);
|
|
5540
|
+
const [tooltipPosition, setTooltipPosition] = React27.useState(null);
|
|
5427
5541
|
const [hoveredBar, setHoveredBar] = React27.useState(null);
|
|
5542
|
+
const chartId = React27.useId();
|
|
5543
|
+
const wrapperClass = `chart-svg-wrapper-${chartId.replace(/:/g, "-")}`;
|
|
5544
|
+
const gridLabelClass = `chart-grid-label-${chartId.replace(/:/g, "-")}`;
|
|
5545
|
+
const axisLabelClass = `chart-axis-label-${chartId.replace(/:/g, "-")}`;
|
|
5546
|
+
const barClass = `chart-bar-${chartId.replace(/:/g, "-")}`;
|
|
5428
5547
|
const padding = {
|
|
5429
|
-
top:
|
|
5430
|
-
right:
|
|
5431
|
-
bottom: showXAxis ? horizontal ?
|
|
5432
|
-
left: showYAxis ? horizontal ?
|
|
5548
|
+
top: 50,
|
|
5549
|
+
right: 50,
|
|
5550
|
+
bottom: showXAxis ? horizontal ? 120 : 140 : 50,
|
|
5551
|
+
left: showYAxis ? horizontal ? 140 : 130 : 50
|
|
5433
5552
|
};
|
|
5434
|
-
const chartWidth =
|
|
5435
|
-
const chartHeight =
|
|
5553
|
+
const chartWidth = viewBoxWidth - padding.left - padding.right;
|
|
5554
|
+
const chartHeight = viewBoxHeight - padding.top - padding.bottom;
|
|
5555
|
+
const gridLabelFontSize = viewBoxWidth * 0.045;
|
|
5556
|
+
const axisLabelFontSize = viewBoxWidth * 0.05;
|
|
5557
|
+
const titleFontSize = viewBoxWidth * 0.055;
|
|
5436
5558
|
const allYValues = stacked ? data[0]?.data.map(
|
|
5437
5559
|
(_, i) => data.reduce((sum, series) => sum + (series.data[i]?.y || 0), 0)
|
|
5438
5560
|
) || [] : data.flatMap((series) => series.data.map((p) => p.y));
|
|
5439
5561
|
const minY = Math.min(0, ...allYValues);
|
|
5440
5562
|
const maxY = Math.max(...allYValues);
|
|
5441
5563
|
const yRange = maxY - minY;
|
|
5442
|
-
const yMin = minY - yRange * 0.1;
|
|
5564
|
+
const yMin = Math.max(0, minY - yRange * 0.1);
|
|
5443
5565
|
const yMax = maxY + yRange * 0.1;
|
|
5444
5566
|
const numBars = data[0]?.data.length || 0;
|
|
5445
5567
|
const numSeries = data.length;
|
|
@@ -5466,19 +5588,20 @@ var BarChart = ({
|
|
|
5466
5588
|
x2: chartWidth,
|
|
5467
5589
|
y2: y,
|
|
5468
5590
|
stroke: "currentColor",
|
|
5469
|
-
strokeWidth: "
|
|
5591
|
+
strokeWidth: "0.5",
|
|
5470
5592
|
className: "text-gray-200 dark:text-gray-700",
|
|
5471
|
-
strokeDasharray: "
|
|
5593
|
+
strokeDasharray: "4,4"
|
|
5472
5594
|
}
|
|
5473
5595
|
),
|
|
5474
5596
|
showYAxis && !horizontal && /* @__PURE__ */ jsx109(
|
|
5475
5597
|
"text",
|
|
5476
5598
|
{
|
|
5477
|
-
x: -
|
|
5478
|
-
y
|
|
5599
|
+
x: -25,
|
|
5600
|
+
y,
|
|
5479
5601
|
textAnchor: "end",
|
|
5480
|
-
|
|
5481
|
-
|
|
5602
|
+
dominantBaseline: "middle",
|
|
5603
|
+
fontSize: gridLabelFontSize,
|
|
5604
|
+
className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
|
|
5482
5605
|
children: yValue.toFixed(0)
|
|
5483
5606
|
}
|
|
5484
5607
|
)
|
|
@@ -5527,12 +5650,20 @@ var BarChart = ({
|
|
|
5527
5650
|
x: xPos,
|
|
5528
5651
|
y: yPos,
|
|
5529
5652
|
width: barW,
|
|
5530
|
-
height:
|
|
5531
|
-
fill: data[seriesIndex].color ||
|
|
5532
|
-
className:
|
|
5653
|
+
height: Math.abs(scaleY(0) - yPos),
|
|
5654
|
+
fill: data[seriesIndex].color || colors[seriesIndex % colors.length],
|
|
5655
|
+
className: `cursor-pointer transition-opacity ${barClass}`,
|
|
5533
5656
|
opacity: isHovered ? 0.8 : 1,
|
|
5534
|
-
onMouseEnter: () =>
|
|
5535
|
-
|
|
5657
|
+
onMouseEnter: () => {
|
|
5658
|
+
if (showTooltip) {
|
|
5659
|
+
setHoveredBar({ seriesIndex, barIndex, x: xPos + barW / 2, y: yPos });
|
|
5660
|
+
setTooltipPosition(getTooltipPosition(padding.left + xPos + barW / 2, padding.top + yPos));
|
|
5661
|
+
}
|
|
5662
|
+
},
|
|
5663
|
+
onMouseLeave: () => {
|
|
5664
|
+
setHoveredBar(null);
|
|
5665
|
+
setTooltipPosition(null);
|
|
5666
|
+
}
|
|
5536
5667
|
},
|
|
5537
5668
|
`bar-${seriesIndex}-${barIndex}`
|
|
5538
5669
|
)
|
|
@@ -5557,8 +5688,8 @@ var BarChart = ({
|
|
|
5557
5688
|
y: yPos,
|
|
5558
5689
|
width: actualBarWidth,
|
|
5559
5690
|
height: barHeight,
|
|
5560
|
-
fill: data[seriesIndex].color ||
|
|
5561
|
-
className:
|
|
5691
|
+
fill: data[seriesIndex].color || colors[seriesIndex % colors.length],
|
|
5692
|
+
className: `cursor-pointer transition-opacity ${barClass}`,
|
|
5562
5693
|
opacity: isHovered ? 0.8 : 1,
|
|
5563
5694
|
onMouseEnter: () => showTooltip && setHoveredBar({ seriesIndex, barIndex, x: xPos + actualBarWidth / 2, y: yPos }),
|
|
5564
5695
|
onMouseLeave: () => setHoveredBar(null)
|
|
@@ -5572,10 +5703,11 @@ var BarChart = ({
|
|
|
5572
5703
|
"text",
|
|
5573
5704
|
{
|
|
5574
5705
|
x: xPos + actualBarWidth / 2,
|
|
5575
|
-
y: yPos -
|
|
5706
|
+
y: yPos - 10,
|
|
5576
5707
|
textAnchor: "middle",
|
|
5577
|
-
|
|
5578
|
-
|
|
5708
|
+
dominantBaseline: "middle",
|
|
5709
|
+
fontSize: "11",
|
|
5710
|
+
fontWeight: "600",
|
|
5579
5711
|
className: "fill-gray-700 dark:fill-gray-300",
|
|
5580
5712
|
children: point.y
|
|
5581
5713
|
},
|
|
@@ -5594,30 +5726,77 @@ var BarChart = ({
|
|
|
5594
5726
|
"text",
|
|
5595
5727
|
{
|
|
5596
5728
|
x: xPos,
|
|
5597
|
-
y: chartHeight +
|
|
5729
|
+
y: chartHeight + 35,
|
|
5598
5730
|
textAnchor: "middle",
|
|
5599
|
-
|
|
5600
|
-
|
|
5731
|
+
dominantBaseline: "hanging",
|
|
5732
|
+
fontSize: gridLabelFontSize,
|
|
5733
|
+
className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
|
|
5601
5734
|
children: point.x
|
|
5602
5735
|
},
|
|
5603
5736
|
`x-label-${i}`
|
|
5604
5737
|
);
|
|
5605
5738
|
});
|
|
5739
|
+
const getTooltipPosition = React27.useCallback((x, y) => {
|
|
5740
|
+
if (!containerRef.current) return { x, y };
|
|
5741
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
5742
|
+
const tooltipWidth = 140;
|
|
5743
|
+
const tooltipHeight = 80;
|
|
5744
|
+
let tooltipX = x + 10;
|
|
5745
|
+
let tooltipY = y - 30;
|
|
5746
|
+
if (tooltipX + tooltipWidth > rect.width) {
|
|
5747
|
+
tooltipX = x - tooltipWidth - 10;
|
|
5748
|
+
}
|
|
5749
|
+
if (tooltipY + tooltipHeight > rect.height) {
|
|
5750
|
+
tooltipY = y + 30;
|
|
5751
|
+
}
|
|
5752
|
+
return { x: tooltipX, y: tooltipY };
|
|
5753
|
+
}, []);
|
|
5754
|
+
const containerStyle = {
|
|
5755
|
+
"--font-size-base": `${baseFontSize}px`,
|
|
5756
|
+
"--font-size-lg": `calc(var(--font-size-base) * 1.125)`,
|
|
5757
|
+
"--font-size-sm": `calc(var(--font-size-base) * 0.875)`,
|
|
5758
|
+
"--font-size-xs": `calc(var(--font-size-base) * 0.75)`
|
|
5759
|
+
};
|
|
5606
5760
|
return /* @__PURE__ */ jsxs36(
|
|
5607
5761
|
"div",
|
|
5608
5762
|
{
|
|
5609
|
-
|
|
5610
|
-
|
|
5763
|
+
ref: containerRef,
|
|
5764
|
+
className: `relative flex flex-col gap-4 ${responsive ? "w-full" : "inline-block"} ${className}`,
|
|
5765
|
+
style: {
|
|
5766
|
+
...containerStyle
|
|
5767
|
+
},
|
|
5611
5768
|
children: [
|
|
5769
|
+
/* @__PURE__ */ jsx109("style", { children: `
|
|
5770
|
+
/* Mobile: Large fonts, hidden axis titles, thicker bars (default) */
|
|
5771
|
+
.${gridLabelClass} { font-size: ${gridLabelFontSize}px !important; }
|
|
5772
|
+
.${axisLabelClass} { display: none; }
|
|
5773
|
+
|
|
5774
|
+
/* Tablet: Medium fonts, show axis titles */
|
|
5775
|
+
@media (min-width: 640px) {
|
|
5776
|
+
.${gridLabelClass} { font-size: ${gridLabelFontSize * 0.7}px !important; }
|
|
5777
|
+
.${axisLabelClass} {
|
|
5778
|
+
font-size: ${axisLabelFontSize * 0.7}px !important;
|
|
5779
|
+
display: block;
|
|
5780
|
+
}
|
|
5781
|
+
}
|
|
5782
|
+
|
|
5783
|
+
/* Desktop: Small fonts, show axis titles */
|
|
5784
|
+
@media (min-width: 1024px) {
|
|
5785
|
+
.${gridLabelClass} { font-size: ${gridLabelFontSize * 0.4}px !important; }
|
|
5786
|
+
.${axisLabelClass} {
|
|
5787
|
+
font-size: ${axisLabelFontSize * 0.4}px !important;
|
|
5788
|
+
display: block;
|
|
5789
|
+
}
|
|
5790
|
+
}
|
|
5791
|
+
` }),
|
|
5612
5792
|
/* @__PURE__ */ jsx109(
|
|
5613
5793
|
"svg",
|
|
5614
5794
|
{
|
|
5615
5795
|
width: "100%",
|
|
5616
|
-
|
|
5617
|
-
viewBox: `0 0 ${width} ${height}`,
|
|
5796
|
+
viewBox: `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
|
|
5618
5797
|
preserveAspectRatio: "xMidYMid meet",
|
|
5619
|
-
className: "bg-white dark:bg-gray-800 block",
|
|
5620
|
-
style: { overflow: "visible" },
|
|
5798
|
+
className: "bg-white dark:bg-gray-800 block w-full",
|
|
5799
|
+
style: { height: "auto", overflow: "visible" },
|
|
5621
5800
|
children: /* @__PURE__ */ jsxs36("g", { transform: `translate(${padding.left}, ${padding.top})`, children: [
|
|
5622
5801
|
gridLines,
|
|
5623
5802
|
renderBars(),
|
|
@@ -5626,11 +5805,12 @@ var BarChart = ({
|
|
|
5626
5805
|
"text",
|
|
5627
5806
|
{
|
|
5628
5807
|
x: chartWidth / 2,
|
|
5629
|
-
y: chartHeight +
|
|
5808
|
+
y: chartHeight + 80,
|
|
5630
5809
|
textAnchor: "middle",
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5810
|
+
dominantBaseline: "hanging",
|
|
5811
|
+
fontSize: axisLabelFontSize,
|
|
5812
|
+
fontWeight: "600",
|
|
5813
|
+
className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
|
|
5634
5814
|
children: xAxisLabel
|
|
5635
5815
|
}
|
|
5636
5816
|
),
|
|
@@ -5638,41 +5818,43 @@ var BarChart = ({
|
|
|
5638
5818
|
"text",
|
|
5639
5819
|
{
|
|
5640
5820
|
x: -chartHeight / 2,
|
|
5641
|
-
y: -
|
|
5821
|
+
y: -100,
|
|
5642
5822
|
textAnchor: "middle",
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5823
|
+
dominantBaseline: "middle",
|
|
5824
|
+
fontSize: axisLabelFontSize,
|
|
5825
|
+
fontWeight: "600",
|
|
5826
|
+
transform: "rotate(-90)",
|
|
5827
|
+
className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
|
|
5647
5828
|
children: yAxisLabel
|
|
5648
5829
|
}
|
|
5649
5830
|
)
|
|
5650
5831
|
] })
|
|
5651
5832
|
}
|
|
5652
5833
|
),
|
|
5653
|
-
showLegend && /* @__PURE__ */ jsx109("div", { className: "flex flex-wrap gap-
|
|
5834
|
+
showLegend && /* @__PURE__ */ jsx109("div", { className: "flex flex-wrap gap-3 justify-center px-4", children: data.map((series, index) => /* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
5654
5835
|
/* @__PURE__ */ jsx109(
|
|
5655
5836
|
"div",
|
|
5656
5837
|
{
|
|
5657
|
-
className: "w-
|
|
5838
|
+
className: "w-3 h-3 rounded-sm flex-shrink-0",
|
|
5658
5839
|
style: {
|
|
5659
|
-
backgroundColor: series.color ||
|
|
5840
|
+
backgroundColor: series.color || colors[index % colors.length]
|
|
5660
5841
|
}
|
|
5661
5842
|
}
|
|
5662
5843
|
),
|
|
5663
|
-
/* @__PURE__ */ jsx109("span", { className: "text-
|
|
5844
|
+
/* @__PURE__ */ jsx109("span", { className: "text-gray-700 dark:text-gray-300", children: series.name })
|
|
5664
5845
|
] }, `legend-${index}`)) }),
|
|
5665
|
-
showTooltip && hoveredBar && /* @__PURE__ */ jsxs36(
|
|
5846
|
+
showTooltip && hoveredBar && tooltipPosition && /* @__PURE__ */ jsxs36(
|
|
5666
5847
|
"div",
|
|
5667
5848
|
{
|
|
5668
|
-
className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg
|
|
5849
|
+
className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg pointer-events-none z-50 text-sm whitespace-nowrap",
|
|
5669
5850
|
style: {
|
|
5670
|
-
left: `${
|
|
5671
|
-
top: `${
|
|
5851
|
+
left: `${tooltipPosition.x}px`,
|
|
5852
|
+
top: `${tooltipPosition.y}px`,
|
|
5853
|
+
transform: "translateZ(0)"
|
|
5672
5854
|
},
|
|
5673
5855
|
children: [
|
|
5674
5856
|
/* @__PURE__ */ jsx109("div", { className: "font-semibold", children: data[hoveredBar.seriesIndex].name }),
|
|
5675
|
-
/* @__PURE__ */ jsxs36("div", { children: [
|
|
5857
|
+
/* @__PURE__ */ jsxs36("div", { className: "text-xs opacity-90", children: [
|
|
5676
5858
|
data[hoveredBar.seriesIndex].data[hoveredBar.barIndex].x,
|
|
5677
5859
|
": ",
|
|
5678
5860
|
data[hoveredBar.seriesIndex].data[hoveredBar.barIndex].y
|
|
@@ -5720,14 +5902,32 @@ var AreaChart = ({
|
|
|
5720
5902
|
strokeWidth = 2,
|
|
5721
5903
|
className = "",
|
|
5722
5904
|
xAxisLabel,
|
|
5723
|
-
yAxisLabel
|
|
5905
|
+
yAxisLabel,
|
|
5906
|
+
baseFontSize = 14
|
|
5724
5907
|
}) => {
|
|
5725
|
-
const
|
|
5726
|
-
const
|
|
5908
|
+
const viewBoxWidth = 1e3;
|
|
5909
|
+
const viewBoxHeight = 600;
|
|
5910
|
+
const containerRef = React28.useRef(null);
|
|
5911
|
+
const svgRef = React28.useRef(null);
|
|
5912
|
+
const [tooltipPosition, setTooltipPosition] = React28.useState(null);
|
|
5727
5913
|
const [hoveredPoint, setHoveredPoint] = React28.useState(null);
|
|
5728
|
-
const
|
|
5729
|
-
const
|
|
5730
|
-
const
|
|
5914
|
+
const chartId = React28.useId();
|
|
5915
|
+
const wrapperClass = `chart-svg-wrapper-${chartId.replace(/:/g, "-")}`;
|
|
5916
|
+
const gridLabelClass = `chart-grid-label-${chartId.replace(/:/g, "-")}`;
|
|
5917
|
+
const axisLabelClass = `chart-axis-label-${chartId.replace(/:/g, "-")}`;
|
|
5918
|
+
const lineClass = `chart-line-${chartId.replace(/:/g, "-")}`;
|
|
5919
|
+
const pointClass = `chart-point-${chartId.replace(/:/g, "-")}`;
|
|
5920
|
+
const padding = {
|
|
5921
|
+
top: 50,
|
|
5922
|
+
right: 50,
|
|
5923
|
+
bottom: showXAxis ? 120 : 50,
|
|
5924
|
+
left: showYAxis ? 130 : 50
|
|
5925
|
+
};
|
|
5926
|
+
const chartWidth = viewBoxWidth - padding.left - padding.right;
|
|
5927
|
+
const chartHeight = viewBoxHeight - padding.top - padding.bottom;
|
|
5928
|
+
const gridLabelFontSize = viewBoxWidth * 0.045;
|
|
5929
|
+
const axisLabelFontSize = viewBoxWidth * 0.05;
|
|
5930
|
+
const titleFontSize = viewBoxWidth * 0.055;
|
|
5731
5931
|
const allPoints = data.flatMap((series) => series.data);
|
|
5732
5932
|
const allYValues = stacked ? data[0]?.data.map(
|
|
5733
5933
|
(_, i) => data.reduce((sum, series) => sum + (series.data[i]?.y || 0), 0)
|
|
@@ -5741,7 +5941,7 @@ var AreaChart = ({
|
|
|
5741
5941
|
const minY = Math.min(0, ...allYValues);
|
|
5742
5942
|
const maxY = Math.max(...allYValues);
|
|
5743
5943
|
const yRange = maxY - minY;
|
|
5744
|
-
const yMin = minY - yRange * 0.1;
|
|
5944
|
+
const yMin = Math.max(0, minY - yRange * 0.1);
|
|
5745
5945
|
const yMax = maxY + yRange * 0.1;
|
|
5746
5946
|
const scaleX = (x, index) => {
|
|
5747
5947
|
const numX = isStringX ? index : x;
|
|
@@ -5822,20 +6022,21 @@ var AreaChart = ({
|
|
|
5822
6022
|
x2: chartWidth,
|
|
5823
6023
|
y2: y,
|
|
5824
6024
|
stroke: "currentColor",
|
|
5825
|
-
strokeWidth: "
|
|
6025
|
+
strokeWidth: "0.5",
|
|
5826
6026
|
className: "text-gray-200 dark:text-gray-700",
|
|
5827
|
-
strokeDasharray: "
|
|
6027
|
+
strokeDasharray: "4,4"
|
|
5828
6028
|
}
|
|
5829
6029
|
),
|
|
5830
6030
|
showYAxis && /* @__PURE__ */ jsx110(
|
|
5831
6031
|
"text",
|
|
5832
6032
|
{
|
|
5833
|
-
x: -
|
|
5834
|
-
y
|
|
6033
|
+
x: -25,
|
|
6034
|
+
y,
|
|
5835
6035
|
textAnchor: "end",
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
|
|
6036
|
+
dominantBaseline: "middle",
|
|
6037
|
+
fontSize: gridLabelFontSize,
|
|
6038
|
+
className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
|
|
6039
|
+
children: yValue.toFixed(1)
|
|
5839
6040
|
}
|
|
5840
6041
|
)
|
|
5841
6042
|
] }, `grid-h-${i}`)
|
|
@@ -5855,19 +6056,20 @@ var AreaChart = ({
|
|
|
5855
6056
|
x2: x,
|
|
5856
6057
|
y2: chartHeight,
|
|
5857
6058
|
stroke: "currentColor",
|
|
5858
|
-
strokeWidth: "
|
|
6059
|
+
strokeWidth: "0.5",
|
|
5859
6060
|
className: "text-gray-200 dark:text-gray-700",
|
|
5860
|
-
strokeDasharray: "
|
|
6061
|
+
strokeDasharray: "4,4"
|
|
5861
6062
|
}
|
|
5862
6063
|
),
|
|
5863
6064
|
showXAxis && /* @__PURE__ */ jsx110(
|
|
5864
6065
|
"text",
|
|
5865
6066
|
{
|
|
5866
6067
|
x,
|
|
5867
|
-
y: chartHeight +
|
|
6068
|
+
y: chartHeight + 35,
|
|
5868
6069
|
textAnchor: "middle",
|
|
5869
|
-
|
|
5870
|
-
|
|
6070
|
+
dominantBaseline: "hanging",
|
|
6071
|
+
fontSize: gridLabelFontSize,
|
|
6072
|
+
className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
|
|
5871
6073
|
children: xValue
|
|
5872
6074
|
}
|
|
5873
6075
|
)
|
|
@@ -5879,20 +6081,72 @@ var AreaChart = ({
|
|
|
5879
6081
|
if (stacked) {
|
|
5880
6082
|
cumulativeValues = Array(data[0]?.data.length || 0).fill(0);
|
|
5881
6083
|
}
|
|
6084
|
+
const getTooltipPosition = React28.useCallback((x, y) => {
|
|
6085
|
+
if (!containerRef.current) return { x, y };
|
|
6086
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
6087
|
+
const tooltipWidth = 120;
|
|
6088
|
+
const tooltipHeight = 80;
|
|
6089
|
+
let tooltipX = x + 10;
|
|
6090
|
+
let tooltipY = y - 30;
|
|
6091
|
+
if (tooltipX + tooltipWidth > rect.width) {
|
|
6092
|
+
tooltipX = x - tooltipWidth - 10;
|
|
6093
|
+
}
|
|
6094
|
+
if (tooltipY + tooltipHeight > rect.height) {
|
|
6095
|
+
tooltipY = y + 30;
|
|
6096
|
+
}
|
|
6097
|
+
return { x: tooltipX, y: tooltipY };
|
|
6098
|
+
}, []);
|
|
6099
|
+
const containerStyle = {
|
|
6100
|
+
"--font-size-base": `${baseFontSize}px`,
|
|
6101
|
+
"--font-size-lg": `calc(var(--font-size-base) * 1.125)`,
|
|
6102
|
+
"--font-size-sm": `calc(var(--font-size-base) * 0.875)`,
|
|
6103
|
+
"--font-size-xs": `calc(var(--font-size-base) * 0.75)`
|
|
6104
|
+
};
|
|
5882
6105
|
return /* @__PURE__ */ jsxs37(
|
|
5883
6106
|
"div",
|
|
5884
6107
|
{
|
|
5885
|
-
|
|
5886
|
-
|
|
6108
|
+
ref: containerRef,
|
|
6109
|
+
className: `relative flex flex-col gap-4 ${responsive ? "w-full" : "inline-block"} ${className}`,
|
|
6110
|
+
style: containerStyle,
|
|
5887
6111
|
children: [
|
|
6112
|
+
/* @__PURE__ */ jsx110("style", { children: `
|
|
6113
|
+
/* Mobile: Large fonts, hidden axis titles, thicker lines (default) */
|
|
6114
|
+
.${gridLabelClass} { font-size: ${gridLabelFontSize}px !important; }
|
|
6115
|
+
.${axisLabelClass} { display: none; }
|
|
6116
|
+
.${lineClass} { stroke-width: ${strokeWidth * 2.5} !important; }
|
|
6117
|
+
.${pointClass} { r: 6 !important; stroke-width: 3 !important; }
|
|
6118
|
+
|
|
6119
|
+
/* Tablet: Medium fonts, show axis titles, medium lines */
|
|
6120
|
+
@media (min-width: 640px) {
|
|
6121
|
+
.${gridLabelClass} { font-size: ${gridLabelFontSize * 0.7}px !important; }
|
|
6122
|
+
.${axisLabelClass} {
|
|
6123
|
+
font-size: ${axisLabelFontSize * 0.7}px !important;
|
|
6124
|
+
display: block;
|
|
6125
|
+
}
|
|
6126
|
+
.${lineClass} { stroke-width: ${strokeWidth * 1.5} !important; }
|
|
6127
|
+
.${pointClass} { r: 4 !important; stroke-width: 2 !important; }
|
|
6128
|
+
}
|
|
6129
|
+
|
|
6130
|
+
/* Desktop: Small fonts, show axis titles, normal lines */
|
|
6131
|
+
@media (min-width: 1024px) {
|
|
6132
|
+
.${gridLabelClass} { font-size: ${gridLabelFontSize * 0.4}px !important; }
|
|
6133
|
+
.${axisLabelClass} {
|
|
6134
|
+
font-size: ${axisLabelFontSize * 0.4}px !important;
|
|
6135
|
+
display: block;
|
|
6136
|
+
}
|
|
6137
|
+
.${lineClass} { stroke-width: ${strokeWidth} !important; }
|
|
6138
|
+
.${pointClass} { r: 3 !important; stroke-width: 1.5 !important; }
|
|
6139
|
+
}
|
|
6140
|
+
` }),
|
|
5888
6141
|
/* @__PURE__ */ jsx110(
|
|
5889
6142
|
"svg",
|
|
5890
6143
|
{
|
|
6144
|
+
ref: svgRef,
|
|
5891
6145
|
width: "100%",
|
|
5892
|
-
|
|
5893
|
-
viewBox: `0 0 ${width} ${height}`,
|
|
6146
|
+
viewBox: `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
|
|
5894
6147
|
preserveAspectRatio: "xMidYMid meet",
|
|
5895
|
-
className: "bg-white dark:bg-gray-800 block",
|
|
6148
|
+
className: "bg-white dark:bg-gray-800 block w-full",
|
|
6149
|
+
style: { height: "auto", overflow: "visible" },
|
|
5896
6150
|
children: /* @__PURE__ */ jsxs37("g", { transform: `translate(${padding.left}, ${padding.top})`, children: [
|
|
5897
6151
|
gridLines,
|
|
5898
6152
|
data.map((series, seriesIndex) => {
|
|
@@ -5921,7 +6175,8 @@ var AreaChart = ({
|
|
|
5921
6175
|
stroke: series.color || defaultColors3[seriesIndex % defaultColors3.length],
|
|
5922
6176
|
strokeWidth,
|
|
5923
6177
|
strokeLinecap: "round",
|
|
5924
|
-
strokeLinejoin: "round"
|
|
6178
|
+
strokeLinejoin: "round",
|
|
6179
|
+
className: lineClass
|
|
5925
6180
|
}
|
|
5926
6181
|
)
|
|
5927
6182
|
] }, `area-${seriesIndex}`);
|
|
@@ -5943,9 +6198,28 @@ var AreaChart = ({
|
|
|
5943
6198
|
fill: series.color || defaultColors3[seriesIndex % defaultColors3.length],
|
|
5944
6199
|
stroke: "white",
|
|
5945
6200
|
strokeWidth: "2",
|
|
5946
|
-
className:
|
|
5947
|
-
onMouseEnter: () =>
|
|
5948
|
-
|
|
6201
|
+
className: `cursor-pointer transition-all ${pointClass}`,
|
|
6202
|
+
onMouseEnter: (e) => {
|
|
6203
|
+
if (showTooltip && containerRef.current) {
|
|
6204
|
+
setHoveredPoint({ seriesIndex, pointIndex, x, y });
|
|
6205
|
+
const containerRect = containerRef.current.getBoundingClientRect();
|
|
6206
|
+
const mouseX = e.clientX - containerRect.left;
|
|
6207
|
+
const mouseY = e.clientY - containerRect.top;
|
|
6208
|
+
setTooltipPosition(getTooltipPosition(mouseX, mouseY));
|
|
6209
|
+
}
|
|
6210
|
+
},
|
|
6211
|
+
onMouseMove: (e) => {
|
|
6212
|
+
if (showTooltip && hoveredPoint?.seriesIndex === seriesIndex && hoveredPoint?.pointIndex === pointIndex && containerRef.current) {
|
|
6213
|
+
const containerRect = containerRef.current.getBoundingClientRect();
|
|
6214
|
+
const mouseX = e.clientX - containerRect.left;
|
|
6215
|
+
const mouseY = e.clientY - containerRect.top;
|
|
6216
|
+
setTooltipPosition(getTooltipPosition(mouseX, mouseY));
|
|
6217
|
+
}
|
|
6218
|
+
},
|
|
6219
|
+
onMouseLeave: () => {
|
|
6220
|
+
setHoveredPoint(null);
|
|
6221
|
+
setTooltipPosition(null);
|
|
6222
|
+
}
|
|
5949
6223
|
},
|
|
5950
6224
|
`point-${seriesIndex}-${pointIndex}`
|
|
5951
6225
|
);
|
|
@@ -5955,11 +6229,12 @@ var AreaChart = ({
|
|
|
5955
6229
|
"text",
|
|
5956
6230
|
{
|
|
5957
6231
|
x: chartWidth / 2,
|
|
5958
|
-
y: chartHeight +
|
|
6232
|
+
y: chartHeight + 80,
|
|
5959
6233
|
textAnchor: "middle",
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
6234
|
+
dominantBaseline: "hanging",
|
|
6235
|
+
fontSize: axisLabelFontSize,
|
|
6236
|
+
fontWeight: "600",
|
|
6237
|
+
className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
|
|
5963
6238
|
children: xAxisLabel
|
|
5964
6239
|
}
|
|
5965
6240
|
),
|
|
@@ -5967,45 +6242,47 @@ var AreaChart = ({
|
|
|
5967
6242
|
"text",
|
|
5968
6243
|
{
|
|
5969
6244
|
x: -chartHeight / 2,
|
|
5970
|
-
y: -
|
|
6245
|
+
y: -100,
|
|
5971
6246
|
textAnchor: "middle",
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
6247
|
+
dominantBaseline: "middle",
|
|
6248
|
+
fontSize: axisLabelFontSize,
|
|
6249
|
+
fontWeight: "600",
|
|
6250
|
+
transform: "rotate(-90)",
|
|
6251
|
+
className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
|
|
5976
6252
|
children: yAxisLabel
|
|
5977
6253
|
}
|
|
5978
6254
|
)
|
|
5979
6255
|
] })
|
|
5980
6256
|
}
|
|
5981
6257
|
),
|
|
5982
|
-
showLegend && /* @__PURE__ */ jsx110("div", { className: "flex flex-wrap gap-
|
|
6258
|
+
showLegend && /* @__PURE__ */ jsx110("div", { className: "flex flex-wrap gap-3 justify-center px-4", children: data.map((series, index) => /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
5983
6259
|
/* @__PURE__ */ jsx110(
|
|
5984
6260
|
"div",
|
|
5985
6261
|
{
|
|
5986
|
-
className: "w-
|
|
6262
|
+
className: "w-3 h-3 rounded-sm flex-shrink-0",
|
|
5987
6263
|
style: {
|
|
5988
6264
|
backgroundColor: series.color || defaultColors3[index % defaultColors3.length]
|
|
5989
6265
|
}
|
|
5990
6266
|
}
|
|
5991
6267
|
),
|
|
5992
|
-
/* @__PURE__ */ jsx110("span", { className: "text-
|
|
6268
|
+
/* @__PURE__ */ jsx110("span", { className: "text-gray-700 dark:text-gray-300", children: series.name })
|
|
5993
6269
|
] }, `legend-${index}`)) }),
|
|
5994
|
-
showTooltip && hoveredPoint && /* @__PURE__ */ jsxs37(
|
|
6270
|
+
showTooltip && hoveredPoint && tooltipPosition && /* @__PURE__ */ jsxs37(
|
|
5995
6271
|
"div",
|
|
5996
6272
|
{
|
|
5997
|
-
className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg
|
|
6273
|
+
className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg pointer-events-none z-50 text-sm whitespace-nowrap",
|
|
5998
6274
|
style: {
|
|
5999
|
-
left: `${
|
|
6000
|
-
top: `${
|
|
6275
|
+
left: `${tooltipPosition.x}px`,
|
|
6276
|
+
top: `${tooltipPosition.y}px`,
|
|
6277
|
+
transform: "translateZ(0)"
|
|
6001
6278
|
},
|
|
6002
6279
|
children: [
|
|
6003
6280
|
/* @__PURE__ */ jsx110("div", { className: "font-semibold", children: data[hoveredPoint.seriesIndex].name }),
|
|
6004
|
-
/* @__PURE__ */ jsxs37("div", { children: [
|
|
6281
|
+
/* @__PURE__ */ jsxs37("div", { className: "text-xs opacity-90", children: [
|
|
6005
6282
|
"x: ",
|
|
6006
6283
|
data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].x
|
|
6007
6284
|
] }),
|
|
6008
|
-
/* @__PURE__ */ jsxs37("div", { children: [
|
|
6285
|
+
/* @__PURE__ */ jsxs37("div", { className: "text-xs opacity-90", children: [
|
|
6009
6286
|
"y: ",
|
|
6010
6287
|
data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].y
|
|
6011
6288
|
] })
|
|
@@ -6050,16 +6327,27 @@ var PieChart = ({
|
|
|
6050
6327
|
showPercentages = false,
|
|
6051
6328
|
donut = false,
|
|
6052
6329
|
donutWidth = 60,
|
|
6053
|
-
className = ""
|
|
6330
|
+
className = "",
|
|
6331
|
+
baseFontSize = 14
|
|
6054
6332
|
}) => {
|
|
6055
|
-
const
|
|
6056
|
-
const
|
|
6333
|
+
const viewBoxWidth = 600;
|
|
6334
|
+
const viewBoxHeight = 600;
|
|
6335
|
+
const containerRef = React29.useRef(null);
|
|
6336
|
+
const [tooltipPosition, setTooltipPosition] = React29.useState(null);
|
|
6057
6337
|
const [hoveredSlice, setHoveredSlice] = React29.useState(null);
|
|
6338
|
+
const chartId = React29.useId();
|
|
6339
|
+
const wrapperClass = `chart-svg-wrapper-${chartId.replace(/:/g, "-")}`;
|
|
6340
|
+
const gridLabelClass = `chart-grid-label-${chartId.replace(/:/g, "-")}`;
|
|
6341
|
+
const axisLabelClass = `chart-axis-label-${chartId.replace(/:/g, "-")}`;
|
|
6342
|
+
const sliceClass = `chart-slice-${chartId.replace(/:/g, "-")}`;
|
|
6058
6343
|
const total = data.reduce((sum, item) => sum + item.value, 0);
|
|
6059
|
-
const centerX =
|
|
6060
|
-
const centerY =
|
|
6061
|
-
const radius = Math.min(
|
|
6344
|
+
const centerX = viewBoxWidth / 2;
|
|
6345
|
+
const centerY = viewBoxHeight / 2;
|
|
6346
|
+
const radius = Math.min(viewBoxWidth, viewBoxHeight) / 2 - 40;
|
|
6062
6347
|
const innerRadius = donut ? radius - donutWidth : 0;
|
|
6348
|
+
const gridLabelFontSize = viewBoxWidth * 0.045;
|
|
6349
|
+
const axisLabelFontSize = viewBoxWidth * 0.05;
|
|
6350
|
+
const titleFontSize = viewBoxWidth * 0.055;
|
|
6063
6351
|
let currentAngle = -90;
|
|
6064
6352
|
const slices = data.map((item, index) => {
|
|
6065
6353
|
const percentage = item.value / total * 100;
|
|
@@ -6111,20 +6399,64 @@ var PieChart = ({
|
|
|
6111
6399
|
index
|
|
6112
6400
|
};
|
|
6113
6401
|
});
|
|
6402
|
+
const getTooltipPosition = React29.useCallback((x, y) => {
|
|
6403
|
+
if (!containerRef.current) return { x, y };
|
|
6404
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
6405
|
+
const tooltipWidth = 120;
|
|
6406
|
+
const tooltipHeight = 80;
|
|
6407
|
+
let tooltipX = x + 10;
|
|
6408
|
+
let tooltipY = y - 30;
|
|
6409
|
+
if (tooltipX + tooltipWidth > rect.width) {
|
|
6410
|
+
tooltipX = x - tooltipWidth - 10;
|
|
6411
|
+
}
|
|
6412
|
+
if (tooltipY + tooltipHeight > rect.height) {
|
|
6413
|
+
tooltipY = y + 30;
|
|
6414
|
+
}
|
|
6415
|
+
return { x: tooltipX, y: tooltipY };
|
|
6416
|
+
}, []);
|
|
6417
|
+
const containerStyle = {
|
|
6418
|
+
"--font-size-base": `${baseFontSize}px`,
|
|
6419
|
+
"--font-size-lg": `calc(var(--font-size-base) * 1.125)`,
|
|
6420
|
+
"--font-size-sm": `calc(var(--font-size-base) * 0.875)`,
|
|
6421
|
+
"--font-size-xs": `calc(var(--font-size-base) * 0.75)`,
|
|
6422
|
+
"--font-size-xl": `calc(var(--font-size-base) * 1.5)`,
|
|
6423
|
+
"--font-size-2xl": `calc(var(--font-size-base) * 2)`
|
|
6424
|
+
};
|
|
6425
|
+
if (responsive) {
|
|
6426
|
+
containerStyle["--font-size-base"] = `clamp(${baseFontSize * 0.8}px, 4vw, ${baseFontSize}px)`;
|
|
6427
|
+
}
|
|
6114
6428
|
return /* @__PURE__ */ jsxs38(
|
|
6115
6429
|
"div",
|
|
6116
6430
|
{
|
|
6117
|
-
|
|
6118
|
-
|
|
6431
|
+
ref: containerRef,
|
|
6432
|
+
className: `relative flex flex-col gap-4 ${responsive ? "w-full" : "inline-block"} ${className}`,
|
|
6433
|
+
style: containerStyle,
|
|
6119
6434
|
children: [
|
|
6435
|
+
/* @__PURE__ */ jsx111("style", { children: `
|
|
6436
|
+
/* Mobile: Large fonts (default) */
|
|
6437
|
+
.${gridLabelClass} { font-size: ${gridLabelFontSize}px !important; }
|
|
6438
|
+
.${axisLabelClass} { font-size: ${titleFontSize}px !important; }
|
|
6439
|
+
|
|
6440
|
+
/* Tablet: Medium fonts */
|
|
6441
|
+
@media (min-width: 640px) {
|
|
6442
|
+
.${gridLabelClass} { font-size: ${gridLabelFontSize * 0.7}px !important; }
|
|
6443
|
+
.${axisLabelClass} { font-size: ${titleFontSize * 0.7}px !important; }
|
|
6444
|
+
}
|
|
6445
|
+
|
|
6446
|
+
/* Desktop: Small fonts */
|
|
6447
|
+
@media (min-width: 1024px) {
|
|
6448
|
+
.${gridLabelClass} { font-size: ${gridLabelFontSize * 0.4}px !important; }
|
|
6449
|
+
.${axisLabelClass} { font-size: ${titleFontSize * 0.4}px !important; }
|
|
6450
|
+
}
|
|
6451
|
+
` }),
|
|
6120
6452
|
/* @__PURE__ */ jsxs38(
|
|
6121
6453
|
"svg",
|
|
6122
6454
|
{
|
|
6123
6455
|
width: "100%",
|
|
6124
|
-
|
|
6125
|
-
viewBox: `0 0 ${width} ${height}`,
|
|
6456
|
+
viewBox: `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
|
|
6126
6457
|
preserveAspectRatio: "xMidYMid meet",
|
|
6127
|
-
className: "bg-white dark:bg-gray-800 block",
|
|
6458
|
+
className: "bg-white dark:bg-gray-800 block w-full",
|
|
6459
|
+
style: { height: "auto", overflow: "visible" },
|
|
6128
6460
|
children: [
|
|
6129
6461
|
slices.map((slice) => {
|
|
6130
6462
|
const isHovered = hoveredSlice === slice.index;
|
|
@@ -6138,8 +6470,19 @@ var PieChart = ({
|
|
|
6138
6470
|
strokeWidth: "2",
|
|
6139
6471
|
className: "cursor-pointer transition-opacity",
|
|
6140
6472
|
opacity: isHovered ? 0.8 : 1,
|
|
6141
|
-
onMouseEnter: () =>
|
|
6142
|
-
|
|
6473
|
+
onMouseEnter: (e) => {
|
|
6474
|
+
setHoveredSlice(slice.index);
|
|
6475
|
+
if (containerRef.current) {
|
|
6476
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
6477
|
+
const svgX = e.clientX - rect.left;
|
|
6478
|
+
const svgY = e.clientY - rect.top;
|
|
6479
|
+
setTooltipPosition(getTooltipPosition(svgX, svgY));
|
|
6480
|
+
}
|
|
6481
|
+
},
|
|
6482
|
+
onMouseLeave: () => {
|
|
6483
|
+
setHoveredSlice(null);
|
|
6484
|
+
setTooltipPosition(null);
|
|
6485
|
+
}
|
|
6143
6486
|
}
|
|
6144
6487
|
),
|
|
6145
6488
|
showLabels && slice.percentage > 5 && /* @__PURE__ */ jsxs38(
|
|
@@ -6149,9 +6492,9 @@ var PieChart = ({
|
|
|
6149
6492
|
y: slice.labelY,
|
|
6150
6493
|
textAnchor: "middle",
|
|
6151
6494
|
dominantBaseline: "middle",
|
|
6152
|
-
fontSize:
|
|
6495
|
+
fontSize: gridLabelFontSize,
|
|
6153
6496
|
fontWeight: "600",
|
|
6154
|
-
className:
|
|
6497
|
+
className: `fill-gray-700 dark:fill-gray-200 pointer-events-none ${gridLabelClass}`,
|
|
6155
6498
|
children: [
|
|
6156
6499
|
showPercentages && `${slice.percentage.toFixed(1)}%`,
|
|
6157
6500
|
showPercentages && showValues && " ",
|
|
@@ -6169,9 +6512,10 @@ var PieChart = ({
|
|
|
6169
6512
|
x: centerX,
|
|
6170
6513
|
y: centerY - 10,
|
|
6171
6514
|
textAnchor: "middle",
|
|
6172
|
-
|
|
6515
|
+
dominantBaseline: "middle",
|
|
6516
|
+
fontSize: titleFontSize,
|
|
6173
6517
|
fontWeight: "700",
|
|
6174
|
-
className:
|
|
6518
|
+
className: `fill-gray-900 dark:fill-gray-100 ${axisLabelClass}`,
|
|
6175
6519
|
children: total
|
|
6176
6520
|
}
|
|
6177
6521
|
),
|
|
@@ -6181,8 +6525,9 @@ var PieChart = ({
|
|
|
6181
6525
|
x: centerX,
|
|
6182
6526
|
y: centerY + 15,
|
|
6183
6527
|
textAnchor: "middle",
|
|
6184
|
-
|
|
6185
|
-
|
|
6528
|
+
dominantBaseline: "middle",
|
|
6529
|
+
fontSize: axisLabelFontSize,
|
|
6530
|
+
className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
|
|
6186
6531
|
children: "Total"
|
|
6187
6532
|
}
|
|
6188
6533
|
)
|
|
@@ -6190,23 +6535,23 @@ var PieChart = ({
|
|
|
6190
6535
|
]
|
|
6191
6536
|
}
|
|
6192
6537
|
),
|
|
6193
|
-
showLegend && /* @__PURE__ */ jsx111("div", { className: "flex flex-wrap gap-
|
|
6538
|
+
showLegend && /* @__PURE__ */ jsx111("div", { className: "flex flex-wrap gap-3 justify-center px-4", children: data.map((item, index) => /* @__PURE__ */ jsxs38(
|
|
6194
6539
|
"div",
|
|
6195
6540
|
{
|
|
6196
|
-
className: "flex items-center gap-2 cursor-pointer",
|
|
6541
|
+
className: "flex items-center gap-2 text-sm cursor-pointer",
|
|
6197
6542
|
onMouseEnter: () => setHoveredSlice(index),
|
|
6198
6543
|
onMouseLeave: () => setHoveredSlice(null),
|
|
6199
6544
|
children: [
|
|
6200
6545
|
/* @__PURE__ */ jsx111(
|
|
6201
6546
|
"div",
|
|
6202
6547
|
{
|
|
6203
|
-
className: "w-
|
|
6548
|
+
className: "w-3 h-3 rounded-sm flex-shrink-0",
|
|
6204
6549
|
style: {
|
|
6205
6550
|
backgroundColor: item.color || defaultColors4[index % defaultColors4.length]
|
|
6206
6551
|
}
|
|
6207
6552
|
}
|
|
6208
6553
|
),
|
|
6209
|
-
/* @__PURE__ */ jsxs38("span", { className: "text-
|
|
6554
|
+
/* @__PURE__ */ jsxs38("span", { className: "text-gray-700 dark:text-gray-300", children: [
|
|
6210
6555
|
item.label,
|
|
6211
6556
|
": ",
|
|
6212
6557
|
item.value,
|
|
@@ -6216,18 +6561,29 @@ var PieChart = ({
|
|
|
6216
6561
|
},
|
|
6217
6562
|
`legend-${index}`
|
|
6218
6563
|
)) }),
|
|
6219
|
-
hoveredSlice !== null && /* @__PURE__ */ jsxs38(
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
"
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6564
|
+
hoveredSlice !== null && tooltipPosition && /* @__PURE__ */ jsxs38(
|
|
6565
|
+
"div",
|
|
6566
|
+
{
|
|
6567
|
+
className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg pointer-events-none z-50 text-sm whitespace-nowrap",
|
|
6568
|
+
style: {
|
|
6569
|
+
left: `${tooltipPosition.x}px`,
|
|
6570
|
+
top: `${tooltipPosition.y}px`,
|
|
6571
|
+
transform: "translateZ(0)"
|
|
6572
|
+
},
|
|
6573
|
+
children: [
|
|
6574
|
+
/* @__PURE__ */ jsx111("div", { className: "font-semibold", children: data[hoveredSlice].label }),
|
|
6575
|
+
/* @__PURE__ */ jsxs38("div", { className: "text-xs opacity-90", children: [
|
|
6576
|
+
"Value: ",
|
|
6577
|
+
data[hoveredSlice].value
|
|
6578
|
+
] }),
|
|
6579
|
+
/* @__PURE__ */ jsxs38("div", { className: "text-xs opacity-90", children: [
|
|
6580
|
+
"Percentage: ",
|
|
6581
|
+
(data[hoveredSlice].value / total * 100).toFixed(1),
|
|
6582
|
+
"%"
|
|
6583
|
+
] })
|
|
6584
|
+
]
|
|
6585
|
+
}
|
|
6586
|
+
)
|
|
6231
6587
|
]
|
|
6232
6588
|
}
|
|
6233
6589
|
);
|