@marcoschwartz/lite-ui 0.11.0 → 0.15.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 +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +623 -412
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +623 -412
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3333,6 +3333,7 @@ var RichTextEditor = ({
|
|
|
3333
3333
|
const [showImageModal, setShowImageModal] = (0, import_react20.useState)(false);
|
|
3334
3334
|
const [imageUrl, setImageUrl] = (0, import_react20.useState)("");
|
|
3335
3335
|
const [imageAlt, setImageAlt] = (0, import_react20.useState)("");
|
|
3336
|
+
const savedSelection = (0, import_react20.useRef)(null);
|
|
3336
3337
|
(0, import_react20.useLayoutEffect)(() => {
|
|
3337
3338
|
const styleId = "rich-text-editor-styles";
|
|
3338
3339
|
if (!document.getElementById(styleId)) {
|
|
@@ -3359,6 +3360,15 @@ var RichTextEditor = ({
|
|
|
3359
3360
|
font-weight: bold;
|
|
3360
3361
|
margin: 0.83em 0;
|
|
3361
3362
|
}
|
|
3363
|
+
[contenteditable] p {
|
|
3364
|
+
margin: 0.5em 0;
|
|
3365
|
+
}
|
|
3366
|
+
[contenteditable] p:first-child {
|
|
3367
|
+
margin-top: 0;
|
|
3368
|
+
}
|
|
3369
|
+
[contenteditable] p:last-child {
|
|
3370
|
+
margin-bottom: 0;
|
|
3371
|
+
}
|
|
3362
3372
|
[contenteditable] ul, [contenteditable] ol {
|
|
3363
3373
|
margin: 1em 0;
|
|
3364
3374
|
padding-left: 2em;
|
|
@@ -3387,11 +3397,60 @@ var RichTextEditor = ({
|
|
|
3387
3397
|
}
|
|
3388
3398
|
}, []);
|
|
3389
3399
|
const isInitialRender = (0, import_react20.useRef)(true);
|
|
3400
|
+
const isInternalUpdate = (0, import_react20.useRef)(false);
|
|
3390
3401
|
(0, import_react20.useEffect)(() => {
|
|
3391
|
-
if (
|
|
3402
|
+
if (isInitialRender.current && editorRef.current) {
|
|
3392
3403
|
editorRef.current.innerHTML = value;
|
|
3404
|
+
isInitialRender.current = false;
|
|
3405
|
+
try {
|
|
3406
|
+
document.execCommand("defaultParagraphSeparator", false, "p");
|
|
3407
|
+
} catch (e) {
|
|
3408
|
+
console.warn("Could not set defaultParagraphSeparator", e);
|
|
3409
|
+
}
|
|
3393
3410
|
}
|
|
3394
|
-
|
|
3411
|
+
}, []);
|
|
3412
|
+
(0, import_react20.useEffect)(() => {
|
|
3413
|
+
if (!isInitialRender.current && !isInternalUpdate.current && editorRef.current) {
|
|
3414
|
+
const currentHtml = editorRef.current.innerHTML;
|
|
3415
|
+
if (currentHtml !== value) {
|
|
3416
|
+
const selection = window.getSelection();
|
|
3417
|
+
const range = selection && selection.rangeCount > 0 ? selection.getRangeAt(0) : null;
|
|
3418
|
+
const preSelectionRange = range ? range.cloneRange() : null;
|
|
3419
|
+
if (preSelectionRange && editorRef.current.contains(preSelectionRange.startContainer)) {
|
|
3420
|
+
preSelectionRange.selectNodeContents(editorRef.current);
|
|
3421
|
+
preSelectionRange.setEnd(range.startContainer, range.startOffset);
|
|
3422
|
+
const start = preSelectionRange.toString().length;
|
|
3423
|
+
editorRef.current.innerHTML = value;
|
|
3424
|
+
const textNodes = [];
|
|
3425
|
+
const getTextNodes = (node) => {
|
|
3426
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
3427
|
+
textNodes.push(node);
|
|
3428
|
+
} else {
|
|
3429
|
+
node.childNodes.forEach(getTextNodes);
|
|
3430
|
+
}
|
|
3431
|
+
};
|
|
3432
|
+
getTextNodes(editorRef.current);
|
|
3433
|
+
let charCount = 0;
|
|
3434
|
+
let foundStart = false;
|
|
3435
|
+
for (const textNode of textNodes) {
|
|
3436
|
+
const textLength = textNode.textContent?.length || 0;
|
|
3437
|
+
if (!foundStart && charCount + textLength >= start) {
|
|
3438
|
+
const newRange = document.createRange();
|
|
3439
|
+
newRange.setStart(textNode, start - charCount);
|
|
3440
|
+
newRange.collapse(true);
|
|
3441
|
+
selection?.removeAllRanges();
|
|
3442
|
+
selection?.addRange(newRange);
|
|
3443
|
+
foundStart = true;
|
|
3444
|
+
break;
|
|
3445
|
+
}
|
|
3446
|
+
charCount += textLength;
|
|
3447
|
+
}
|
|
3448
|
+
} else {
|
|
3449
|
+
editorRef.current.innerHTML = value;
|
|
3450
|
+
}
|
|
3451
|
+
}
|
|
3452
|
+
}
|
|
3453
|
+
isInternalUpdate.current = false;
|
|
3395
3454
|
}, [value]);
|
|
3396
3455
|
const updateActiveFormats = (0, import_react20.useCallback)(() => {
|
|
3397
3456
|
const formats = /* @__PURE__ */ new Set();
|
|
@@ -3412,10 +3471,25 @@ var RichTextEditor = ({
|
|
|
3412
3471
|
}, []);
|
|
3413
3472
|
const handleInput = (0, import_react20.useCallback)(() => {
|
|
3414
3473
|
if (editorRef.current && onChange) {
|
|
3474
|
+
isInternalUpdate.current = true;
|
|
3415
3475
|
onChange(editorRef.current.innerHTML);
|
|
3416
3476
|
}
|
|
3417
3477
|
updateActiveFormats();
|
|
3418
3478
|
}, [onChange, updateActiveFormats]);
|
|
3479
|
+
const handleFocus = (0, import_react20.useCallback)(() => {
|
|
3480
|
+
setIsFocused(true);
|
|
3481
|
+
if (editorRef.current && (!editorRef.current.innerHTML || editorRef.current.innerHTML === "")) {
|
|
3482
|
+
editorRef.current.innerHTML = "<p><br></p>";
|
|
3483
|
+
const selection = window.getSelection();
|
|
3484
|
+
const range = document.createRange();
|
|
3485
|
+
if (editorRef.current.firstChild) {
|
|
3486
|
+
range.setStart(editorRef.current.firstChild, 0);
|
|
3487
|
+
range.collapse(true);
|
|
3488
|
+
selection?.removeAllRanges();
|
|
3489
|
+
selection?.addRange(range);
|
|
3490
|
+
}
|
|
3491
|
+
}
|
|
3492
|
+
}, []);
|
|
3419
3493
|
const handleFormat = (0, import_react20.useCallback)((command) => {
|
|
3420
3494
|
if (disabled) return;
|
|
3421
3495
|
document.execCommand(command, false);
|
|
@@ -3439,16 +3513,29 @@ var RichTextEditor = ({
|
|
|
3439
3513
|
}, [disabled, updateActiveFormats, handleInput]);
|
|
3440
3514
|
const handleLink = (0, import_react20.useCallback)(() => {
|
|
3441
3515
|
if (disabled) return;
|
|
3516
|
+
const selection = window.getSelection();
|
|
3517
|
+
if (selection && selection.rangeCount > 0) {
|
|
3518
|
+
savedSelection.current = selection.getRangeAt(0).cloneRange();
|
|
3519
|
+
}
|
|
3442
3520
|
setShowLinkModal(true);
|
|
3443
3521
|
}, [disabled]);
|
|
3444
3522
|
const insertLink = (0, import_react20.useCallback)(() => {
|
|
3445
|
-
if (linkUrl)
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3523
|
+
if (!linkUrl || !editorRef.current) return;
|
|
3524
|
+
const selection = window.getSelection();
|
|
3525
|
+
if (savedSelection.current && selection) {
|
|
3526
|
+
try {
|
|
3527
|
+
selection.removeAllRanges();
|
|
3528
|
+
selection.addRange(savedSelection.current);
|
|
3529
|
+
document.execCommand("createLink", false, linkUrl);
|
|
3530
|
+
savedSelection.current = null;
|
|
3531
|
+
} catch (e) {
|
|
3532
|
+
console.warn("Could not insert link at saved position", e);
|
|
3533
|
+
}
|
|
3451
3534
|
}
|
|
3535
|
+
setShowLinkModal(false);
|
|
3536
|
+
setLinkUrl("");
|
|
3537
|
+
editorRef.current?.focus();
|
|
3538
|
+
handleInput();
|
|
3452
3539
|
}, [linkUrl, handleInput]);
|
|
3453
3540
|
const handleCode = (0, import_react20.useCallback)(() => {
|
|
3454
3541
|
if (disabled) return;
|
|
@@ -3468,33 +3555,82 @@ var RichTextEditor = ({
|
|
|
3468
3555
|
}, [disabled, handleInput]);
|
|
3469
3556
|
const handleImage = (0, import_react20.useCallback)(() => {
|
|
3470
3557
|
if (disabled) return;
|
|
3558
|
+
const selection = window.getSelection();
|
|
3559
|
+
if (selection && selection.rangeCount > 0) {
|
|
3560
|
+
savedSelection.current = selection.getRangeAt(0).cloneRange();
|
|
3561
|
+
}
|
|
3471
3562
|
setShowImageModal(true);
|
|
3472
3563
|
}, [disabled]);
|
|
3473
3564
|
const insertImage = (0, import_react20.useCallback)(() => {
|
|
3474
|
-
if (!imageUrl) return;
|
|
3565
|
+
if (!imageUrl || !editorRef.current) return;
|
|
3566
|
+
editorRef.current.focus();
|
|
3475
3567
|
const img = document.createElement("img");
|
|
3476
3568
|
img.src = imageUrl;
|
|
3477
3569
|
img.alt = imageAlt || "";
|
|
3478
3570
|
img.style.maxWidth = "100%";
|
|
3479
3571
|
img.style.height = "auto";
|
|
3480
3572
|
const selection = window.getSelection();
|
|
3481
|
-
if (
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3573
|
+
if (savedSelection.current && selection && editorRef.current.contains(savedSelection.current.commonAncestorContainer)) {
|
|
3574
|
+
try {
|
|
3575
|
+
selection.removeAllRanges();
|
|
3576
|
+
selection.addRange(savedSelection.current);
|
|
3577
|
+
savedSelection.current.deleteContents();
|
|
3578
|
+
savedSelection.current.insertNode(img);
|
|
3579
|
+
const br = document.createElement("br");
|
|
3580
|
+
savedSelection.current.setStartAfter(img);
|
|
3581
|
+
savedSelection.current.insertNode(br);
|
|
3582
|
+
savedSelection.current.setStartAfter(br);
|
|
3583
|
+
savedSelection.current.collapse(true);
|
|
3584
|
+
selection.removeAllRanges();
|
|
3585
|
+
selection.addRange(savedSelection.current);
|
|
3586
|
+
savedSelection.current = null;
|
|
3587
|
+
} catch (e) {
|
|
3588
|
+
console.warn("Could not insert at saved position", e);
|
|
3589
|
+
if (selection.rangeCount > 0) {
|
|
3590
|
+
const range = selection.getRangeAt(0);
|
|
3591
|
+
if (editorRef.current.contains(range.commonAncestorContainer)) {
|
|
3592
|
+
range.insertNode(img);
|
|
3593
|
+
const br = document.createElement("br");
|
|
3594
|
+
range.setStartAfter(img);
|
|
3595
|
+
range.insertNode(br);
|
|
3596
|
+
range.setStartAfter(br);
|
|
3597
|
+
range.collapse(true);
|
|
3598
|
+
} else {
|
|
3599
|
+
editorRef.current.appendChild(img);
|
|
3600
|
+
editorRef.current.appendChild(document.createElement("br"));
|
|
3601
|
+
}
|
|
3602
|
+
} else {
|
|
3603
|
+
editorRef.current.appendChild(img);
|
|
3604
|
+
editorRef.current.appendChild(document.createElement("br"));
|
|
3605
|
+
}
|
|
3606
|
+
}
|
|
3607
|
+
} else {
|
|
3608
|
+
if (selection && selection.rangeCount > 0) {
|
|
3609
|
+
const range = selection.getRangeAt(0);
|
|
3610
|
+
if (editorRef.current.contains(range.commonAncestorContainer)) {
|
|
3611
|
+
range.deleteContents();
|
|
3612
|
+
range.insertNode(img);
|
|
3613
|
+
const br = document.createElement("br");
|
|
3614
|
+
range.setStartAfter(img);
|
|
3615
|
+
range.insertNode(br);
|
|
3616
|
+
range.setStartAfter(br);
|
|
3617
|
+
range.collapse(true);
|
|
3618
|
+
selection.removeAllRanges();
|
|
3619
|
+
selection.addRange(range);
|
|
3620
|
+
} else {
|
|
3621
|
+
editorRef.current.appendChild(img);
|
|
3622
|
+
editorRef.current.appendChild(document.createElement("br"));
|
|
3623
|
+
}
|
|
3624
|
+
} else {
|
|
3625
|
+
editorRef.current.appendChild(img);
|
|
3626
|
+
editorRef.current.appendChild(document.createElement("br"));
|
|
3627
|
+
}
|
|
3491
3628
|
}
|
|
3492
3629
|
setShowImageModal(false);
|
|
3493
3630
|
setImageUrl("");
|
|
3494
3631
|
setImageAlt("");
|
|
3495
|
-
editorRef.current?.focus();
|
|
3496
3632
|
handleInput();
|
|
3497
|
-
}, [imageUrl, imageAlt, handleInput
|
|
3633
|
+
}, [imageUrl, imageAlt, handleInput]);
|
|
3498
3634
|
const getButtonClass = (isActive) => {
|
|
3499
3635
|
const baseClass = themeName === "minimalistic" ? "border border-white text-white transition-colors" : "border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 transition-colors";
|
|
3500
3636
|
const activeClass = themeName === "minimalistic" ? "bg-white text-black" : "bg-blue-100 dark:bg-blue-900 border-blue-500 dark:border-blue-400";
|
|
@@ -3658,11 +3794,10 @@ var RichTextEditor = ({
|
|
|
3658
3794
|
ref: editorRef,
|
|
3659
3795
|
contentEditable: !disabled,
|
|
3660
3796
|
onInput: handleInput,
|
|
3661
|
-
onFocus:
|
|
3797
|
+
onFocus: handleFocus,
|
|
3662
3798
|
onBlur: () => setIsFocused(false),
|
|
3663
3799
|
onMouseUp: updateActiveFormats,
|
|
3664
3800
|
onKeyUp: updateActiveFormats,
|
|
3665
|
-
dangerouslySetInnerHTML: { __html: value },
|
|
3666
3801
|
className: `
|
|
3667
3802
|
w-full px-4 py-3 rounded-b-lg outline-none overflow-y-auto
|
|
3668
3803
|
${editorBaseClass} ${focusClass} ${errorClass}
|
|
@@ -5151,8 +5286,10 @@ var defaultColors = [
|
|
|
5151
5286
|
];
|
|
5152
5287
|
var LineChart = ({
|
|
5153
5288
|
data,
|
|
5154
|
-
width
|
|
5155
|
-
height
|
|
5289
|
+
width: providedWidth,
|
|
5290
|
+
height: providedHeight,
|
|
5291
|
+
aspectRatio = 16 / 9,
|
|
5292
|
+
responsive = true,
|
|
5156
5293
|
showGrid = true,
|
|
5157
5294
|
showXAxis = true,
|
|
5158
5295
|
showYAxis = true,
|
|
@@ -5165,6 +5302,8 @@ var LineChart = ({
|
|
|
5165
5302
|
xAxisLabel,
|
|
5166
5303
|
yAxisLabel
|
|
5167
5304
|
}) => {
|
|
5305
|
+
const height = providedHeight ?? 400;
|
|
5306
|
+
const width = providedWidth ?? (responsive ? 600 : 600);
|
|
5168
5307
|
const [hoveredPoint, setHoveredPoint] = import_react26.default.useState(null);
|
|
5169
5308
|
const padding = { top: 20, right: 20, bottom: showXAxis ? 60 : 20, left: showYAxis ? 60 : 20 };
|
|
5170
5309
|
const chartWidth = width - padding.left - padding.right;
|
|
@@ -5239,7 +5378,8 @@ var LineChart = ({
|
|
|
5239
5378
|
x: -10,
|
|
5240
5379
|
y: y + 4,
|
|
5241
5380
|
textAnchor: "end",
|
|
5242
|
-
|
|
5381
|
+
fontSize: "16",
|
|
5382
|
+
className: "fill-gray-600 dark:fill-gray-400",
|
|
5243
5383
|
children: yValue.toFixed(1)
|
|
5244
5384
|
}
|
|
5245
5385
|
)
|
|
@@ -5271,7 +5411,8 @@ var LineChart = ({
|
|
|
5271
5411
|
x,
|
|
5272
5412
|
y: chartHeight + 20,
|
|
5273
5413
|
textAnchor: "middle",
|
|
5274
|
-
|
|
5414
|
+
fontSize: "14",
|
|
5415
|
+
className: "fill-gray-600 dark:fill-gray-400",
|
|
5275
5416
|
children: xValue
|
|
5276
5417
|
}
|
|
5277
5418
|
)
|
|
@@ -5279,108 +5420,121 @@ var LineChart = ({
|
|
|
5279
5420
|
);
|
|
5280
5421
|
}
|
|
5281
5422
|
}
|
|
5282
|
-
return /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)(
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
{
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
},
|
|
5302
|
-
`line-${seriesIndex}`
|
|
5303
|
-
)),
|
|
5304
|
-
showDots && data.map(
|
|
5305
|
-
(series, seriesIndex) => series.data.map((point, pointIndex) => {
|
|
5306
|
-
const x = scaleX(point.x, pointIndex);
|
|
5307
|
-
const y = scaleY(point.y);
|
|
5308
|
-
const isHovered = hoveredPoint?.seriesIndex === seriesIndex && hoveredPoint?.pointIndex === pointIndex;
|
|
5309
|
-
return /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5310
|
-
"circle",
|
|
5423
|
+
return /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)(
|
|
5424
|
+
"div",
|
|
5425
|
+
{
|
|
5426
|
+
className: `relative ${responsive ? "w-full" : "inline-block"} ${className}`,
|
|
5427
|
+
style: responsive ? { aspectRatio: `${width} / ${height}` } : void 0,
|
|
5428
|
+
children: [
|
|
5429
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5430
|
+
"svg",
|
|
5431
|
+
{
|
|
5432
|
+
width: "100%",
|
|
5433
|
+
height: "100%",
|
|
5434
|
+
viewBox: `0 0 ${width} ${height}`,
|
|
5435
|
+
preserveAspectRatio: "xMidYMid meet",
|
|
5436
|
+
className: "bg-white dark:bg-gray-800 block",
|
|
5437
|
+
style: { overflow: "visible" },
|
|
5438
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("g", { transform: `translate(${padding.left}, ${padding.top})`, children: [
|
|
5439
|
+
gridLines,
|
|
5440
|
+
data.map((series, seriesIndex) => /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5441
|
+
"path",
|
|
5311
5442
|
{
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
className: "cursor-pointer transition-all",
|
|
5319
|
-
onMouseEnter: () => showTooltip && setHoveredPoint({ seriesIndex, pointIndex, x, y }),
|
|
5320
|
-
onMouseLeave: () => setHoveredPoint(null)
|
|
5443
|
+
d: generatePath(series),
|
|
5444
|
+
fill: "none",
|
|
5445
|
+
stroke: series.color || defaultColors[seriesIndex % defaultColors.length],
|
|
5446
|
+
strokeWidth,
|
|
5447
|
+
strokeLinecap: "round",
|
|
5448
|
+
strokeLinejoin: "round"
|
|
5321
5449
|
},
|
|
5322
|
-
`
|
|
5323
|
-
)
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5450
|
+
`line-${seriesIndex}`
|
|
5451
|
+
)),
|
|
5452
|
+
showDots && data.map(
|
|
5453
|
+
(series, seriesIndex) => series.data.map((point, pointIndex) => {
|
|
5454
|
+
const x = scaleX(point.x, pointIndex);
|
|
5455
|
+
const y = scaleY(point.y);
|
|
5456
|
+
const isHovered = hoveredPoint?.seriesIndex === seriesIndex && hoveredPoint?.pointIndex === pointIndex;
|
|
5457
|
+
return /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5458
|
+
"circle",
|
|
5459
|
+
{
|
|
5460
|
+
cx: x,
|
|
5461
|
+
cy: y,
|
|
5462
|
+
r: isHovered ? 6 : 4,
|
|
5463
|
+
fill: series.color || defaultColors[seriesIndex % defaultColors.length],
|
|
5464
|
+
stroke: "white",
|
|
5465
|
+
strokeWidth: "2",
|
|
5466
|
+
className: "cursor-pointer transition-all",
|
|
5467
|
+
onMouseEnter: () => showTooltip && setHoveredPoint({ seriesIndex, pointIndex, x, y }),
|
|
5468
|
+
onMouseLeave: () => setHoveredPoint(null)
|
|
5469
|
+
},
|
|
5470
|
+
`point-${seriesIndex}-${pointIndex}`
|
|
5471
|
+
);
|
|
5472
|
+
})
|
|
5473
|
+
),
|
|
5474
|
+
xAxisLabel && showXAxis && /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5475
|
+
"text",
|
|
5476
|
+
{
|
|
5477
|
+
x: chartWidth / 2,
|
|
5478
|
+
y: chartHeight + 50,
|
|
5479
|
+
textAnchor: "middle",
|
|
5480
|
+
fontSize: "16",
|
|
5481
|
+
fontWeight: "500",
|
|
5482
|
+
className: "fill-gray-700 dark:fill-gray-300",
|
|
5483
|
+
children: xAxisLabel
|
|
5484
|
+
}
|
|
5485
|
+
),
|
|
5486
|
+
yAxisLabel && showYAxis && /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5487
|
+
"text",
|
|
5488
|
+
{
|
|
5489
|
+
x: -chartHeight / 2,
|
|
5490
|
+
y: -45,
|
|
5491
|
+
textAnchor: "middle",
|
|
5492
|
+
fontSize: "16",
|
|
5493
|
+
fontWeight: "500",
|
|
5494
|
+
transform: `rotate(-90, 0, 0)`,
|
|
5495
|
+
className: "fill-gray-700 dark:fill-gray-300",
|
|
5496
|
+
children: yAxisLabel
|
|
5497
|
+
}
|
|
5498
|
+
)
|
|
5499
|
+
] })
|
|
5500
|
+
}
|
|
5501
|
+
),
|
|
5502
|
+
showLegend && /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "flex flex-wrap gap-4 mt-4 justify-center", children: data.map((series, index) => /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5503
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5504
|
+
"div",
|
|
5328
5505
|
{
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
children: xAxisLabel
|
|
5506
|
+
className: "w-4 h-4 rounded-sm",
|
|
5507
|
+
style: {
|
|
5508
|
+
backgroundColor: series.color || defaultColors[index % defaultColors.length]
|
|
5509
|
+
}
|
|
5334
5510
|
}
|
|
5335
5511
|
),
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
}
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5512
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: series.name })
|
|
5513
|
+
] }, `legend-${index}`)) }),
|
|
5514
|
+
showTooltip && hoveredPoint && /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)(
|
|
5515
|
+
"div",
|
|
5516
|
+
{
|
|
5517
|
+
className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg text-sm pointer-events-none z-50",
|
|
5518
|
+
style: {
|
|
5519
|
+
left: `${padding.left + hoveredPoint.x + 10}px`,
|
|
5520
|
+
top: `${padding.top + hoveredPoint.y - 30}px`
|
|
5521
|
+
},
|
|
5522
|
+
children: [
|
|
5523
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "font-semibold", children: data[hoveredPoint.seriesIndex].name }),
|
|
5524
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { children: [
|
|
5525
|
+
"x: ",
|
|
5526
|
+
data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].x
|
|
5527
|
+
] }),
|
|
5528
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { children: [
|
|
5529
|
+
"y: ",
|
|
5530
|
+
data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].y
|
|
5531
|
+
] })
|
|
5532
|
+
]
|
|
5357
5533
|
}
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
showTooltip && hoveredPoint && /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)(
|
|
5363
|
-
"div",
|
|
5364
|
-
{
|
|
5365
|
-
className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg text-sm pointer-events-none z-50",
|
|
5366
|
-
style: {
|
|
5367
|
-
left: `${padding.left + hoveredPoint.x + 10}px`,
|
|
5368
|
-
top: `${padding.top + hoveredPoint.y - 30}px`
|
|
5369
|
-
},
|
|
5370
|
-
children: [
|
|
5371
|
-
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "font-semibold", children: data[hoveredPoint.seriesIndex].name }),
|
|
5372
|
-
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { children: [
|
|
5373
|
-
"x: ",
|
|
5374
|
-
data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].x
|
|
5375
|
-
] }),
|
|
5376
|
-
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { children: [
|
|
5377
|
-
"y: ",
|
|
5378
|
-
data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].y
|
|
5379
|
-
] })
|
|
5380
|
-
]
|
|
5381
|
-
}
|
|
5382
|
-
)
|
|
5383
|
-
] });
|
|
5534
|
+
)
|
|
5535
|
+
]
|
|
5536
|
+
}
|
|
5537
|
+
);
|
|
5384
5538
|
};
|
|
5385
5539
|
|
|
5386
5540
|
// src/components/BarChart.tsx
|
|
@@ -5402,8 +5556,10 @@ var defaultColors2 = [
|
|
|
5402
5556
|
];
|
|
5403
5557
|
var BarChart = ({
|
|
5404
5558
|
data,
|
|
5405
|
-
width
|
|
5406
|
-
height
|
|
5559
|
+
width: providedWidth,
|
|
5560
|
+
height: providedHeight,
|
|
5561
|
+
aspectRatio = 16 / 9,
|
|
5562
|
+
responsive = true,
|
|
5407
5563
|
showGrid = true,
|
|
5408
5564
|
showXAxis = true,
|
|
5409
5565
|
showYAxis = true,
|
|
@@ -5417,6 +5573,8 @@ var BarChart = ({
|
|
|
5417
5573
|
xAxisLabel,
|
|
5418
5574
|
yAxisLabel
|
|
5419
5575
|
}) => {
|
|
5576
|
+
const height = providedHeight ?? 400;
|
|
5577
|
+
const width = providedWidth ?? (responsive ? 800 : 600);
|
|
5420
5578
|
const [hoveredBar, setHoveredBar] = import_react27.default.useState(null);
|
|
5421
5579
|
const padding = {
|
|
5422
5580
|
top: 20,
|
|
@@ -5470,7 +5628,8 @@ var BarChart = ({
|
|
|
5470
5628
|
x: -10,
|
|
5471
5629
|
y: y + 4,
|
|
5472
5630
|
textAnchor: "end",
|
|
5473
|
-
|
|
5631
|
+
fontSize: "14",
|
|
5632
|
+
className: "fill-gray-600 dark:fill-gray-400",
|
|
5474
5633
|
children: yValue.toFixed(0)
|
|
5475
5634
|
}
|
|
5476
5635
|
)
|
|
@@ -5566,7 +5725,9 @@ var BarChart = ({
|
|
|
5566
5725
|
x: xPos + actualBarWidth / 2,
|
|
5567
5726
|
y: yPos - 5,
|
|
5568
5727
|
textAnchor: "middle",
|
|
5569
|
-
|
|
5728
|
+
fontSize: "14",
|
|
5729
|
+
fontWeight: "500",
|
|
5730
|
+
className: "fill-gray-700 dark:fill-gray-300",
|
|
5570
5731
|
children: point.y
|
|
5571
5732
|
},
|
|
5572
5733
|
`value-${seriesIndex}-${barIndex}`
|
|
@@ -5586,79 +5747,93 @@ var BarChart = ({
|
|
|
5586
5747
|
x: xPos,
|
|
5587
5748
|
y: chartHeight + 20,
|
|
5588
5749
|
textAnchor: "middle",
|
|
5589
|
-
|
|
5750
|
+
fontSize: "14",
|
|
5751
|
+
className: "fill-gray-600 dark:fill-gray-400",
|
|
5590
5752
|
children: point.x
|
|
5591
5753
|
},
|
|
5592
5754
|
`x-label-${i}`
|
|
5593
5755
|
);
|
|
5594
5756
|
});
|
|
5595
|
-
return /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)(
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
{
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
"
|
|
5757
|
+
return /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)(
|
|
5758
|
+
"div",
|
|
5759
|
+
{
|
|
5760
|
+
className: `relative ${responsive ? "w-full" : "inline-block"} ${className}`,
|
|
5761
|
+
style: responsive ? { aspectRatio: `${width} / ${height}` } : void 0,
|
|
5762
|
+
children: [
|
|
5763
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
|
|
5764
|
+
"svg",
|
|
5765
|
+
{
|
|
5766
|
+
width: "100%",
|
|
5767
|
+
height: "100%",
|
|
5768
|
+
viewBox: `0 0 ${width} ${height}`,
|
|
5769
|
+
preserveAspectRatio: "xMidYMid meet",
|
|
5770
|
+
className: "bg-white dark:bg-gray-800 block",
|
|
5771
|
+
style: { overflow: "visible" },
|
|
5772
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("g", { transform: `translate(${padding.left}, ${padding.top})`, children: [
|
|
5773
|
+
gridLines,
|
|
5774
|
+
renderBars(),
|
|
5775
|
+
showXAxis && xAxisLabels,
|
|
5776
|
+
xAxisLabel && showXAxis && /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
|
|
5777
|
+
"text",
|
|
5778
|
+
{
|
|
5779
|
+
x: chartWidth / 2,
|
|
5780
|
+
y: chartHeight + 50,
|
|
5781
|
+
textAnchor: "middle",
|
|
5782
|
+
fontSize: "16",
|
|
5783
|
+
fontWeight: "500",
|
|
5784
|
+
className: "fill-gray-700 dark:fill-gray-300",
|
|
5785
|
+
children: xAxisLabel
|
|
5786
|
+
}
|
|
5787
|
+
),
|
|
5788
|
+
yAxisLabel && showYAxis && /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
|
|
5789
|
+
"text",
|
|
5790
|
+
{
|
|
5791
|
+
x: -chartHeight / 2,
|
|
5792
|
+
y: -45,
|
|
5793
|
+
textAnchor: "middle",
|
|
5794
|
+
fontSize: "16",
|
|
5795
|
+
fontWeight: "500",
|
|
5796
|
+
transform: `rotate(-90, 0, 0)`,
|
|
5797
|
+
className: "fill-gray-700 dark:fill-gray-300",
|
|
5798
|
+
children: yAxisLabel
|
|
5799
|
+
}
|
|
5800
|
+
)
|
|
5801
|
+
] })
|
|
5802
|
+
}
|
|
5803
|
+
),
|
|
5804
|
+
showLegend && /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("div", { className: "flex flex-wrap gap-4 mt-4 justify-center", children: data.map((series, index) => /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5805
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
|
|
5806
|
+
"div",
|
|
5609
5807
|
{
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
children: xAxisLabel
|
|
5808
|
+
className: "w-4 h-4 rounded-sm",
|
|
5809
|
+
style: {
|
|
5810
|
+
backgroundColor: series.color || defaultColors2[index % defaultColors2.length]
|
|
5811
|
+
}
|
|
5615
5812
|
}
|
|
5616
5813
|
),
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
}
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
className: "w-4 h-4 rounded-sm",
|
|
5636
|
-
style: {
|
|
5637
|
-
backgroundColor: series.color || defaultColors2[index % defaultColors2.length]
|
|
5814
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsx)("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: series.name })
|
|
5815
|
+
] }, `legend-${index}`)) }),
|
|
5816
|
+
showTooltip && hoveredBar && /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)(
|
|
5817
|
+
"div",
|
|
5818
|
+
{
|
|
5819
|
+
className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg text-sm pointer-events-none z-50",
|
|
5820
|
+
style: {
|
|
5821
|
+
left: `${padding.left + hoveredBar.x + 10}px`,
|
|
5822
|
+
top: `${padding.top + hoveredBar.y - 30}px`
|
|
5823
|
+
},
|
|
5824
|
+
children: [
|
|
5825
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsx)("div", { className: "font-semibold", children: data[hoveredBar.seriesIndex].name }),
|
|
5826
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("div", { children: [
|
|
5827
|
+
data[hoveredBar.seriesIndex].data[hoveredBar.barIndex].x,
|
|
5828
|
+
": ",
|
|
5829
|
+
data[hoveredBar.seriesIndex].data[hoveredBar.barIndex].y
|
|
5830
|
+
] })
|
|
5831
|
+
]
|
|
5638
5832
|
}
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
showTooltip && hoveredBar && /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)(
|
|
5644
|
-
"div",
|
|
5645
|
-
{
|
|
5646
|
-
className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg text-sm pointer-events-none z-50",
|
|
5647
|
-
style: {
|
|
5648
|
-
left: `${padding.left + hoveredBar.x + 10}px`,
|
|
5649
|
-
top: `${padding.top + hoveredBar.y - 30}px`
|
|
5650
|
-
},
|
|
5651
|
-
children: [
|
|
5652
|
-
/* @__PURE__ */ (0, import_jsx_runtime109.jsx)("div", { className: "font-semibold", children: data[hoveredBar.seriesIndex].name }),
|
|
5653
|
-
/* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("div", { children: [
|
|
5654
|
-
data[hoveredBar.seriesIndex].data[hoveredBar.barIndex].x,
|
|
5655
|
-
": ",
|
|
5656
|
-
data[hoveredBar.seriesIndex].data[hoveredBar.barIndex].y
|
|
5657
|
-
] })
|
|
5658
|
-
]
|
|
5659
|
-
}
|
|
5660
|
-
)
|
|
5661
|
-
] });
|
|
5833
|
+
)
|
|
5834
|
+
]
|
|
5835
|
+
}
|
|
5836
|
+
);
|
|
5662
5837
|
};
|
|
5663
5838
|
|
|
5664
5839
|
// src/components/AreaChart.tsx
|
|
@@ -5680,8 +5855,10 @@ var defaultColors3 = [
|
|
|
5680
5855
|
];
|
|
5681
5856
|
var AreaChart = ({
|
|
5682
5857
|
data,
|
|
5683
|
-
width
|
|
5684
|
-
height
|
|
5858
|
+
width: providedWidth,
|
|
5859
|
+
height: providedHeight,
|
|
5860
|
+
aspectRatio = 16 / 9,
|
|
5861
|
+
responsive = true,
|
|
5685
5862
|
showGrid = true,
|
|
5686
5863
|
showXAxis = true,
|
|
5687
5864
|
showYAxis = true,
|
|
@@ -5696,6 +5873,8 @@ var AreaChart = ({
|
|
|
5696
5873
|
xAxisLabel,
|
|
5697
5874
|
yAxisLabel
|
|
5698
5875
|
}) => {
|
|
5876
|
+
const height = providedHeight ?? 400;
|
|
5877
|
+
const width = providedWidth ?? 800;
|
|
5699
5878
|
const [hoveredPoint, setHoveredPoint] = import_react28.default.useState(null);
|
|
5700
5879
|
const padding = { top: 20, right: 20, bottom: showXAxis ? 60 : 20, left: showYAxis ? 60 : 20 };
|
|
5701
5880
|
const chartWidth = width - padding.left - padding.right;
|
|
@@ -5805,7 +5984,8 @@ var AreaChart = ({
|
|
|
5805
5984
|
x: -10,
|
|
5806
5985
|
y: y + 4,
|
|
5807
5986
|
textAnchor: "end",
|
|
5808
|
-
|
|
5987
|
+
fontSize: "12",
|
|
5988
|
+
className: "fill-gray-600 dark:fill-gray-400",
|
|
5809
5989
|
children: yValue.toFixed(0)
|
|
5810
5990
|
}
|
|
5811
5991
|
)
|
|
@@ -5837,7 +6017,8 @@ var AreaChart = ({
|
|
|
5837
6017
|
x,
|
|
5838
6018
|
y: chartHeight + 20,
|
|
5839
6019
|
textAnchor: "middle",
|
|
5840
|
-
|
|
6020
|
+
fontSize: "12",
|
|
6021
|
+
className: "fill-gray-600 dark:fill-gray-400",
|
|
5841
6022
|
children: xValue
|
|
5842
6023
|
}
|
|
5843
6024
|
)
|
|
@@ -5849,130 +6030,142 @@ var AreaChart = ({
|
|
|
5849
6030
|
if (stacked) {
|
|
5850
6031
|
cumulativeValues = Array(data[0]?.data.length || 0).fill(0);
|
|
5851
6032
|
}
|
|
5852
|
-
return /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)(
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
{
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
6033
|
+
return /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)(
|
|
6034
|
+
"div",
|
|
6035
|
+
{
|
|
6036
|
+
className: `relative ${responsive ? "w-full" : "inline-block"} ${className}`,
|
|
6037
|
+
style: responsive ? { width: "100%", aspectRatio: `${width} / ${height}` } : void 0,
|
|
6038
|
+
children: [
|
|
6039
|
+
/* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
6040
|
+
"svg",
|
|
6041
|
+
{
|
|
6042
|
+
width: "100%",
|
|
6043
|
+
height: "100%",
|
|
6044
|
+
viewBox: `0 0 ${width} ${height}`,
|
|
6045
|
+
preserveAspectRatio: "xMidYMid meet",
|
|
6046
|
+
className: "bg-white dark:bg-gray-800 block",
|
|
6047
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)("g", { transform: `translate(${padding.left}, ${padding.top})`, children: [
|
|
6048
|
+
gridLines,
|
|
6049
|
+
data.map((series, seriesIndex) => {
|
|
6050
|
+
const baselineYValues = stacked ? [...cumulativeValues] : void 0;
|
|
6051
|
+
const areaPath = generateAreaPath(series, baselineYValues);
|
|
6052
|
+
const linePath = generateLinePath(series, baselineYValues);
|
|
6053
|
+
if (stacked) {
|
|
6054
|
+
series.data.forEach((point, i) => {
|
|
6055
|
+
cumulativeValues[i] += point.y;
|
|
6056
|
+
});
|
|
6057
|
+
}
|
|
6058
|
+
return /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)("g", { children: [
|
|
6059
|
+
/* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
6060
|
+
"path",
|
|
6061
|
+
{
|
|
6062
|
+
d: areaPath,
|
|
6063
|
+
fill: series.color || defaultColors3[seriesIndex % defaultColors3.length],
|
|
6064
|
+
opacity: fillOpacity
|
|
6065
|
+
}
|
|
6066
|
+
),
|
|
6067
|
+
/* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
6068
|
+
"path",
|
|
6069
|
+
{
|
|
6070
|
+
d: linePath,
|
|
6071
|
+
fill: "none",
|
|
6072
|
+
stroke: series.color || defaultColors3[seriesIndex % defaultColors3.length],
|
|
6073
|
+
strokeWidth,
|
|
6074
|
+
strokeLinecap: "round",
|
|
6075
|
+
strokeLinejoin: "round"
|
|
6076
|
+
}
|
|
6077
|
+
)
|
|
6078
|
+
] }, `area-${seriesIndex}`);
|
|
6079
|
+
}),
|
|
6080
|
+
showDots && data.map((series, seriesIndex) => {
|
|
6081
|
+
const baselineYValues = stacked ? data.slice(0, seriesIndex).reduce((acc, s) => {
|
|
6082
|
+
return acc.map((val, i) => val + (s.data[i]?.y || 0));
|
|
6083
|
+
}, Array(series.data.length).fill(0)) : void 0;
|
|
6084
|
+
return series.data.map((point, pointIndex) => {
|
|
6085
|
+
const x = scaleX(point.x, pointIndex);
|
|
6086
|
+
const y = baselineYValues ? scaleY(baselineYValues[pointIndex] + point.y) : scaleY(point.y);
|
|
6087
|
+
const isHovered = hoveredPoint?.seriesIndex === seriesIndex && hoveredPoint?.pointIndex === pointIndex;
|
|
6088
|
+
return /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
6089
|
+
"circle",
|
|
6090
|
+
{
|
|
6091
|
+
cx: x,
|
|
6092
|
+
cy: y,
|
|
6093
|
+
r: isHovered ? 6 : 4,
|
|
6094
|
+
fill: series.color || defaultColors3[seriesIndex % defaultColors3.length],
|
|
6095
|
+
stroke: "white",
|
|
6096
|
+
strokeWidth: "2",
|
|
6097
|
+
className: "cursor-pointer transition-all",
|
|
6098
|
+
onMouseEnter: () => showTooltip && setHoveredPoint({ seriesIndex, pointIndex, x, y }),
|
|
6099
|
+
onMouseLeave: () => setHoveredPoint(null)
|
|
6100
|
+
},
|
|
6101
|
+
`point-${seriesIndex}-${pointIndex}`
|
|
6102
|
+
);
|
|
6103
|
+
});
|
|
6104
|
+
}),
|
|
6105
|
+
xAxisLabel && showXAxis && /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
6106
|
+
"text",
|
|
5874
6107
|
{
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
6108
|
+
x: chartWidth / 2,
|
|
6109
|
+
y: chartHeight + 50,
|
|
6110
|
+
textAnchor: "middle",
|
|
6111
|
+
fontSize: "14",
|
|
6112
|
+
fontWeight: "500",
|
|
6113
|
+
className: "fill-gray-700 dark:fill-gray-300",
|
|
6114
|
+
children: xAxisLabel
|
|
5878
6115
|
}
|
|
5879
6116
|
),
|
|
5880
|
-
/* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
5881
|
-
"
|
|
6117
|
+
yAxisLabel && showYAxis && /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
6118
|
+
"text",
|
|
5882
6119
|
{
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
6120
|
+
x: -chartHeight / 2,
|
|
6121
|
+
y: -45,
|
|
6122
|
+
textAnchor: "middle",
|
|
6123
|
+
fontSize: "14",
|
|
6124
|
+
fontWeight: "500",
|
|
6125
|
+
transform: "rotate(-90, 0, 0)",
|
|
6126
|
+
className: "fill-gray-700 dark:fill-gray-300",
|
|
6127
|
+
children: yAxisLabel
|
|
5889
6128
|
}
|
|
5890
6129
|
)
|
|
5891
|
-
] }
|
|
5892
|
-
}
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
return series.data.map((point, pointIndex) => {
|
|
5898
|
-
const x = scaleX(point.x, pointIndex);
|
|
5899
|
-
const y = baselineYValues ? scaleY(baselineYValues[pointIndex] + point.y) : scaleY(point.y);
|
|
5900
|
-
const isHovered = hoveredPoint?.seriesIndex === seriesIndex && hoveredPoint?.pointIndex === pointIndex;
|
|
5901
|
-
return /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
5902
|
-
"circle",
|
|
5903
|
-
{
|
|
5904
|
-
cx: x,
|
|
5905
|
-
cy: y,
|
|
5906
|
-
r: isHovered ? 6 : 4,
|
|
5907
|
-
fill: series.color || defaultColors3[seriesIndex % defaultColors3.length],
|
|
5908
|
-
stroke: "white",
|
|
5909
|
-
strokeWidth: "2",
|
|
5910
|
-
className: "cursor-pointer transition-all",
|
|
5911
|
-
onMouseEnter: () => showTooltip && setHoveredPoint({ seriesIndex, pointIndex, x, y }),
|
|
5912
|
-
onMouseLeave: () => setHoveredPoint(null)
|
|
5913
|
-
},
|
|
5914
|
-
`point-${seriesIndex}-${pointIndex}`
|
|
5915
|
-
);
|
|
5916
|
-
});
|
|
5917
|
-
}),
|
|
5918
|
-
xAxisLabel && showXAxis && /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
5919
|
-
"text",
|
|
6130
|
+
] })
|
|
6131
|
+
}
|
|
6132
|
+
),
|
|
6133
|
+
showLegend && /* @__PURE__ */ (0, import_jsx_runtime110.jsx)("div", { className: "flex flex-wrap gap-4 mt-4 justify-center", children: data.map((series, index) => /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
6134
|
+
/* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
6135
|
+
"div",
|
|
5920
6136
|
{
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
children: xAxisLabel
|
|
6137
|
+
className: "w-4 h-4 rounded-sm",
|
|
6138
|
+
style: {
|
|
6139
|
+
backgroundColor: series.color || defaultColors3[index % defaultColors3.length]
|
|
6140
|
+
}
|
|
5926
6141
|
}
|
|
5927
6142
|
),
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
}
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
6143
|
+
/* @__PURE__ */ (0, import_jsx_runtime110.jsx)("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: series.name })
|
|
6144
|
+
] }, `legend-${index}`)) }),
|
|
6145
|
+
showTooltip && hoveredPoint && /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)(
|
|
6146
|
+
"div",
|
|
6147
|
+
{
|
|
6148
|
+
className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg text-sm pointer-events-none z-50",
|
|
6149
|
+
style: {
|
|
6150
|
+
left: `${padding.left + hoveredPoint.x + 10}px`,
|
|
6151
|
+
top: `${padding.top + hoveredPoint.y - 30}px`
|
|
6152
|
+
},
|
|
6153
|
+
children: [
|
|
6154
|
+
/* @__PURE__ */ (0, import_jsx_runtime110.jsx)("div", { className: "font-semibold", children: data[hoveredPoint.seriesIndex].name }),
|
|
6155
|
+
/* @__PURE__ */ (0, import_jsx_runtime110.jsxs)("div", { children: [
|
|
6156
|
+
"x: ",
|
|
6157
|
+
data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].x
|
|
6158
|
+
] }),
|
|
6159
|
+
/* @__PURE__ */ (0, import_jsx_runtime110.jsxs)("div", { children: [
|
|
6160
|
+
"y: ",
|
|
6161
|
+
data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].y
|
|
6162
|
+
] })
|
|
6163
|
+
]
|
|
5949
6164
|
}
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
showTooltip && hoveredPoint && /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)(
|
|
5955
|
-
"div",
|
|
5956
|
-
{
|
|
5957
|
-
className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg text-sm pointer-events-none z-50",
|
|
5958
|
-
style: {
|
|
5959
|
-
left: `${padding.left + hoveredPoint.x + 10}px`,
|
|
5960
|
-
top: `${padding.top + hoveredPoint.y - 30}px`
|
|
5961
|
-
},
|
|
5962
|
-
children: [
|
|
5963
|
-
/* @__PURE__ */ (0, import_jsx_runtime110.jsx)("div", { className: "font-semibold", children: data[hoveredPoint.seriesIndex].name }),
|
|
5964
|
-
/* @__PURE__ */ (0, import_jsx_runtime110.jsxs)("div", { children: [
|
|
5965
|
-
"x: ",
|
|
5966
|
-
data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].x
|
|
5967
|
-
] }),
|
|
5968
|
-
/* @__PURE__ */ (0, import_jsx_runtime110.jsxs)("div", { children: [
|
|
5969
|
-
"y: ",
|
|
5970
|
-
data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].y
|
|
5971
|
-
] })
|
|
5972
|
-
]
|
|
5973
|
-
}
|
|
5974
|
-
)
|
|
5975
|
-
] });
|
|
6165
|
+
)
|
|
6166
|
+
]
|
|
6167
|
+
}
|
|
6168
|
+
);
|
|
5976
6169
|
};
|
|
5977
6170
|
|
|
5978
6171
|
// src/components/PieChart.tsx
|
|
@@ -5998,8 +6191,10 @@ var defaultColors4 = [
|
|
|
5998
6191
|
];
|
|
5999
6192
|
var PieChart = ({
|
|
6000
6193
|
data,
|
|
6001
|
-
width
|
|
6002
|
-
height
|
|
6194
|
+
width: providedWidth,
|
|
6195
|
+
height: providedHeight,
|
|
6196
|
+
aspectRatio = 1,
|
|
6197
|
+
responsive = true,
|
|
6003
6198
|
showLegend = true,
|
|
6004
6199
|
showLabels = true,
|
|
6005
6200
|
showValues = false,
|
|
@@ -6008,6 +6203,8 @@ var PieChart = ({
|
|
|
6008
6203
|
donutWidth = 60,
|
|
6009
6204
|
className = ""
|
|
6010
6205
|
}) => {
|
|
6206
|
+
const height = providedHeight ?? 400;
|
|
6207
|
+
const width = providedWidth ?? 400;
|
|
6011
6208
|
const [hoveredSlice, setHoveredSlice] = import_react29.default.useState(null);
|
|
6012
6209
|
const total = data.reduce((sum, item) => sum + item.value, 0);
|
|
6013
6210
|
const centerX = width / 2;
|
|
@@ -6065,112 +6262,126 @@ var PieChart = ({
|
|
|
6065
6262
|
index
|
|
6066
6263
|
};
|
|
6067
6264
|
});
|
|
6068
|
-
return /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)(
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
{
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6265
|
+
return /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)(
|
|
6266
|
+
"div",
|
|
6267
|
+
{
|
|
6268
|
+
className: `relative ${responsive ? "w-full flex justify-center" : "inline-block"} ${className}`,
|
|
6269
|
+
style: responsive ? { aspectRatio: `${width} / ${height}` } : void 0,
|
|
6270
|
+
children: [
|
|
6271
|
+
/* @__PURE__ */ (0, import_jsx_runtime111.jsxs)(
|
|
6272
|
+
"svg",
|
|
6273
|
+
{
|
|
6274
|
+
width: "100%",
|
|
6275
|
+
height: "100%",
|
|
6276
|
+
viewBox: `0 0 ${width} ${height}`,
|
|
6277
|
+
preserveAspectRatio: "xMidYMid meet",
|
|
6278
|
+
className: "bg-white dark:bg-gray-800 block",
|
|
6279
|
+
children: [
|
|
6280
|
+
slices.map((slice) => {
|
|
6281
|
+
const isHovered = hoveredSlice === slice.index;
|
|
6282
|
+
return /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("g", { children: [
|
|
6283
|
+
/* @__PURE__ */ (0, import_jsx_runtime111.jsx)(
|
|
6284
|
+
"path",
|
|
6285
|
+
{
|
|
6286
|
+
d: slice.path,
|
|
6287
|
+
fill: slice.color,
|
|
6288
|
+
stroke: "white",
|
|
6289
|
+
strokeWidth: "2",
|
|
6290
|
+
className: "cursor-pointer transition-opacity",
|
|
6291
|
+
opacity: isHovered ? 0.8 : 1,
|
|
6292
|
+
onMouseEnter: () => setHoveredSlice(slice.index),
|
|
6293
|
+
onMouseLeave: () => setHoveredSlice(null)
|
|
6294
|
+
}
|
|
6295
|
+
),
|
|
6296
|
+
showLabels && slice.percentage > 5 && /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)(
|
|
6297
|
+
"text",
|
|
6298
|
+
{
|
|
6299
|
+
x: slice.labelX,
|
|
6300
|
+
y: slice.labelY,
|
|
6301
|
+
textAnchor: "middle",
|
|
6302
|
+
dominantBaseline: "middle",
|
|
6303
|
+
fontSize: "14",
|
|
6304
|
+
fontWeight: "600",
|
|
6305
|
+
className: "fill-gray-700 dark:fill-gray-200 pointer-events-none",
|
|
6306
|
+
children: [
|
|
6307
|
+
showPercentages && `${slice.percentage.toFixed(1)}%`,
|
|
6308
|
+
showPercentages && showValues && " ",
|
|
6309
|
+
showValues && `(${slice.value})`,
|
|
6310
|
+
!showPercentages && !showValues && slice.label
|
|
6311
|
+
]
|
|
6312
|
+
}
|
|
6313
|
+
)
|
|
6314
|
+
] }, slice.index);
|
|
6315
|
+
}),
|
|
6316
|
+
donut && /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("g", { children: [
|
|
6317
|
+
/* @__PURE__ */ (0, import_jsx_runtime111.jsx)(
|
|
6318
|
+
"text",
|
|
6319
|
+
{
|
|
6320
|
+
x: centerX,
|
|
6321
|
+
y: centerY - 10,
|
|
6322
|
+
textAnchor: "middle",
|
|
6323
|
+
fontSize: "32",
|
|
6324
|
+
fontWeight: "700",
|
|
6325
|
+
className: "fill-gray-900 dark:fill-gray-100",
|
|
6326
|
+
children: total
|
|
6327
|
+
}
|
|
6328
|
+
),
|
|
6329
|
+
/* @__PURE__ */ (0, import_jsx_runtime111.jsx)(
|
|
6330
|
+
"text",
|
|
6331
|
+
{
|
|
6332
|
+
x: centerX,
|
|
6333
|
+
y: centerY + 15,
|
|
6334
|
+
textAnchor: "middle",
|
|
6335
|
+
fontSize: "16",
|
|
6336
|
+
className: "fill-gray-600 dark:fill-gray-400",
|
|
6337
|
+
children: "Total"
|
|
6338
|
+
}
|
|
6339
|
+
)
|
|
6340
|
+
] })
|
|
6341
|
+
]
|
|
6342
|
+
}
|
|
6343
|
+
),
|
|
6344
|
+
showLegend && /* @__PURE__ */ (0, import_jsx_runtime111.jsx)("div", { className: "flex flex-wrap gap-4 mt-4 justify-center", children: data.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)(
|
|
6345
|
+
"div",
|
|
6346
|
+
{
|
|
6347
|
+
className: "flex items-center gap-2 cursor-pointer",
|
|
6348
|
+
onMouseEnter: () => setHoveredSlice(index),
|
|
6349
|
+
onMouseLeave: () => setHoveredSlice(null),
|
|
6350
|
+
children: [
|
|
6079
6351
|
/* @__PURE__ */ (0, import_jsx_runtime111.jsx)(
|
|
6080
|
-
"
|
|
6352
|
+
"div",
|
|
6081
6353
|
{
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
|
|
6086
|
-
className: "cursor-pointer transition-opacity",
|
|
6087
|
-
opacity: isHovered ? 0.8 : 1,
|
|
6088
|
-
onMouseEnter: () => setHoveredSlice(slice.index),
|
|
6089
|
-
onMouseLeave: () => setHoveredSlice(null)
|
|
6354
|
+
className: "w-4 h-4 rounded-sm",
|
|
6355
|
+
style: {
|
|
6356
|
+
backgroundColor: item.color || defaultColors4[index % defaultColors4.length]
|
|
6357
|
+
}
|
|
6090
6358
|
}
|
|
6091
6359
|
),
|
|
6092
|
-
|
|
6093
|
-
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
"text",
|
|
6113
|
-
{
|
|
6114
|
-
x: centerX,
|
|
6115
|
-
y: centerY - 10,
|
|
6116
|
-
textAnchor: "middle",
|
|
6117
|
-
className: "text-2xl font-bold fill-gray-900 dark:fill-gray-100",
|
|
6118
|
-
children: total
|
|
6119
|
-
}
|
|
6120
|
-
),
|
|
6121
|
-
/* @__PURE__ */ (0, import_jsx_runtime111.jsx)(
|
|
6122
|
-
"text",
|
|
6123
|
-
{
|
|
6124
|
-
x: centerX,
|
|
6125
|
-
y: centerY + 15,
|
|
6126
|
-
textAnchor: "middle",
|
|
6127
|
-
className: "text-sm fill-gray-600 dark:fill-gray-400",
|
|
6128
|
-
children: "Total"
|
|
6129
|
-
}
|
|
6130
|
-
)
|
|
6131
|
-
] })
|
|
6132
|
-
]
|
|
6133
|
-
}
|
|
6134
|
-
),
|
|
6135
|
-
showLegend && /* @__PURE__ */ (0, import_jsx_runtime111.jsx)("div", { className: "flex flex-wrap gap-4 mt-4 justify-center", children: data.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)(
|
|
6136
|
-
"div",
|
|
6137
|
-
{
|
|
6138
|
-
className: "flex items-center gap-2 cursor-pointer",
|
|
6139
|
-
onMouseEnter: () => setHoveredSlice(index),
|
|
6140
|
-
onMouseLeave: () => setHoveredSlice(null),
|
|
6141
|
-
children: [
|
|
6142
|
-
/* @__PURE__ */ (0, import_jsx_runtime111.jsx)(
|
|
6143
|
-
"div",
|
|
6144
|
-
{
|
|
6145
|
-
className: "w-4 h-4 rounded-sm",
|
|
6146
|
-
style: {
|
|
6147
|
-
backgroundColor: item.color || defaultColors4[index % defaultColors4.length]
|
|
6148
|
-
}
|
|
6149
|
-
}
|
|
6150
|
-
),
|
|
6151
|
-
/* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: [
|
|
6152
|
-
item.label,
|
|
6153
|
-
": ",
|
|
6154
|
-
item.value,
|
|
6155
|
-
showPercentages && ` (${(item.value / total * 100).toFixed(1)}%)`
|
|
6360
|
+
/* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: [
|
|
6361
|
+
item.label,
|
|
6362
|
+
": ",
|
|
6363
|
+
item.value,
|
|
6364
|
+
showPercentages && ` (${(item.value / total * 100).toFixed(1)}%)`
|
|
6365
|
+
] })
|
|
6366
|
+
]
|
|
6367
|
+
},
|
|
6368
|
+
`legend-${index}`
|
|
6369
|
+
)) }),
|
|
6370
|
+
hoveredSlice !== null && /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("div", { className: "absolute top-2 right-2 bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg text-sm pointer-events-none z-50", children: [
|
|
6371
|
+
/* @__PURE__ */ (0, import_jsx_runtime111.jsx)("div", { className: "font-semibold", children: data[hoveredSlice].label }),
|
|
6372
|
+
/* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("div", { children: [
|
|
6373
|
+
"Value: ",
|
|
6374
|
+
data[hoveredSlice].value
|
|
6375
|
+
] }),
|
|
6376
|
+
/* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("div", { children: [
|
|
6377
|
+
"Percentage: ",
|
|
6378
|
+
(data[hoveredSlice].value / total * 100).toFixed(1),
|
|
6379
|
+
"%"
|
|
6156
6380
|
] })
|
|
6157
|
-
]
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
hoveredSlice !== null && /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("div", { className: "absolute top-2 right-2 bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg text-sm pointer-events-none z-50", children: [
|
|
6162
|
-
/* @__PURE__ */ (0, import_jsx_runtime111.jsx)("div", { className: "font-semibold", children: data[hoveredSlice].label }),
|
|
6163
|
-
/* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("div", { children: [
|
|
6164
|
-
"Value: ",
|
|
6165
|
-
data[hoveredSlice].value
|
|
6166
|
-
] }),
|
|
6167
|
-
/* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("div", { children: [
|
|
6168
|
-
"Percentage: ",
|
|
6169
|
-
(data[hoveredSlice].value / total * 100).toFixed(1),
|
|
6170
|
-
"%"
|
|
6171
|
-
] })
|
|
6172
|
-
] })
|
|
6173
|
-
] });
|
|
6381
|
+
] })
|
|
6382
|
+
]
|
|
6383
|
+
}
|
|
6384
|
+
);
|
|
6174
6385
|
};
|
|
6175
6386
|
|
|
6176
6387
|
// src/utils/theme-script.ts
|