namirasoft-site-react 1.4.560 → 1.4.561
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/SKILL.md +1 -1
- package/dist/ColorOperation.d.ts +27 -0
- package/dist/ColorOperation.js +145 -0
- package/dist/ColorOperation.js.map +1 -0
- package/dist/components/NSBoxBaseCombo.d.ts +2 -0
- package/dist/components/NSBoxBaseCombo.js +16 -14
- package/dist/components/NSBoxBaseCombo.js.map +1 -1
- package/dist/components/NSBoxCombo.d.ts +4 -4
- package/dist/components/NSBoxCombo.js +2 -2
- package/dist/components/NSBoxCombo.js.map +1 -1
- package/dist/components/NSBoxOptions.d.ts +32 -0
- package/dist/components/NSBoxOptions.js +105 -0
- package/dist/components/NSBoxOptions.js.map +1 -0
- package/dist/components/NSBoxOptions.module.css +54 -0
- package/dist/components/{NSChartColumn.d.ts → NSChartBar.d.ts} +6 -2
- package/dist/components/NSChartBar.js +93 -0
- package/dist/components/NSChartBar.js.map +1 -0
- package/dist/components/NSChartDoughnut.d.ts +3 -0
- package/dist/components/NSChartDoughnut.js +22 -20
- package/dist/components/NSChartDoughnut.js.map +1 -1
- package/dist/components/NSChartLine.d.ts +21 -0
- package/dist/components/NSChartLine.js +76 -0
- package/dist/components/NSChartLine.js.map +1 -0
- package/dist/components/NSChartPie.d.ts +3 -0
- package/dist/components/NSChartPie.js +20 -21
- package/dist/components/NSChartPie.js.map +1 -1
- package/dist/components/NSPagination.js +9 -8
- package/dist/components/NSPagination.js.map +1 -1
- package/dist/components/NSPagination.module.css +1 -0
- package/dist/components/NSTable.d.ts +1 -0
- package/dist/components/NSTable.js +9 -3
- package/dist/components/NSTable.js.map +1 -1
- package/dist/components/NSTableChart.d.ts +49 -0
- package/dist/components/NSTableChart.js +335 -0
- package/dist/components/NSTableChart.js.map +1 -0
- package/dist/components/NSTableChart.module.css +120 -0
- package/dist/main.d.ts +5 -2
- package/dist/main.js +5 -2
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
- package/src/ColorOperation.ts +154 -0
- package/src/components/NSBoxBaseCombo.tsx +14 -10
- package/src/components/NSBoxCombo.tsx +2 -2
- package/src/components/NSBoxOptions.module.css +54 -0
- package/src/components/NSBoxOptions.tsx +183 -0
- package/src/components/NSChartBar.tsx +135 -0
- package/src/components/NSChartDoughnut.tsx +26 -24
- package/src/components/NSChartLine.tsx +111 -0
- package/src/components/NSChartPie.tsx +23 -23
- package/src/components/NSPagination.module.css +1 -0
- package/src/components/NSPagination.tsx +14 -13
- package/src/components/NSTable.tsx +17 -1
- package/src/components/NSTableChart.module.css +120 -0
- package/src/components/NSTableChart.tsx +588 -0
- package/src/main.ts +5 -2
- package/dist/components/NSChartColumn.js +0 -95
- package/dist/components/NSChartColumn.js.map +0 -1
- package/dist/components/NSChartColumn.module.css +0 -8
- package/dist/components/NSChartTable.d.ts +0 -15
- package/dist/components/NSChartTable.js +0 -63
- package/dist/components/NSChartTable.js.map +0 -1
- package/dist/components/NSChartTable.module.css +0 -22
- package/src/components/NSChartColumn.module.css +0 -8
- package/src/components/NSChartColumn.tsx +0 -131
- package/src/components/NSChartTable.module.css +0 -22
- package/src/components/NSChartTable.tsx +0 -95
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { Bar } from 'react-chartjs-2';
|
|
2
|
+
import { Chart as ChartJS, CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend, ChartOptions, ChartData } from 'chart.js';
|
|
3
|
+
import { IBaseComponentProps } from '../props/IBaseComponentProps';
|
|
4
|
+
import { ColorOperation } from '../ColorOperation';
|
|
5
|
+
|
|
6
|
+
ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend);
|
|
7
|
+
|
|
8
|
+
export type NSChartBarMode = "grouped" | "stacked" | "percent";
|
|
9
|
+
|
|
10
|
+
const toPercentDatasets = (dataset: DataSetItem[]): DataSetItem[] =>
|
|
11
|
+
{
|
|
12
|
+
let totals: number[] = [];
|
|
13
|
+
dataset.forEach(item => item.data.forEach((value, index) => totals[index] = (totals[index] ?? 0) + (value || 0)));
|
|
14
|
+
return dataset.map(item => ({
|
|
15
|
+
...item,
|
|
16
|
+
data: item.data.map((value, index) => totals[index] ? (value / totals[index]) * 100 : 0),
|
|
17
|
+
}));
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const prepareDatasets = (dataset: DataSetItem[], mode: NSChartBarMode) =>
|
|
21
|
+
{
|
|
22
|
+
let stacked = mode === "stacked" || mode === "percent";
|
|
23
|
+
let source = mode === "percent" ? toPercentDatasets(dataset) : dataset;
|
|
24
|
+
return source.map((item, index) => ({
|
|
25
|
+
label: item.label,
|
|
26
|
+
data: item.data,
|
|
27
|
+
backgroundColor: item.color ?? ColorOperation.at(index),
|
|
28
|
+
stack: stacked ? "stack" : `stack-${index}`,
|
|
29
|
+
}));
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export interface DataSetItem
|
|
33
|
+
{
|
|
34
|
+
label: string;
|
|
35
|
+
color?: string;
|
|
36
|
+
data: number[]
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
export interface NSChartBarProps extends IBaseComponentProps
|
|
41
|
+
{
|
|
42
|
+
labels: string[];
|
|
43
|
+
dataset: DataSetItem[];
|
|
44
|
+
range: {
|
|
45
|
+
min: number,
|
|
46
|
+
max: number,
|
|
47
|
+
}
|
|
48
|
+
xTitle?: string;
|
|
49
|
+
mode?: NSChartBarMode;
|
|
50
|
+
horizontal?: boolean;
|
|
51
|
+
yGrid?: boolean;
|
|
52
|
+
height?: number;
|
|
53
|
+
width?: number;
|
|
54
|
+
formatValue?: (value: number) => string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function NSChartBar(props: NSChartBarProps)
|
|
58
|
+
{
|
|
59
|
+
let mode: NSChartBarMode = props.mode ?? "grouped";
|
|
60
|
+
let stacked = mode === "stacked" || mode === "percent";
|
|
61
|
+
let percent = mode === "percent";
|
|
62
|
+
let horizontal = props.horizontal ?? false;
|
|
63
|
+
|
|
64
|
+
const data: ChartData<"bar", number[], string> = {
|
|
65
|
+
labels: props.labels,
|
|
66
|
+
datasets: prepareDatasets(props.dataset, mode)
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const categoryScale: any = {
|
|
70
|
+
stacked: stacked,
|
|
71
|
+
ticks: {
|
|
72
|
+
font: { size: 12, weight: 400 },
|
|
73
|
+
color: '#141B5C',
|
|
74
|
+
maxRotation: horizontal ? 0 : 45,
|
|
75
|
+
minRotation: 0,
|
|
76
|
+
},
|
|
77
|
+
grid: { display: false },
|
|
78
|
+
border: { display: false },
|
|
79
|
+
};
|
|
80
|
+
const valueScale: any = {
|
|
81
|
+
stacked: stacked,
|
|
82
|
+
min: percent ? 0 : props.range.min,
|
|
83
|
+
max: percent ? 100 : props.range.max,
|
|
84
|
+
ticks: {
|
|
85
|
+
callback: function (value: any)
|
|
86
|
+
{
|
|
87
|
+
if (percent)
|
|
88
|
+
return value + "%";
|
|
89
|
+
return props.formatValue ? props.formatValue(value as number) : value;
|
|
90
|
+
},
|
|
91
|
+
font: { size: 12, weight: 400 },
|
|
92
|
+
color: '#141B5C',
|
|
93
|
+
},
|
|
94
|
+
grid: { display: props.yGrid, color: "#E6EEF5" },
|
|
95
|
+
border: { display: false },
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const options: ChartOptions<'bar'> = {
|
|
99
|
+
indexAxis: horizontal ? "y" : "x",
|
|
100
|
+
responsive: true,
|
|
101
|
+
maintainAspectRatio: false,
|
|
102
|
+
plugins: {
|
|
103
|
+
legend: {
|
|
104
|
+
display: true,
|
|
105
|
+
position: "bottom"
|
|
106
|
+
},
|
|
107
|
+
tooltip: {
|
|
108
|
+
enabled: true,
|
|
109
|
+
callbacks: {
|
|
110
|
+
title: (items) =>
|
|
111
|
+
{
|
|
112
|
+
let label = items[0]?.label ?? "";
|
|
113
|
+
return props.xTitle ? `${props.xTitle}: ${label}` : label;
|
|
114
|
+
},
|
|
115
|
+
label: ({ dataset, raw }) => percent
|
|
116
|
+
? `${dataset.label}: ${(raw as number).toFixed(1)}%`
|
|
117
|
+
: `${dataset.label}: ${props.formatValue ? props.formatValue(raw as number) : raw}`,
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
scales: {
|
|
122
|
+
x: horizontal ? valueScale : categoryScale,
|
|
123
|
+
y: horizontal ? categoryScale : valueScale,
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<Bar
|
|
129
|
+
data={data}
|
|
130
|
+
options={options}
|
|
131
|
+
width={props.width ?? 320}
|
|
132
|
+
height={props.height ?? 240}
|
|
133
|
+
/>
|
|
134
|
+
);
|
|
135
|
+
};
|
|
@@ -2,13 +2,18 @@
|
|
|
2
2
|
import { Doughnut } from 'react-chartjs-2';
|
|
3
3
|
import { Chart as ChartJS, ArcElement, Tooltip, Legend, Title, SubTitle, CategoryScale, LinearScale, BarElement, PointElement, LineElement, ChartData, Plugin, ArcElement as ArcElementType } from 'chart.js';
|
|
4
4
|
import { IBaseComponentProps } from '../props/IBaseComponentProps';
|
|
5
|
+
import { ColorOperation } from '../ColorOperation';
|
|
5
6
|
|
|
6
7
|
ChartJS.register(ArcElement, Tooltip, Legend, Title, SubTitle, CategoryScale, LinearScale, BarElement, PointElement, LineElement);
|
|
8
|
+
|
|
7
9
|
export interface NSChartDoughnutProps extends IBaseComponentProps
|
|
8
10
|
{
|
|
9
11
|
title: string;
|
|
10
12
|
datas: number[];
|
|
11
13
|
labels: string[]
|
|
14
|
+
labelTitle?: string;
|
|
15
|
+
valueTitle?: string;
|
|
16
|
+
formatValue?: (value: number) => string;
|
|
12
17
|
backgroundColors?: string[];
|
|
13
18
|
borderWidth?: number;
|
|
14
19
|
}
|
|
@@ -16,7 +21,6 @@ export interface NSChartDoughnutProps extends IBaseComponentProps
|
|
|
16
21
|
|
|
17
22
|
export function NSChartDoughnut(props: NSChartDoughnutProps)
|
|
18
23
|
{
|
|
19
|
-
let backgroundColors: string[] = [""];
|
|
20
24
|
const options = {
|
|
21
25
|
responsive: true,
|
|
22
26
|
plugins: {
|
|
@@ -28,11 +32,12 @@ export function NSChartDoughnut(props: NSChartDoughnutProps)
|
|
|
28
32
|
useBorderRadius: false,
|
|
29
33
|
borderRadius: 100,
|
|
30
34
|
boxWidth: 16,
|
|
31
|
-
color: '
|
|
35
|
+
color: '#141b5c',
|
|
32
36
|
},
|
|
33
37
|
},
|
|
34
38
|
title: {
|
|
35
|
-
display:
|
|
39
|
+
display: false,
|
|
40
|
+
text: props.title,
|
|
36
41
|
},
|
|
37
42
|
tooltip: {
|
|
38
43
|
enabled: true,
|
|
@@ -42,6 +47,18 @@ export function NSChartDoughnut(props: NSChartDoughnutProps)
|
|
|
42
47
|
bodyFont: {
|
|
43
48
|
size: 12
|
|
44
49
|
},
|
|
50
|
+
callbacks: {
|
|
51
|
+
title: (items: any[]) =>
|
|
52
|
+
{
|
|
53
|
+
let label = items[0]?.label ?? "";
|
|
54
|
+
return props.labelTitle ? `${props.labelTitle}: ${label}` : label;
|
|
55
|
+
},
|
|
56
|
+
label: (item: any) =>
|
|
57
|
+
{
|
|
58
|
+
let value = props.formatValue ? props.formatValue(item.raw as number) : item.raw;
|
|
59
|
+
return props.valueTitle ? `${props.valueTitle}: ${value}` : `${value}`;
|
|
60
|
+
},
|
|
61
|
+
},
|
|
45
62
|
},
|
|
46
63
|
},
|
|
47
64
|
animation: {
|
|
@@ -49,29 +66,14 @@ export function NSChartDoughnut(props: NSChartDoughnutProps)
|
|
|
49
66
|
}
|
|
50
67
|
};
|
|
51
68
|
|
|
52
|
-
const generateRandomColor = (): string =>
|
|
53
|
-
{
|
|
54
|
-
let maxVal = 0xFFFFFF;
|
|
55
|
-
let randomNumber: number = Math.random() * maxVal;
|
|
56
|
-
randomNumber = Math.floor(randomNumber);
|
|
57
|
-
let X: string = randomNumber.toString(16);
|
|
58
|
-
let randomColor: string = X.padStart(6, "0");
|
|
59
|
-
return `#${randomColor.toUpperCase()}`
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const setRandomColor = (): string[] =>
|
|
63
|
-
{
|
|
64
|
-
props.datas.forEach(() => backgroundColors?.push(generateRandomColor()))
|
|
65
|
-
return backgroundColors;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
69
|
const data: ChartData<'doughnut'> = {
|
|
69
70
|
labels: props.labels,
|
|
70
71
|
datasets: [
|
|
71
72
|
{
|
|
72
73
|
data: props.datas,
|
|
73
|
-
backgroundColor: props.backgroundColors ??
|
|
74
|
-
|
|
74
|
+
backgroundColor: props.backgroundColors ?? ColorOperation.generate(props.datas.length),
|
|
75
|
+
borderColor: "#ffffff",
|
|
76
|
+
borderWidth: props.borderWidth ?? 2
|
|
75
77
|
}
|
|
76
78
|
]
|
|
77
79
|
};
|
|
@@ -83,13 +85,13 @@ export function NSChartDoughnut(props: NSChartDoughnutProps)
|
|
|
83
85
|
const meta = chart.getDatasetMeta(0);
|
|
84
86
|
const arc = meta.data[0] as unknown as ArcElementType;
|
|
85
87
|
ctx.save();
|
|
86
|
-
const fontSize = arc.innerRadius / 3;
|
|
87
|
-
ctx.font = fontSize
|
|
88
|
+
const fontSize = Math.max(12, arc.innerRadius / 3);
|
|
89
|
+
ctx.font = `${fontSize}px sans-serif`;
|
|
88
90
|
ctx.fillStyle = 'hsla(234, 64%, 22%, 1)';
|
|
89
91
|
ctx.textBaseline = 'middle';
|
|
90
92
|
ctx.textAlign = 'center';
|
|
91
93
|
|
|
92
|
-
const text =
|
|
94
|
+
const text = (chart.options?.plugins?.title?.text as string) ?? "";
|
|
93
95
|
const centerX = (arc.x || width / 2);
|
|
94
96
|
const centerY = (arc.y || height / 2);
|
|
95
97
|
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Line } from 'react-chartjs-2';
|
|
2
|
+
import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Filler, Title, Tooltip, Legend, ChartOptions, ChartData } from 'chart.js';
|
|
3
|
+
import { IBaseComponentProps } from '../props/IBaseComponentProps';
|
|
4
|
+
import { ColorOperation } from '../ColorOperation';
|
|
5
|
+
|
|
6
|
+
ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Filler, Title, Tooltip, Legend);
|
|
7
|
+
|
|
8
|
+
export interface NSChartLineDataSetItem
|
|
9
|
+
{
|
|
10
|
+
label: string;
|
|
11
|
+
color?: string;
|
|
12
|
+
data: number[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface NSChartLineProps extends IBaseComponentProps
|
|
16
|
+
{
|
|
17
|
+
labels: string[];
|
|
18
|
+
dataset: NSChartLineDataSetItem[];
|
|
19
|
+
range: {
|
|
20
|
+
min: number,
|
|
21
|
+
max: number,
|
|
22
|
+
}
|
|
23
|
+
xTitle?: string;
|
|
24
|
+
area?: boolean;
|
|
25
|
+
yGrid?: boolean;
|
|
26
|
+
height?: number;
|
|
27
|
+
width?: number;
|
|
28
|
+
formatValue?: (value: number) => string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function NSChartLine(props: NSChartLineProps)
|
|
32
|
+
{
|
|
33
|
+
let area = props.area ?? false;
|
|
34
|
+
|
|
35
|
+
const data: ChartData<"line", number[], string> = {
|
|
36
|
+
labels: props.labels,
|
|
37
|
+
datasets: props.dataset.map((item, index) =>
|
|
38
|
+
{
|
|
39
|
+
let color = item.color ?? ColorOperation.at(index);
|
|
40
|
+
return {
|
|
41
|
+
label: item.label,
|
|
42
|
+
data: item.data,
|
|
43
|
+
borderColor: color,
|
|
44
|
+
backgroundColor: area ? color + "44" : color,
|
|
45
|
+
pointBackgroundColor: color,
|
|
46
|
+
pointRadius: 3,
|
|
47
|
+
pointHoverRadius: 5,
|
|
48
|
+
borderWidth: 2,
|
|
49
|
+
tension: 0.3,
|
|
50
|
+
fill: area,
|
|
51
|
+
};
|
|
52
|
+
})
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const options: ChartOptions<'line'> = {
|
|
56
|
+
responsive: true,
|
|
57
|
+
maintainAspectRatio: false,
|
|
58
|
+
plugins: {
|
|
59
|
+
legend: {
|
|
60
|
+
display: true,
|
|
61
|
+
position: "bottom"
|
|
62
|
+
},
|
|
63
|
+
tooltip: {
|
|
64
|
+
enabled: true,
|
|
65
|
+
callbacks: {
|
|
66
|
+
title: (items) =>
|
|
67
|
+
{
|
|
68
|
+
let label = items[0]?.label ?? "";
|
|
69
|
+
return props.xTitle ? `${props.xTitle}: ${label}` : label;
|
|
70
|
+
},
|
|
71
|
+
label: ({ dataset, raw }) => `${dataset.label}: ${props.formatValue ? props.formatValue(raw as number) : raw}`,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
scales: {
|
|
76
|
+
x: {
|
|
77
|
+
ticks: {
|
|
78
|
+
font: { size: 12, weight: 400 },
|
|
79
|
+
color: '#141B5C',
|
|
80
|
+
maxRotation: 45,
|
|
81
|
+
minRotation: 0,
|
|
82
|
+
},
|
|
83
|
+
grid: { display: false },
|
|
84
|
+
border: { display: false },
|
|
85
|
+
},
|
|
86
|
+
y: {
|
|
87
|
+
min: props.range.min,
|
|
88
|
+
max: props.range.max,
|
|
89
|
+
ticks: {
|
|
90
|
+
callback: function (value)
|
|
91
|
+
{
|
|
92
|
+
return props.formatValue ? props.formatValue(value as number) : value;
|
|
93
|
+
},
|
|
94
|
+
font: { size: 12, weight: 400 },
|
|
95
|
+
color: '#141B5C',
|
|
96
|
+
},
|
|
97
|
+
grid: { display: props.yGrid, color: "#E6EEF5" },
|
|
98
|
+
border: { display: false },
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<Line
|
|
105
|
+
data={data}
|
|
106
|
+
options={options}
|
|
107
|
+
width={props.width ?? 320}
|
|
108
|
+
height={props.height ?? 240}
|
|
109
|
+
/>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
@@ -2,19 +2,23 @@
|
|
|
2
2
|
import { Pie } from 'react-chartjs-2';
|
|
3
3
|
import { Chart as ChartJS, ArcElement, Tooltip, Legend, Title, SubTitle, CategoryScale, LinearScale, BarElement, PointElement, LineElement, ChartData, Plugin, ArcElement as ArcElementType } from 'chart.js';
|
|
4
4
|
import { IBaseComponentProps } from '../props/IBaseComponentProps';
|
|
5
|
+
import { ColorOperation } from '../ColorOperation';
|
|
5
6
|
|
|
6
7
|
ChartJS.register(ArcElement, Tooltip, Legend, Title, SubTitle, CategoryScale, LinearScale, BarElement, PointElement, LineElement);
|
|
8
|
+
|
|
7
9
|
export interface NSChartPieProps extends IBaseComponentProps
|
|
8
10
|
{
|
|
9
11
|
title?: string;
|
|
10
12
|
datas: number[];
|
|
11
13
|
labels: string[];
|
|
14
|
+
labelTitle?: string;
|
|
15
|
+
valueTitle?: string;
|
|
16
|
+
formatValue?: (value: number) => string;
|
|
12
17
|
backgroundColors?: string[];
|
|
13
18
|
borderWidth?: number;
|
|
14
19
|
}
|
|
15
20
|
export function NSChartPie(props: NSChartPieProps)
|
|
16
21
|
{
|
|
17
|
-
let backgroundColors: string[] = [""];
|
|
18
22
|
const options = {
|
|
19
23
|
responsive: true,
|
|
20
24
|
plugins: {
|
|
@@ -23,7 +27,7 @@ export function NSChartPie(props: NSChartPieProps)
|
|
|
23
27
|
responsive: true,
|
|
24
28
|
position: 'left' as 'top',
|
|
25
29
|
labels: {
|
|
26
|
-
useBorderRadius:
|
|
30
|
+
useBorderRadius: false,
|
|
27
31
|
borderRadius: 100,
|
|
28
32
|
boxWidth: 16,
|
|
29
33
|
color: 'hsla(250, 87%, 29%, 1)',
|
|
@@ -37,6 +41,18 @@ export function NSChartPie(props: NSChartPieProps)
|
|
|
37
41
|
bodyFont: {
|
|
38
42
|
size: 12
|
|
39
43
|
},
|
|
44
|
+
callbacks: {
|
|
45
|
+
title: (items: any[]) =>
|
|
46
|
+
{
|
|
47
|
+
let label = items[0]?.label ?? "";
|
|
48
|
+
return props.labelTitle ? `${props.labelTitle}: ${label}` : label;
|
|
49
|
+
},
|
|
50
|
+
label: (item: any) =>
|
|
51
|
+
{
|
|
52
|
+
let value = props.formatValue ? props.formatValue(item.raw as number) : item.raw;
|
|
53
|
+
return props.valueTitle ? `${props.valueTitle}: ${value}` : `${value}`;
|
|
54
|
+
},
|
|
55
|
+
},
|
|
40
56
|
},
|
|
41
57
|
},
|
|
42
58
|
animation: {
|
|
@@ -44,30 +60,14 @@ export function NSChartPie(props: NSChartPieProps)
|
|
|
44
60
|
}
|
|
45
61
|
};
|
|
46
62
|
|
|
47
|
-
const generateRandomColor = (): string =>
|
|
48
|
-
{
|
|
49
|
-
let maxVal = 0xFFFFFF;
|
|
50
|
-
let randomNumber: number = Math.random() * maxVal;
|
|
51
|
-
randomNumber = Math.floor(randomNumber);
|
|
52
|
-
let X: string = randomNumber.toString(16);
|
|
53
|
-
let randomColor: string = X.padStart(6, "0");
|
|
54
|
-
return `#${randomColor.toUpperCase()}`
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const setRandomColor = (): string[] =>
|
|
58
|
-
{
|
|
59
|
-
props.datas.forEach(() => backgroundColors?.push(generateRandomColor()))
|
|
60
|
-
return backgroundColors;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
63
|
const data: ChartData<'pie'> = {
|
|
64
64
|
labels: props.labels,
|
|
65
65
|
datasets: [
|
|
66
66
|
{
|
|
67
67
|
data: props.datas,
|
|
68
|
-
backgroundColor: props.backgroundColors ??
|
|
69
|
-
borderColor:
|
|
70
|
-
borderWidth: props.borderWidth ??
|
|
68
|
+
backgroundColor: props.backgroundColors ?? ColorOperation.generate(props.datas.length),
|
|
69
|
+
borderColor: "#ffffff",
|
|
70
|
+
borderWidth: props.borderWidth ?? 2
|
|
71
71
|
}
|
|
72
72
|
]
|
|
73
73
|
};
|
|
@@ -80,8 +80,8 @@ export function NSChartPie(props: NSChartPieProps)
|
|
|
80
80
|
const arc = meta.data[0] as unknown as ArcElementType;
|
|
81
81
|
|
|
82
82
|
ctx.save();
|
|
83
|
-
const fontSize = arc.innerRadius / 3;
|
|
84
|
-
ctx.font = fontSize
|
|
83
|
+
const fontSize = Math.max(12, arc.innerRadius / 3);
|
|
84
|
+
ctx.font = `${fontSize}px sans-serif`;
|
|
85
85
|
ctx.fillStyle = 'hsla(234, 64%, 22%, 1)';
|
|
86
86
|
ctx.textBaseline = 'middle';
|
|
87
87
|
ctx.textAlign = 'center';
|
|
@@ -3,6 +3,7 @@ import { IBaseComponentProps } from '../props/IBaseComponentProps';
|
|
|
3
3
|
import Styles from './NSPagination.module.css';
|
|
4
4
|
import React from "react";
|
|
5
5
|
import { NSBoxCombo } from './NSBoxCombo';
|
|
6
|
+
import { NSRow } from './NSRow';
|
|
6
7
|
|
|
7
8
|
export interface NSPaginationProps extends IBaseComponentProps
|
|
8
9
|
{
|
|
@@ -143,16 +144,16 @@ export class NSPagination extends Component<NSPaginationProps, NSPaginationState
|
|
|
143
144
|
}
|
|
144
145
|
});
|
|
145
146
|
return (
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
>
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
</div>
|
|
147
|
+
<div
|
|
148
|
+
id={this.props.id}
|
|
149
|
+
className={`${Styles.ns_pagination_container} ${this.props.classList?.join(' ')}`}
|
|
150
|
+
style={this.props.style}
|
|
151
|
+
>
|
|
152
|
+
<div className={Styles.ns_pagination_buttons_container}>
|
|
153
|
+
{pages}
|
|
154
|
+
</div>
|
|
155
155
|
|
|
156
|
+
<NSRow classList={["flex-nowrap"]}>
|
|
156
157
|
<NSBoxCombo
|
|
157
158
|
ref={this.PageSize}
|
|
158
159
|
title=''
|
|
@@ -161,7 +162,7 @@ export class NSPagination extends Component<NSPaginationProps, NSPaginationState
|
|
|
161
162
|
multiple={false}
|
|
162
163
|
defaultValue="25"
|
|
163
164
|
hideHeader
|
|
164
|
-
getOptions={() => pageSizes.map(pagesize => {
|
|
165
|
+
getOptions={() => pageSizes.map(pagesize => ({ value: pagesize.toString(), title: pagesize.toString() }))}
|
|
165
166
|
onChanged={() =>
|
|
166
167
|
{
|
|
167
168
|
let currentPage = this.state.currentPage;
|
|
@@ -171,13 +172,13 @@ export class NSPagination extends Component<NSPaginationProps, NSPaginationState
|
|
|
171
172
|
onPageChange(currentPage, pageSize);
|
|
172
173
|
});
|
|
173
174
|
}}
|
|
174
|
-
style={{ width: "
|
|
175
|
+
style={{ width: "72px" }}
|
|
175
176
|
/>
|
|
176
177
|
<p className={Styles.ns_pagination_info}>
|
|
177
178
|
{`(${current_min.toLocaleString()} - ${current_max.toLocaleString()}) of ${totalItems.toLocaleString()}`}
|
|
178
179
|
</p>
|
|
179
|
-
</
|
|
180
|
-
|
|
180
|
+
</NSRow>
|
|
181
|
+
</div>
|
|
181
182
|
);
|
|
182
183
|
}
|
|
183
184
|
}
|
|
@@ -10,6 +10,7 @@ import { NSDialogPageSelection } from './NSDialogPageSelection';
|
|
|
10
10
|
import { NSLoading } from './NSLoading';
|
|
11
11
|
import { NSNoData } from './NSNoData';
|
|
12
12
|
import { NSPagination } from './NSPagination';
|
|
13
|
+
import { NSTableChart } from './NSTableChart';
|
|
13
14
|
import Styles from './NSTable.module.css';
|
|
14
15
|
|
|
15
16
|
export interface TableInfo
|
|
@@ -93,6 +94,7 @@ interface NSTableState<RowType>
|
|
|
93
94
|
sortItems: SortItem[] | null;
|
|
94
95
|
columnWidths: { [key: string]: number };
|
|
95
96
|
fullscreen: boolean;
|
|
97
|
+
showChart: boolean;
|
|
96
98
|
}
|
|
97
99
|
|
|
98
100
|
enum PageSelectionMode
|
|
@@ -127,6 +129,7 @@ export class NSTable<RowType> extends Component<NSTableProps<RowType>, NSTableSt
|
|
|
127
129
|
sortItems: this.getSortItems(),
|
|
128
130
|
columnWidths: this.loadColumnWidths(),
|
|
129
131
|
fullscreen: false,
|
|
132
|
+
showChart: false,
|
|
130
133
|
};
|
|
131
134
|
this.getSortItemsKey = this.getSortItemsKey.bind(this);
|
|
132
135
|
this.getSortItems = this.getSortItems.bind(this);
|
|
@@ -950,7 +953,10 @@ export class NSTable<RowType> extends Component<NSTableProps<RowType>, NSTableSt
|
|
|
950
953
|
onClick={{
|
|
951
954
|
action: () =>
|
|
952
955
|
{
|
|
953
|
-
this.
|
|
956
|
+
if (!this.state.rows || this.state.rows.length === 0)
|
|
957
|
+
this.showModal(" ", "There is no data to display as a chart.");
|
|
958
|
+
else
|
|
959
|
+
this.setState({ showChart: true });
|
|
954
960
|
},
|
|
955
961
|
showLoading: false
|
|
956
962
|
}}
|
|
@@ -1094,6 +1100,16 @@ export class NSTable<RowType> extends Component<NSTableProps<RowType>, NSTableSt
|
|
|
1094
1100
|
<></>
|
|
1095
1101
|
</NSDialogInfo>
|
|
1096
1102
|
}
|
|
1103
|
+
{
|
|
1104
|
+
this.state.showChart &&
|
|
1105
|
+
<NSTableChart<RowType>
|
|
1106
|
+
name={this.props.name}
|
|
1107
|
+
columns={this.getColumns(true)}
|
|
1108
|
+
rows={this.state.rows ?? []}
|
|
1109
|
+
selectedRows={this.state.selectedRows}
|
|
1110
|
+
onClose={() => this.setState({ showChart: false })}
|
|
1111
|
+
/>
|
|
1112
|
+
}
|
|
1097
1113
|
</div>
|
|
1098
1114
|
);
|
|
1099
1115
|
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
.ns_chart_overlay {
|
|
2
|
+
position: fixed;
|
|
3
|
+
top: 0;
|
|
4
|
+
right: 0;
|
|
5
|
+
left: 0;
|
|
6
|
+
bottom: 0;
|
|
7
|
+
z-index: 950;
|
|
8
|
+
background-color: #ffffff;
|
|
9
|
+
display: flex;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.ns_chart_modal {
|
|
13
|
+
background-color: #ffffff;
|
|
14
|
+
width: 100%;
|
|
15
|
+
height: 100%;
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
overflow: hidden;
|
|
19
|
+
color: #141b5c;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.ns_chart_header {
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
justify-content: space-between;
|
|
26
|
+
padding: 12px 16px;
|
|
27
|
+
border-bottom: 1px solid #e6eef5;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.ns_chart_title {
|
|
31
|
+
font-size: 16px;
|
|
32
|
+
font-weight: 700;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.ns_chart_close {
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.ns_chart_body {
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-direction: column;
|
|
42
|
+
flex: 1;
|
|
43
|
+
min-height: 0;
|
|
44
|
+
overflow-y: auto;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.ns_chart_canvas {
|
|
48
|
+
position: relative;
|
|
49
|
+
flex: none;
|
|
50
|
+
width: 100%;
|
|
51
|
+
padding: 16px;
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
justify-content: center;
|
|
55
|
+
overflow: hidden;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.ns_chart_message {
|
|
59
|
+
color: #6b73a8;
|
|
60
|
+
font-size: 16px;
|
|
61
|
+
text-align: center;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.ns_chart_panel {
|
|
65
|
+
width: 100%;
|
|
66
|
+
border-top: 1px solid #e6eef5;
|
|
67
|
+
padding: 16px;
|
|
68
|
+
align-items: center;
|
|
69
|
+
flex-wrap: nowrap;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.ns_chart_field {
|
|
73
|
+
display: flex;
|
|
74
|
+
flex-direction: column;
|
|
75
|
+
gap: 8px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.ns_chart_label {
|
|
79
|
+
font-size: 13px;
|
|
80
|
+
font-weight: 700;
|
|
81
|
+
color: #141b5c;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.ns_chart_hint {
|
|
85
|
+
font-size: 12px;
|
|
86
|
+
color: #8a90bb;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@media only screen and (min-width: 992px) {
|
|
90
|
+
.ns_chart_header {
|
|
91
|
+
padding: 16px 20px;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.ns_chart_title {
|
|
95
|
+
font-size: 18px;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.ns_chart_body {
|
|
99
|
+
flex-direction: row;
|
|
100
|
+
overflow: hidden;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.ns_chart_canvas {
|
|
104
|
+
flex: 1;
|
|
105
|
+
min-width: 0;
|
|
106
|
+
min-height: 0;
|
|
107
|
+
padding: 48px;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.ns_chart_panel {
|
|
111
|
+
flex: 0 0 400px;
|
|
112
|
+
width: 400px;
|
|
113
|
+
border-top: none;
|
|
114
|
+
border-left: 1px solid #e6eef5;
|
|
115
|
+
padding: 20px;
|
|
116
|
+
align-items: center;
|
|
117
|
+
min-height: 0;
|
|
118
|
+
overflow-y: auto;
|
|
119
|
+
}
|
|
120
|
+
}
|