1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
import { createAsync, useParams } from "@solidjs/router"
import { client, getAnalysisList, paths } from "./api.ts";
import { createSignal, For, onMount, Show, Suspense } from "solid-js";
import { SolidApexCharts } from "solid-apexcharts";
import { BarChart, times } from "chartist";
type AnalysisResult =
{ status: 'not requested' }
| { status: 'loading' }
| { status: 'loaded', result: paths['/analysis/execute']['get']['responses'][200]['content']['application/json'] }
export default function Analysis() {
const pathParams = useParams();
const analysisId = pathParams.id!;
let analysis = createAsync(() => getAnalysisList());
const analysisName = () => analysis()?.data?.find(it => it.id == analysisId)?.name
const [startTimestamp, setStartTimestamp] = createSignal(new Date().getTime() - 1000 * 60 * 60 * 24 * 356);
const [endTimestamp, setEndTimestamp] = createSignal(new Date().getTime());
const [analysisResult, setAnalysisResult] = createSignal<AnalysisResult>({ status: 'not requested' });
return <>
<h1 class="text-xl"><Suspense fallback="Name not loaded...">{analysisName()}</Suspense></h1>
<p>
<label>
Start:
<input type="date" value={new Date(startTimestamp()).toISOString().substring(0, 10)} onInput={it => setStartTimestamp(it.target.valueAsNumber)}></input>
</label>
<label>
End:
<input type="date" value={new Date(endTimestamp()).toISOString().substring(0, 10)} onInput={it => setEndTimestamp(it.target.valueAsNumber)}></input>
</label>
<button disabled={analysisResult().status === 'loading'} onClick={() => {
setAnalysisResult({ status: 'loading' });
(async () => {
const result = await client.GET('/analysis/execute', {
params: {
query: {
analysis: analysisId,
tEnd: endTimestamp(),
tStart: startTimestamp()
}
}
});
setAnalysisResult({
status: "loaded",
result: result.data!
});
})();
}}>
Refresh
</button>
<Show when={takeIf(analysisResult(), it => it.status == 'loaded')}>
{element =>
<For each={element().result.visualizations}>
{item =>
<div class="h-300 max-h-[90vh]">
<SolidApexCharts
type="bar"
width={"100%"}
height={"100%"}
options={{
colors: ['#b03060'],
xaxis: {
labels: {
style: {
colors: '#A0A0A0',
},
formatter(value, timestamp, opts) {
return formatDate(timestamp!)
},
},
type: 'numeric',
},
tooltip: {
enabled: false
},
yaxis: {
labels: {
style: {
colors: '#A0A0A0'
},
formatter(val, opts) {
return formatMoney(val)
}
},
decimalsInFloat: 3
},
dataLabels: {
formatter(val, opts) {
return formatMoney(val as number)
},
}
}}
series={[
{
name: item.label,
data: item.dataPoints.map(it => ([it.time, it.value]))
}
]}
></SolidApexCharts>
</div>
}
</For>}
</Show>
</p >
</>
}
const formatMoney = (money: number): string => {
if (money < 0) return `-${formatMoney(money)}`
const moneyNames = [
[1_000_000_000, 'b'],
[1_000_000, 'm'],
[1_000, 'k'],
[1, '']
] as const;
for (const [factor, name] of moneyNames) {
if (money >= factor) {
const scaledValue = Math.round(money / factor * 10) / 10
return `${scaledValue}${name}`
}
}
return money.toString()
}
const formatDate = (date: number | Date) => {
const _date = new Date(date);
return `${_date.getDay()}.${_date.getMonth() + 1}.${_date.getFullYear()}`
}
function takeIf<T extends P, P>(
obj: P,
condition: (arg: P) => arg is T,
): T | false {
return condition(obj) ? obj : false;
}
|