@thebuoyant-tsdev/mui-ts-library 3.29.2 → 3.31.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/README.de.md +49 -1
- package/README.md +49 -1
- package/dist/components/chord-chart/ChordChart.js +112 -112
- package/dist/components/circle-packing-chart/CirclePackingChart.js +135 -135
- package/dist/components/color-picker/ColorPicker.js +217 -217
- package/dist/components/color-picker/PopoverColorPicker.js +7 -7
- package/dist/components/date-range-picker/DateRangePicker.js +9 -9
- package/dist/components/gantt-chart/GanttChart.js +18 -18
- package/dist/components/gantt-chart/GanttTaskDialog.js +43 -43
- package/dist/components/gantt-chart/GanttTaskPanel.js +128 -128
- package/dist/components/gantt-chart/GanttTimeline.js +16 -16
- package/dist/components/gantt-chart/GanttToolbar.js +24 -24
- package/dist/components/horizontal-tree-chart/HorizontalTreeChart.js +244 -244
- package/dist/components/json-editor/JsonEditor.js +9 -9
- package/dist/components/json-editor/JsonEditorContent.js +54 -54
- package/dist/components/json-editor/JsonEditorToolbar.js +12 -12
- package/dist/components/kanban-board/KanbanBoard.d.ts +2 -0
- package/dist/components/kanban-board/KanbanBoard.js +132 -0
- package/dist/components/kanban-board/KanbanBoard.types.d.ts +93 -0
- package/dist/components/kanban-board/KanbanBoard.types.js +19 -0
- package/dist/components/kanban-board/KanbanBoardCard.d.ts +14 -0
- package/dist/components/kanban-board/KanbanBoardCard.js +118 -0
- package/dist/components/kanban-board/KanbanBoardCardDialog.d.ts +23 -0
- package/dist/components/kanban-board/KanbanBoardCardDialog.js +120 -0
- package/dist/components/kanban-board/KanbanBoardColumn.d.ts +15 -0
- package/dist/components/kanban-board/KanbanBoardColumn.js +132 -0
- package/dist/components/kanban-board/kanbanBoardClasses.d.ts +47 -0
- package/dist/components/kanban-board/kanbanBoardClasses.js +18 -0
- package/dist/components/password-strength-meter/PasswordStrengthMeter.js +27 -27
- package/dist/components/radial-stacked-bar-chart/RadialStackedBarChart.js +48 -48
- package/dist/components/radial-tree-chart/RadialTreeChart.js +173 -173
- package/dist/components/rich-text-editor/RichTextEditor.js +32 -32
- package/dist/components/rich-text-editor/RichTextEditorColorPicker.js +20 -20
- package/dist/components/rich-text-editor/RichTextEditorEmojiPicker.js +12 -12
- package/dist/components/rich-text-editor/RichTextEditorImageDialog.js +11 -11
- package/dist/components/rich-text-editor/RichTextEditorLinkDialog.js +11 -11
- package/dist/components/rich-text-editor/RichTextEditorMarkdownDialog.js +14 -14
- package/dist/components/rich-text-editor/RichTextEditorMentionList.js +14 -14
- package/dist/components/rich-text-editor/RichTextEditorTableMenu.js +28 -28
- package/dist/components/rich-text-editor/RichTextEditorToolbar.js +35 -35
- package/dist/components/sql-editor/SqlEditor.js +24 -24
- package/dist/components/sql-editor/SqlEditorContent.js +16 -16
- package/dist/components/sql-editor/SqlEditorHistoryMenu.js +15 -15
- package/dist/components/sql-editor/SqlEditorToolbar.js +21 -21
- package/dist/components/sunburst-chart/SunburstChart.js +126 -126
- package/dist/components/tag-selection/TagSelection.js +18 -18
- package/dist/components/tag-selection/TagSelectionAutocomplete.js +120 -120
- package/dist/components/tag-selection/TagSelectionSelectedTags.js +10 -10
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +38 -35
- package/package.json +9 -2
package/README.de.md
CHANGED
|
@@ -16,13 +16,14 @@ Eine typsichere React-Komponentenbibliothek auf Basis von **TypeScript** und **M
|
|
|
16
16
|
|
|
17
17
|
## Komponenten
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
15 produktionsreife Komponenten in drei Kategorien. Jede verlinkt zu einer interaktiven Live-Demo und einem vollständigen Manual mit allen Props, Typen und Mustern.
|
|
20
20
|
|
|
21
21
|
### Interaktive UI
|
|
22
22
|
|
|
23
23
|
| Komponente | Wofür | Ausprobieren |
|
|
24
24
|
|---|---|---|
|
|
25
25
|
| [`GanttChart`](#ganttchart) | Drag-and-Drop-Projekt-Timelines mit Meilensteinen, Abhängigkeiten und CSV-Export | [Live-Demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-ganttchart--default) · [Docs](user-manuals/GanttChart.de.md) |
|
|
26
|
+
| [`KanbanBoard`](#kanbanboard) | Drag-and-Drop-Kanban-Board mit eingebauten CRUD-Dialogen, WIP-Limits und i18n | [Live-Demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-kanbanboard--default) · [Docs](user-manuals/KanbanBoard.de.md) |
|
|
26
27
|
| [`DateRangePicker`](#daterangepicker) | Start- und Enddatum in einem Inline-Picker — schließt die MUI X Pro-Lücke, kostenlos und ohne zusätzliche Abhängigkeiten | [Live-Demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-daterangepicker--default) · [Docs](user-manuals/DateRangePicker.de.md) |
|
|
27
28
|
| [`TagSelection`](#tagselection) | Multi-Tag-Autocomplete mit freier Tag-Erstellung und Suchergebnis-Highlighting | [Live-Demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-tagselection--default) · [Docs](user-manuals/TagSelection.de.md) |
|
|
28
29
|
| [`PasswordStrengthMeter`](#passwordstrengthmeter) | Echtzeit-Stärke-Feedback mit eingebautem sicheren Passwort-Generator | [Live-Demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-passwordstrengthmeter--default) · [Docs](user-manuals/PasswordStrengthMeter.de.md) |
|
|
@@ -101,6 +102,43 @@ const tasks: GanttTask[] = [
|
|
|
101
102
|
|
|
102
103
|
---
|
|
103
104
|
|
|
105
|
+
### KanbanBoard
|
|
106
|
+
|
|
107
|
+
Ein Drag-and-Drop-Kanban-Board mit eingebauten Hinzufügen-/Bearbeiten-/Löschen-Dialogen, WIP-Limits und vollständiger i18n. Ideal für Task-Management-Dashboards, Sprint-Boards oder jeden Workflow, bei dem Nutzer Aufgaben zwischen Statusspalten verschieben sollen — mit Kartenfarben, Zuständige-Person-Chips, Fälligkeitsdatum-Chips und konfigurierbarer Chip-Darstellung.
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
import { KanbanBoard } from '@thebuoyant-tsdev/mui-ts-library';
|
|
111
|
+
import type { KanbanColumn, KanbanTask } from '@thebuoyant-tsdev/mui-ts-library';
|
|
112
|
+
import { useState } from 'react';
|
|
113
|
+
|
|
114
|
+
const columns: KanbanColumn[] = [
|
|
115
|
+
{ id: 'todo', label: 'Zu erledigen', color: '#9e9e9e' },
|
|
116
|
+
{ id: 'in-progress', label: 'In Arbeit', color: '#2196f3' },
|
|
117
|
+
{ id: 'done', label: 'Erledigt', color: '#4caf50' },
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
function App() {
|
|
121
|
+
const [tasks, setTasks] = useState<KanbanTask[]>([
|
|
122
|
+
{ id: '1', title: 'Projekt aufsetzen', status: 'todo', assignee: 'Alice' },
|
|
123
|
+
{ id: '2', title: 'Feature umsetzen', status: 'in-progress', assignee: 'Bob', dueDate: new Date('2026-08-01') },
|
|
124
|
+
{ id: '3', title: 'Tests schreiben', status: 'done' },
|
|
125
|
+
]);
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<KanbanBoard
|
|
129
|
+
columns={columns}
|
|
130
|
+
tasks={tasks}
|
|
131
|
+
onTasksChange={setTasks}
|
|
132
|
+
height={500}
|
|
133
|
+
/>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
→ [Vollständige Dokumentation](user-manuals/KanbanBoard.de.md)
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
104
142
|
### DateRangePicker
|
|
105
143
|
|
|
106
144
|
Start- und Enddatum in einem einzigen Inline-Picker — kein MUI X Pro-Lizenz erforderlich. Entwickelt für Formulare, Filter und Buchungsflows. Unterstützt Controlled/Uncontrolled-Modus, `minDate`/`maxDate`, `required`, Inline-Validierung und vollständige i18n. `onChange` gibt für jedes Datum sowohl ein `Date`-Objekt als auch einen ISO-String zurück.
|
|
@@ -458,6 +496,9 @@ import type {
|
|
|
458
496
|
// GanttChart
|
|
459
497
|
GanttTask, GanttTranslations, GanttTheme, GanttToolbarConfig,
|
|
460
498
|
|
|
499
|
+
// KanbanBoard
|
|
500
|
+
KanbanTask, KanbanColumn, KanbanBoardProps, KanbanBoardTranslation,
|
|
501
|
+
|
|
461
502
|
// DateRangePicker
|
|
462
503
|
DateRange, DateRangeEntry, DateRangeInput, DateRangePickerProps, DateRangePickerTranslation,
|
|
463
504
|
|
|
@@ -514,6 +555,13 @@ Dieses Projekt folgt [Semantic Versioning](https://semver.org/):
|
|
|
514
555
|
|
|
515
556
|
## Changelog
|
|
516
557
|
|
|
558
|
+
### [3.30.0] — 2026-07-17
|
|
559
|
+
|
|
560
|
+
**Hinzugefügt**
|
|
561
|
+
- **KanbanBoard** — neue Drag-and-Drop-Kanban-Board-Komponente mit eingebauten CRUD-Dialogen, WIP-Limits, Kartenfarben, Zuständige-Person- und Fälligkeitsdatum-Chips, `chipVariant`-Prop, vollständiger i18n und CSS-Klassen-API (`kanbanBoardClasses`). Siehe [Vollständiger Changelog](https://github.com/thebuoyant/mui-ts-library/blob/main/CHANGELOG.de.md) für Details.
|
|
562
|
+
|
|
563
|
+
---
|
|
564
|
+
|
|
517
565
|
### [3.29.2] — 2026-07-16
|
|
518
566
|
|
|
519
567
|
**Behoben**
|
package/README.md
CHANGED
|
@@ -16,13 +16,14 @@ A type-safe React component library built on **TypeScript** and **MUI (Material
|
|
|
16
16
|
|
|
17
17
|
## Components
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
15 production-ready components across three categories. Each links to a live, interactive demo and a full manual covering every prop, type, and pattern.
|
|
20
20
|
|
|
21
21
|
### Interactive UI
|
|
22
22
|
|
|
23
23
|
| Component | What it's for | Try it |
|
|
24
24
|
|---|---|---|
|
|
25
25
|
| [`GanttChart`](#ganttchart) | Drag-and-drop project timelines with milestones, dependencies, and CSV export | [Live demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-ganttchart--default) · [Docs](user-manuals/GanttChart.md) |
|
|
26
|
+
| [`KanbanBoard`](#kanbanboard) | Drag-and-drop Kanban board with built-in CRUD dialogs, WIP limits, and i18n | [Live demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-kanbanboard--default) · [Docs](user-manuals/KanbanBoard.md) |
|
|
26
27
|
| [`DateRangePicker`](#daterangepicker) | Start + end date in one inline picker — fills the MUI X Pro gap, free and dependency-free | [Live demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-daterangepicker--default) · [Docs](user-manuals/DateRangePicker.md) |
|
|
27
28
|
| [`TagSelection`](#tagselection) | Multi-tag autocomplete with free-form tag creation and search highlighting | [Live demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-tagselection--default) · [Docs](user-manuals/TagSelection.md) |
|
|
28
29
|
| [`PasswordStrengthMeter`](#passwordstrengthmeter) | Real-time strength feedback with a built-in secure password generator | [Live demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-passwordstrengthmeter--default) · [Docs](user-manuals/PasswordStrengthMeter.md) |
|
|
@@ -101,6 +102,43 @@ const tasks: GanttTask[] = [
|
|
|
101
102
|
|
|
102
103
|
---
|
|
103
104
|
|
|
105
|
+
### KanbanBoard
|
|
106
|
+
|
|
107
|
+
A drag-and-drop Kanban board with built-in Add / Edit / Delete dialogs, WIP limits, and full i18n. Use it for task management dashboards, sprint boards, or any workflow where users move work items between status columns — with card colors, assignee chips, due-date chips, and a configurable chip style.
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
import { KanbanBoard } from '@thebuoyant-tsdev/mui-ts-library';
|
|
111
|
+
import type { KanbanColumn, KanbanTask } from '@thebuoyant-tsdev/mui-ts-library';
|
|
112
|
+
import { useState } from 'react';
|
|
113
|
+
|
|
114
|
+
const columns: KanbanColumn[] = [
|
|
115
|
+
{ id: 'todo', label: 'To Do', color: '#9e9e9e' },
|
|
116
|
+
{ id: 'in-progress', label: 'In Progress', color: '#2196f3' },
|
|
117
|
+
{ id: 'done', label: 'Done', color: '#4caf50' },
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
function App() {
|
|
121
|
+
const [tasks, setTasks] = useState<KanbanTask[]>([
|
|
122
|
+
{ id: '1', title: 'Set up project', status: 'todo', assignee: 'Alice' },
|
|
123
|
+
{ id: '2', title: 'Implement feature', status: 'in-progress', assignee: 'Bob', dueDate: new Date('2026-08-01') },
|
|
124
|
+
{ id: '3', title: 'Write tests', status: 'done' },
|
|
125
|
+
]);
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<KanbanBoard
|
|
129
|
+
columns={columns}
|
|
130
|
+
tasks={tasks}
|
|
131
|
+
onTasksChange={setTasks}
|
|
132
|
+
height={500}
|
|
133
|
+
/>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
→ [Full documentation](user-manuals/KanbanBoard.md)
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
104
142
|
### DateRangePicker
|
|
105
143
|
|
|
106
144
|
Start and end date in a single inline picker — no MUI X Pro license required. Built for forms, filters, and booking flows. Supports controlled/uncontrolled mode, `minDate`/`maxDate`, `required`, inline validation, and full i18n. `onChange` returns both a `Date` object and an ISO string for each date.
|
|
@@ -458,6 +496,9 @@ import type {
|
|
|
458
496
|
// GanttChart
|
|
459
497
|
GanttTask, GanttTranslations, GanttTheme, GanttToolbarConfig,
|
|
460
498
|
|
|
499
|
+
// KanbanBoard
|
|
500
|
+
KanbanTask, KanbanColumn, KanbanBoardProps, KanbanBoardTranslation,
|
|
501
|
+
|
|
461
502
|
// DateRangePicker
|
|
462
503
|
DateRange, DateRangeEntry, DateRangeInput, DateRangePickerProps, DateRangePickerTranslation,
|
|
463
504
|
|
|
@@ -514,6 +555,13 @@ This project follows [Semantic Versioning](https://semver.org/):
|
|
|
514
555
|
|
|
515
556
|
## Changelog
|
|
516
557
|
|
|
558
|
+
### [3.30.0] — 2026-07-17
|
|
559
|
+
|
|
560
|
+
**Added**
|
|
561
|
+
- **KanbanBoard** — new drag-and-drop Kanban board component with built-in Add / Edit / Delete dialogs, WIP limits, card colors, assignee and due-date chips, `chipVariant` prop, full i18n, and a CSS classes API (`kanbanBoardClasses`). See [Full Changelog](https://github.com/thebuoyant/mui-ts-library/blob/main/CHANGELOG.md) for details.
|
|
562
|
+
|
|
563
|
+
---
|
|
564
|
+
|
|
517
565
|
### [3.29.2] — 2026-07-16
|
|
518
566
|
|
|
519
567
|
**Fixed**
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { DEFAULT_CHORD_CHART_TRANSLATION as e } from "./ChordChart.types.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { jsx as
|
|
5
|
-
import * as
|
|
2
|
+
import { Box as t, Tooltip as n, Typography as r, useTheme as i } from "@mui/material";
|
|
3
|
+
import { useCallback as a, useLayoutEffect as o, useMemo as s, useRef as ee, useState as c } from "react";
|
|
4
|
+
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
5
|
+
import * as d from "d3";
|
|
6
6
|
//#region src/components/chord-chart/ChordChart.tsx
|
|
7
|
-
function
|
|
7
|
+
function te(e, t = 0, n = ".", r = ",") {
|
|
8
8
|
if (!isFinite(e)) return String(e);
|
|
9
9
|
let [i, a] = e.toFixed(Math.max(0, t)).split("."), o = i.replace(/\B(?=(\d{3})+(?!\d))/g, r);
|
|
10
10
|
return a ? `${o}${n}${a}` : o;
|
|
11
11
|
}
|
|
12
|
-
function
|
|
13
|
-
return /* @__PURE__ */
|
|
12
|
+
function f({ name: e, valueOut: n, valueIn: i, fmt: a }) {
|
|
13
|
+
return /* @__PURE__ */ u(t, {
|
|
14
14
|
sx: { py: .25 },
|
|
15
15
|
children: [
|
|
16
|
-
/* @__PURE__ */
|
|
16
|
+
/* @__PURE__ */ l(r, {
|
|
17
17
|
variant: "caption",
|
|
18
18
|
sx: {
|
|
19
19
|
fontWeight: "bold",
|
|
@@ -21,30 +21,30 @@ function m({ name: e, valueOut: t, valueIn: n, fmt: r }) {
|
|
|
21
21
|
},
|
|
22
22
|
children: e
|
|
23
23
|
}),
|
|
24
|
-
/* @__PURE__ */
|
|
24
|
+
/* @__PURE__ */ u(r, {
|
|
25
25
|
variant: "caption",
|
|
26
26
|
sx: {
|
|
27
27
|
display: "block",
|
|
28
28
|
opacity: .85
|
|
29
29
|
},
|
|
30
|
-
children: [
|
|
30
|
+
children: [a(n), " outgoing →"]
|
|
31
31
|
}),
|
|
32
|
-
/* @__PURE__ */
|
|
32
|
+
/* @__PURE__ */ u(r, {
|
|
33
33
|
variant: "caption",
|
|
34
34
|
sx: {
|
|
35
35
|
display: "block",
|
|
36
36
|
opacity: .85
|
|
37
37
|
},
|
|
38
|
-
children: [
|
|
38
|
+
children: [a(i), " incoming ←"]
|
|
39
39
|
})
|
|
40
40
|
]
|
|
41
41
|
});
|
|
42
42
|
}
|
|
43
|
-
function
|
|
44
|
-
return /* @__PURE__ */
|
|
43
|
+
function p({ sourceName: e, targetName: n, sourceValue: i, targetValue: a, directed: o, fmt: s }) {
|
|
44
|
+
return /* @__PURE__ */ u(t, {
|
|
45
45
|
sx: { py: .25 },
|
|
46
46
|
children: [
|
|
47
|
-
/* @__PURE__ */
|
|
47
|
+
/* @__PURE__ */ u(r, {
|
|
48
48
|
variant: "caption",
|
|
49
49
|
sx: {
|
|
50
50
|
fontWeight: "bold",
|
|
@@ -53,18 +53,18 @@ function h({ sourceName: e, targetName: t, sourceValue: n, targetValue: r, direc
|
|
|
53
53
|
children: [
|
|
54
54
|
e,
|
|
55
55
|
" → ",
|
|
56
|
-
|
|
56
|
+
n
|
|
57
57
|
]
|
|
58
58
|
}),
|
|
59
|
-
/* @__PURE__ */
|
|
59
|
+
/* @__PURE__ */ l(r, {
|
|
60
60
|
variant: "caption",
|
|
61
61
|
sx: {
|
|
62
62
|
display: "block",
|
|
63
63
|
opacity: .85
|
|
64
64
|
},
|
|
65
|
-
children:
|
|
65
|
+
children: s(i)
|
|
66
66
|
}),
|
|
67
|
-
|
|
67
|
+
o && a > 0 && a !== i && /* @__PURE__ */ u(r, {
|
|
68
68
|
variant: "caption",
|
|
69
69
|
sx: {
|
|
70
70
|
display: "block",
|
|
@@ -72,56 +72,56 @@ function h({ sourceName: e, targetName: t, sourceValue: n, targetValue: r, direc
|
|
|
72
72
|
mt: .25
|
|
73
73
|
},
|
|
74
74
|
children: [
|
|
75
|
-
|
|
75
|
+
n,
|
|
76
76
|
" → ",
|
|
77
77
|
e,
|
|
78
78
|
": ",
|
|
79
|
-
a
|
|
79
|
+
s(a)
|
|
80
80
|
]
|
|
81
81
|
})
|
|
82
82
|
]
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
|
-
function
|
|
86
|
-
let
|
|
85
|
+
function m({ data: r, size: m = 500, innerRadius: h, ringThickness: g = 20, padAngle: ne, ribbonPadAngle: re, sortSubgroups: _ = "descending", sortChords: v = "descending", chartColors: y, groupColorConfigs: b, showGroupLabels: ie = !0, labelOffset: ae = 8, ribbonOpacity: oe = .75, ribbonBlendMode: se, directed: x = !0, valueDecimalCount: S = 0, valueDecimalSeparator: C = ".", valueThousandsSeparator: w = ",", valueFormatter: T, onGroupClick: E, onGroupHover: D, onChordClick: O, onChordHover: k, zoomable: A = !1, disabled: j = !1, translation: ce }) {
|
|
86
|
+
let M = i(), le = {
|
|
87
87
|
...e,
|
|
88
|
-
...
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
],
|
|
97
|
-
|
|
88
|
+
...ce
|
|
89
|
+
}, ue = r.length === 0, de = se ?? (M.palette.mode === "dark" ? "normal" : "multiply"), fe = [
|
|
90
|
+
M.palette.primary.main,
|
|
91
|
+
M.palette.secondary.main,
|
|
92
|
+
M.palette.error.main,
|
|
93
|
+
M.palette.warning.main,
|
|
94
|
+
M.palette.success.main,
|
|
95
|
+
M.palette.info.main
|
|
96
|
+
], N = y && y.length > 0 ? y : fe, P = h ?? Math.min(m, m) * .5 - 90, F = Math.max(10, P), I = F + Math.max(1, g), L = ne ?? 10 / F, R = re ?? 1 / F, z = a((e) => T ? T(e) : te(e, S, C, w), [
|
|
97
|
+
T,
|
|
98
|
+
S,
|
|
98
99
|
C,
|
|
99
|
-
w
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
a == null || o == null || (n[a][o] += i);
|
|
100
|
+
w
|
|
101
|
+
]), { names: B, matrix: V } = s(() => {
|
|
102
|
+
let e = d.sort(d.union(r.map((e) => e.source), r.map((e) => e.target))), t = new Map(e.map((e, t) => [e, t])), n = Array.from({ length: e.length }, () => Array(e.length).fill(0));
|
|
103
|
+
for (let { source: e, target: i, value: a } of r) {
|
|
104
|
+
let r = t.get(e), o = t.get(i);
|
|
105
|
+
r == null || o == null || (n[r][o] += a);
|
|
106
106
|
}
|
|
107
107
|
return {
|
|
108
108
|
names: e,
|
|
109
109
|
matrix: n
|
|
110
110
|
};
|
|
111
|
-
}, [
|
|
112
|
-
let e = (
|
|
113
|
-
return
|
|
111
|
+
}, [r]), H = s(() => {
|
|
112
|
+
let e = (x ? d.chordDirected() : d.chord()).padAngle(L);
|
|
113
|
+
return _ === "ascending" && (e = e.sortSubgroups(d.ascending)), _ === "descending" && (e = e.sortSubgroups(d.descending)), v === "ascending" && (e = e.sortChords(d.ascending)), v === "descending" && (e = e.sortChords(d.descending)), e(V);
|
|
114
114
|
}, [
|
|
115
115
|
V,
|
|
116
116
|
L,
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
]), pe =
|
|
117
|
+
x,
|
|
118
|
+
_,
|
|
119
|
+
v
|
|
120
|
+
]), pe = s(() => d.arc().innerRadius(F).outerRadius(I), [F, I]), U = s(() => (x ? d.ribbonArrow() : d.ribbon()).radius(F - 1).padAngle(R), [
|
|
121
121
|
F,
|
|
122
122
|
R,
|
|
123
|
-
|
|
124
|
-
]), me =
|
|
123
|
+
x
|
|
124
|
+
]), me = a((e) => U({
|
|
125
125
|
source: {
|
|
126
126
|
startAngle: e.source.startAngle,
|
|
127
127
|
endAngle: e.source.endAngle,
|
|
@@ -132,16 +132,16 @@ function g({ data: c, size: g = 500, innerRadius: _, ringThickness: ee = 20, pad
|
|
|
132
132
|
endAngle: e.target.endAngle,
|
|
133
133
|
radius: F - 1
|
|
134
134
|
}
|
|
135
|
-
}) ?? "", [U, F]), W =
|
|
136
|
-
|
|
135
|
+
}) ?? "", [U, F]), W = s(() => d.scaleOrdinal().domain(d.range(B.length)).range(N.length >= B.length ? N : [...Array(Math.ceil(B.length / N.length))].flatMap(() => N).slice(0, B.length)), [N, B.length]), G = a((e) => b?.[B[e]]?.fill ?? W(e), [
|
|
136
|
+
b,
|
|
137
137
|
B,
|
|
138
138
|
W
|
|
139
|
-
]), K =
|
|
139
|
+
]), K = ee(null), [q, J] = c(`-${m / 2} -${m / 2} ${m} ${m}`), [Y, X] = c(1), he = s(() => {
|
|
140
140
|
if (Y === 1) return q;
|
|
141
141
|
let [e, t, n, r] = q.split(" ").map(Number), i = n / Y, a = r / Y;
|
|
142
142
|
return `${e + (n - i) / 2} ${t + (r - a) / 2} ${i} ${a}`;
|
|
143
143
|
}, [q, Y]);
|
|
144
|
-
|
|
144
|
+
o(() => {
|
|
145
145
|
let e = K.current;
|
|
146
146
|
if (!e) return;
|
|
147
147
|
let t = requestAnimationFrame(() => {
|
|
@@ -149,27 +149,27 @@ function g({ data: c, size: g = 500, innerRadius: _, ringThickness: ee = 20, pad
|
|
|
149
149
|
let t = e.getBBox();
|
|
150
150
|
J(`${t.x - 8} ${t.y - 8} ${t.width + 16} ${t.height + 16}`);
|
|
151
151
|
} catch {
|
|
152
|
-
J(`-${
|
|
152
|
+
J(`-${m / 2} -${m / 2} ${m} ${m}`);
|
|
153
153
|
}
|
|
154
154
|
});
|
|
155
155
|
return () => cancelAnimationFrame(t);
|
|
156
156
|
}, [
|
|
157
|
-
|
|
157
|
+
m,
|
|
158
158
|
F,
|
|
159
159
|
I,
|
|
160
160
|
B.length,
|
|
161
161
|
H
|
|
162
162
|
]);
|
|
163
|
-
let [Z, Q] =
|
|
163
|
+
let [Z, Q] = c(null), ge = a((e) => ({
|
|
164
164
|
name: B[e.index],
|
|
165
165
|
index: e.index,
|
|
166
|
-
valueOut:
|
|
167
|
-
valueIn:
|
|
166
|
+
valueOut: d.sum(H, (t) => (t.source.index === e.index ? t.source.value : 0) + (!x && t.target.index === e.index ? t.target.value : 0)),
|
|
167
|
+
valueIn: d.sum(H, (t) => (t.target.index === e.index ? t.source.value : 0) + (!x && t.source.index === e.index ? t.target.value : 0))
|
|
168
168
|
}), [
|
|
169
169
|
B,
|
|
170
170
|
H,
|
|
171
|
-
|
|
172
|
-
]), _e =
|
|
171
|
+
x
|
|
172
|
+
]), _e = a((e) => ({
|
|
173
173
|
source: {
|
|
174
174
|
name: B[e.source.index],
|
|
175
175
|
index: e.source.index,
|
|
@@ -182,81 +182,81 @@ function g({ data: c, size: g = 500, innerRadius: _, ringThickness: ee = 20, pad
|
|
|
182
182
|
}
|
|
183
183
|
}), [B]), ve = (e) => {
|
|
184
184
|
let t = (e.startAngle + e.endAngle) / 2, n = t * 180 / Math.PI - 90, r = t > Math.PI ? " rotate(180)" : "";
|
|
185
|
-
return `rotate(${n}) translate(${I +
|
|
186
|
-
}, ye = (e) => (e.startAngle + e.endAngle) / 2 > Math.PI ? "end" : "start", be =
|
|
187
|
-
if (!
|
|
185
|
+
return `rotate(${n}) translate(${I + ae})${r}`;
|
|
186
|
+
}, ye = (e) => (e.startAngle + e.endAngle) / 2 > Math.PI ? "end" : "start", be = a((e) => {
|
|
187
|
+
if (!A || j || !e.ctrlKey) return;
|
|
188
188
|
e.preventDefault();
|
|
189
189
|
let t = e.deltaY < 0 ? 1.15 : 1 / 1.15;
|
|
190
190
|
X((e) => Math.max(.25, Math.min(8, e * t)));
|
|
191
|
-
}, [
|
|
192
|
-
|
|
193
|
-
if (!
|
|
191
|
+
}, [A, j]);
|
|
192
|
+
o(() => {
|
|
193
|
+
if (!A) return;
|
|
194
194
|
let e = (e) => {
|
|
195
195
|
e.key === "Escape" && X(1);
|
|
196
196
|
};
|
|
197
197
|
return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
|
|
198
|
-
}, [
|
|
198
|
+
}, [A]);
|
|
199
199
|
let $ = {
|
|
200
200
|
followCursor: !0,
|
|
201
201
|
enterDelay: 50,
|
|
202
202
|
enterNextDelay: 0,
|
|
203
|
-
disableHoverListener:
|
|
203
|
+
disableHoverListener: j,
|
|
204
204
|
slotProps: { tooltip: { sx: { maxWidth: 240 } } }
|
|
205
|
-
}, xe =
|
|
206
|
-
return /* @__PURE__ */
|
|
205
|
+
}, xe = M.palette.text.primary, Se = M.typography.fontFamily;
|
|
206
|
+
return /* @__PURE__ */ l(t, {
|
|
207
207
|
sx: {
|
|
208
208
|
display: "inline-flex",
|
|
209
|
-
opacity:
|
|
210
|
-
cursor:
|
|
209
|
+
opacity: j ? .5 : 1,
|
|
210
|
+
cursor: j ? "not-allowed" : "default",
|
|
211
211
|
userSelect: "none"
|
|
212
212
|
},
|
|
213
|
-
children: /* @__PURE__ */
|
|
214
|
-
width:
|
|
215
|
-
height:
|
|
213
|
+
children: /* @__PURE__ */ l("svg", {
|
|
214
|
+
width: m,
|
|
215
|
+
height: m,
|
|
216
216
|
viewBox: he,
|
|
217
217
|
onWheel: be,
|
|
218
218
|
style: {
|
|
219
219
|
fontFamily: Se ?? "sans-serif",
|
|
220
|
-
overflow:
|
|
220
|
+
overflow: A && Y > 1 ? "hidden" : "visible"
|
|
221
221
|
},
|
|
222
222
|
role: "img",
|
|
223
223
|
"aria-label": "Chord chart",
|
|
224
|
-
children: /* @__PURE__ */
|
|
224
|
+
children: /* @__PURE__ */ u("g", {
|
|
225
225
|
ref: K,
|
|
226
226
|
children: [
|
|
227
|
-
|
|
227
|
+
ue && /* @__PURE__ */ l("text", {
|
|
228
228
|
textAnchor: "middle",
|
|
229
229
|
dy: "0.35em",
|
|
230
230
|
fontSize: 13,
|
|
231
|
-
fill:
|
|
232
|
-
children:
|
|
231
|
+
fill: M.palette.text.secondary,
|
|
232
|
+
children: le.noData
|
|
233
233
|
}),
|
|
234
|
-
/* @__PURE__ */
|
|
235
|
-
let t = ge(e),
|
|
236
|
-
return /* @__PURE__ */
|
|
234
|
+
/* @__PURE__ */ l("g", { children: H.groups.map((e) => {
|
|
235
|
+
let t = ge(e), r = Z === e.index, i = Z !== null && !r;
|
|
236
|
+
return /* @__PURE__ */ l(n, {
|
|
237
237
|
...$,
|
|
238
|
-
title: /* @__PURE__ */
|
|
238
|
+
title: /* @__PURE__ */ l(f, {
|
|
239
239
|
name: t.name,
|
|
240
240
|
valueOut: t.valueOut,
|
|
241
241
|
valueIn: t.valueIn,
|
|
242
242
|
fmt: z
|
|
243
243
|
}),
|
|
244
|
-
children: /* @__PURE__ */
|
|
245
|
-
style: { cursor:
|
|
244
|
+
children: /* @__PURE__ */ u("g", {
|
|
245
|
+
style: { cursor: j ? "not-allowed" : "pointer" },
|
|
246
246
|
onMouseEnter: (n) => {
|
|
247
|
-
|
|
247
|
+
j || (Q(e.index), D?.(t, n));
|
|
248
248
|
},
|
|
249
249
|
onMouseLeave: (e) => {
|
|
250
|
-
Q(null),
|
|
250
|
+
Q(null), D?.(null, e);
|
|
251
251
|
},
|
|
252
|
-
onClick: (e) => !
|
|
253
|
-
children: [/* @__PURE__ */
|
|
252
|
+
onClick: (e) => !j && E?.(t, e),
|
|
253
|
+
children: [/* @__PURE__ */ l("path", {
|
|
254
254
|
d: pe(e) || "",
|
|
255
255
|
fill: G(e.index),
|
|
256
|
-
stroke:
|
|
257
|
-
opacity:
|
|
256
|
+
stroke: M.palette.divider,
|
|
257
|
+
opacity: i ? .35 : 1,
|
|
258
258
|
style: { transition: "opacity 0.15s" }
|
|
259
|
-
}),
|
|
259
|
+
}), ie && /* @__PURE__ */ l("text", {
|
|
260
260
|
dy: "0.35em",
|
|
261
261
|
fontSize: 11,
|
|
262
262
|
fill: xe,
|
|
@@ -268,37 +268,37 @@ function g({ data: c, size: g = 500, innerRadius: _, ringThickness: ee = 20, pad
|
|
|
268
268
|
})
|
|
269
269
|
}, `grp-tt-${e.index}`);
|
|
270
270
|
}) }),
|
|
271
|
-
/* @__PURE__ */
|
|
272
|
-
fillOpacity:
|
|
273
|
-
style: { mixBlendMode:
|
|
271
|
+
/* @__PURE__ */ l("g", {
|
|
272
|
+
fillOpacity: oe,
|
|
273
|
+
style: { mixBlendMode: de },
|
|
274
274
|
children: H.map((e, t) => {
|
|
275
|
-
let
|
|
276
|
-
return /* @__PURE__ */
|
|
275
|
+
let r = _e(e), i = Z === null || e.source.index === Z || e.target.index === Z;
|
|
276
|
+
return /* @__PURE__ */ l(n, {
|
|
277
277
|
...$,
|
|
278
|
-
title: /* @__PURE__ */
|
|
279
|
-
sourceName:
|
|
280
|
-
targetName:
|
|
281
|
-
sourceValue:
|
|
282
|
-
targetValue:
|
|
283
|
-
directed:
|
|
278
|
+
title: /* @__PURE__ */ l(p, {
|
|
279
|
+
sourceName: r.source.name,
|
|
280
|
+
targetName: r.target.name,
|
|
281
|
+
sourceValue: r.source.value,
|
|
282
|
+
targetValue: r.target.value,
|
|
283
|
+
directed: x,
|
|
284
284
|
fmt: z
|
|
285
285
|
}),
|
|
286
|
-
children: /* @__PURE__ */
|
|
286
|
+
children: /* @__PURE__ */ l("path", {
|
|
287
287
|
d: me(e),
|
|
288
288
|
fill: G(e.target.index),
|
|
289
289
|
stroke: "none",
|
|
290
|
-
opacity:
|
|
290
|
+
opacity: i ? 1 : .12,
|
|
291
291
|
style: {
|
|
292
|
-
cursor:
|
|
292
|
+
cursor: j ? "not-allowed" : "pointer",
|
|
293
293
|
transition: "opacity 0.15s"
|
|
294
294
|
},
|
|
295
295
|
onMouseEnter: (e) => {
|
|
296
|
-
|
|
296
|
+
j || k?.(r, e);
|
|
297
297
|
},
|
|
298
298
|
onMouseLeave: (e) => {
|
|
299
|
-
|
|
299
|
+
k?.(null, e);
|
|
300
300
|
},
|
|
301
|
-
onClick: (e) => !
|
|
301
|
+
onClick: (e) => !j && O?.(r, e)
|
|
302
302
|
})
|
|
303
303
|
}, `chord-tt-${t}`);
|
|
304
304
|
})
|
|
@@ -308,6 +308,6 @@ function g({ data: c, size: g = 500, innerRadius: _, ringThickness: ee = 20, pad
|
|
|
308
308
|
})
|
|
309
309
|
});
|
|
310
310
|
}
|
|
311
|
-
|
|
311
|
+
m.displayName = "ChordChart";
|
|
312
312
|
//#endregion
|
|
313
|
-
export {
|
|
313
|
+
export { m as ChordChart };
|