- commit
- fdbc654
- parent
- 76557c7
- author
- CheddarCrisp
- date
- 2020-02-16 19:56:38 +0100 CET
Add history display
6 files changed,
+220,
-19
+35,
-0
1@@ -907,6 +907,35 @@
2 "supports-color": "^5.3.0"
3 }
4 },
5+ "chart.js": {
6+ "version": "2.9.3",
7+ "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.3.tgz",
8+ "integrity": "sha512-+2jlOobSk52c1VU6fzkh3UwqHMdSlgH1xFv9FKMqHiNCpXsGPQa/+81AFa+i3jZ253Mq9aAycPwDjnn1XbRNNw==",
9+ "dev": true,
10+ "requires": {
11+ "chartjs-color": "^2.1.0",
12+ "moment": "^2.10.2"
13+ }
14+ },
15+ "chartjs-color": {
16+ "version": "2.4.1",
17+ "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz",
18+ "integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==",
19+ "dev": true,
20+ "requires": {
21+ "chartjs-color-string": "^0.6.0",
22+ "color-convert": "^1.9.3"
23+ }
24+ },
25+ "chartjs-color-string": {
26+ "version": "0.6.0",
27+ "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz",
28+ "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==",
29+ "dev": true,
30+ "requires": {
31+ "color-name": "^1.0.0"
32+ }
33+ },
34 "chokidar": {
35 "version": "2.1.6",
36 "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz",
37@@ -3828,6 +3857,12 @@
38 }
39 }
40 },
41+ "moment": {
42+ "version": "2.24.0",
43+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
44+ "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==",
45+ "dev": true
46+ },
47 "move-concurrently": {
48 "version": "1.0.1",
49 "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
+1,
-0
1@@ -12,6 +12,7 @@
2 "license": "MIT",
3 "devDependencies": {
4 "@beyonk/google-fonts-webpack-plugin": "^1.2.3",
5+ "chart.js": "^2.9.3",
6 "clean-webpack-plugin": "^3.0.0",
7 "css-loader": "^3.4.2",
8 "google-fonts-webpack-plugin": "^0.4.4",
+13,
-8
1@@ -2,8 +2,8 @@
2 {#each $counters as counter}
3 <Counter counterId={ counter.id }></Counter>
4 {/each}
5-</div>
6 <button class="add" on:click="{ showAdd }"><i class="material-icons">add</i></button>
7+</div>
8 {#if showAddDialog}
9 <div class="dialog">
10 <div class="dialog-content">
11@@ -60,6 +60,8 @@ function add(){
12 bottom: 15px;
13 right: 15px;
14
15+ z-index: 2;
16+
17 background-color: #90C090;
18 border-radius: 50%;
19
20@@ -72,13 +74,16 @@ function add(){
21 margin-left: auto;
22 }
23
24- .dialog-content button {
25- padding: 10px;
26- font-size: 14px;
27- font-weight: 600;
28- }
29-
30 .app {
31- padding: 5px 5px 60px 5px;
32+ padding: 5px;
33+ position: fixed;
34+ top: 0;
35+ right: 0;
36+ bottom: 0;
37+ left: 0;
38+
39+ z-index: 1;
40+
41+ overflow: auto;
42 }
43 </style>
+22,
-11
1@@ -7,8 +7,11 @@
2 <div class="controls">
3 <button on:click={ () => { showIncrement = true; } }><i class="material-icons">add</i></button>
4 <button on:click={ () => { showSet = true; } }><i class="material-icons">edit</i></button>
5- <button class="reset" on:click={ reset }><i class="material-icons">undo</i></button>
6- <button on:click={ startEdit }><i class="material-icons">edit</i></button>
7+ <button class="reset" on:click={ reset }><i class="material-icons">replay</i></button>
8+ {#if counter.saveHistory}
9+ <button class="history" on:click={ () => { showHistory = true; } }><i class="material-icons">show_chart</i></button>
10+ {/if}
11+ <button on:click={ startEdit }><i class="material-icons">settings</i></button>
12 <button on:click={ remove }><i class="material-icons">delete</i></button>
13 </div>
14 {#if showValueDialog}
15@@ -33,15 +36,16 @@
16 </div>
17 </div>
18 {/if}
19+ {#if showHistory}
20+ <History { counterId } on:close={ () => { showHistory = false; } }></History>
21+ {/if}
22 </div>
23 <script>
24 import MyProgress from './MyProgress.svelte';
25+import History from './History.svelte';
26 import { tick } from 'svelte';
27-import { createEventDispatcher } from 'svelte';
28 import { counters } from './db.js';
29
30-const dispatch = createEventDispatcher();
31-
32 export let counterId;
33
34 $: counter = $counters.find(x => x.id == counterId);
35@@ -51,6 +55,7 @@ let showIncrement;
36 let showSet;
37 let showEditDialog;
38 let editingCounter;
39+let showHistory;
40
41 $: showValueDialog = showIncrement || showSet;
42
43@@ -125,6 +130,10 @@ function remove(){
44 padding: 5px;
45 }
46
47+.counter:last-child {
48+ margin-bottom: 72px;
49+}
50+
51 .controls {
52 display: flex;
53 }
54@@ -142,9 +151,17 @@ header {
55 }
56
57 .reset {
58+ margin-left: 24px;
59+}
60+
61+.reset + button {
62 margin-left: auto;
63 }
64
65+.history {
66+ margin-right: 24px;
67+}
68+
69 .dialog-value {
70 width: 100%;
71 margin: 5px 0;
72@@ -153,10 +170,4 @@ header {
73 .ok {
74 margin-left: auto;
75 }
76-
77-.dialog-content button {
78- padding: 10px;
79- font-size: 14px;
80- font-weight: 600;
81-}
82 </style>
+143,
-0
1@@ -0,0 +1,143 @@
2+<div class="history-container">
3+ <header>
4+ <h1>{ counter.title }</h1>
5+ <button class="close" on:click={ close }><i class="material-icons">close</i></button>
6+ </header>
7+ <canvas class="chart-container" bind:this={ chartEl } width="{ window.outerWidth }" height="250">
8+ </canvas>
9+ <div class="table-container">
10+ <table class="history">
11+ <thead>
12+ <tr>
13+ <th>Time</th>
14+ <th>Value</th>
15+ </tr>
16+ </thead>
17+ <tbody>
18+ {#each history as data}
19+ <tr>
20+ <td>{ data.time }</td>
21+ <td>{ data.value }</td>
22+ </tr>
23+ {/each}
24+ </tbody>
25+ </table>
26+ </div>
27+</div>
28+<script>
29+import { createEventDispatcher } from 'svelte';
30+import { counters } from './db.js';
31+import Chart from 'chart.js';
32+
33+const dispatch = createEventDispatcher();
34+
35+const formatter = new Intl.DateTimeFormat('en-US',
36+ {
37+ month: 'short',
38+ day: 'numeric',
39+ year: 'numeric',
40+ hour: 'numeric',
41+ minute: 'numeric'
42+ });
43+
44+$: counter = $counters.find(x => x.id == counterId);
45+$: history = counter.history.map(x => {
46+ return {
47+ time: formatter.format(x.time),
48+ value: x.value
49+ }
50+});
51+$: dataset = counter.history.reduce((acc, x) => {
52+ return {
53+ labels: [...acc.labels, x.time],
54+ datasets: [
55+ {
56+ data: [...acc.datasets[0].data, x.value]
57+ }
58+ ]
59+ }
60+}, {
61+ labels: [],
62+ datasets: [
63+ {
64+ data: []
65+ }
66+ ]
67+});
68+
69+export let counterId;
70+
71+let chartEl;
72+
73+$: {
74+ if(chartEl){
75+ new Chart(chartEl, {
76+ type: 'line',
77+ data: dataset,
78+ options: {
79+ scales: {
80+ xAxes: [
81+ {
82+ type: 'time'
83+ }
84+ ]
85+ },
86+ legend: {
87+ display: false
88+ }
89+ }
90+ });
91+ }
92+}
93+
94+function close(){
95+ dispatch('close');
96+}
97+</script>
98+<style>
99+ .history-container{
100+ background-color: white;
101+ position: fixed;
102+ top: 0;
103+ right: 0;
104+ bottom: 0;
105+ left: 0;
106+ z-index: 3;
107+
108+ display: flex;
109+ flex-direction: column;
110+ align-items: stretch;
111+
112+ overflow: auto;
113+ }
114+
115+ header {
116+ display: flex;
117+ }
118+
119+ header h1 {
120+ font-size: 22px;
121+ font-weight: 600;
122+ margin: 5px;
123+ }
124+
125+ .table-container {
126+ position: relative;
127+ }
128+
129+ .close {
130+ margin-left: auto;
131+ }
132+
133+ .history th {
134+ font-weight: 600;
135+ position: sticky;
136+ background-color: white;
137+ top: 0;
138+ }
139+
140+ .history th, .history td {
141+ border: 1px solid black;
142+ padding: 5px;
143+ }
144+</style>
+6,
-0
1@@ -70,6 +70,12 @@ button {
2 margin-left: auto;
3 }
4
5+.dialog-content button {
6+ padding: 10px;
7+ font-size: 14px;
8+ font-weight: 600;
9+}
10+
11 input[type="text"],
12 input[type="number"] {
13 font-size: 16px;