Compare commits

...

122 Commits

Author SHA1 Message Date
ROY 6a1a31d6e3 [update] debug cp 2022-09-20 18:49:49 +08:00
ROY 86c7f2b30d [update] update eis AC_AMP fomula 2022-09-16 10:43:39 +08:00
ROY 97de1cf4e3 [update] update eis AC_AMP & FREQ fomula 2022-09-14 18:22:03 +08:00
peterlu14 91e100319f [update] project parameter duplicate remove 2022-09-14 18:19:29 +08:00
peterlu14 ca3a525332 [update] add slide-out 2022-09-07 09:46:53 +08:00
peterlu14 9d77ba9c01 [update] add fake start action at start & add new action idle & add click css 2022-09-06 19:43:19 +08:00
peterlu14 53ba6ee486 [update] battery 1s -> 1min & Potential force direct to V 2022-09-05 14:48:29 +08:00
peterlu14 cb42635f6a Merge remote-tracking branch 'origin/dev/battery_display' into release/v1.3.6/battery 2022-08-31 10:20:30 +08:00
peterlu14 d43de5927f Merge remote-tracking branch 'origin/dev/sync-parameter' into release/v1.3.5/cached 2022-08-31 10:08:45 +08:00
sss28072637 05ecd69ecd [update] update battery icon & add low battery warning 2022-08-30 18:16:31 +08:00
peterlu14 062938dd0b [update] refresh cache 2022-08-30 15:31:06 +08:00
peterlu14 5e3eb47614 [update] area display fix 2022-08-29 16:48:05 +08:00
peterlu14 1b682421fd [debug] get legend name fail & capture multitimes 2022-08-29 16:36:29 +08:00
peterlu14 aac74382ad Merge remote-tracking branch 'origin/dev/EISReplayFix' into release/v1.3.4/battery&replayEIS 2022-08-29 16:04:11 +08:00
nthu1080112244 0b005638f6 [debug] fix chartAct device undefined 2022-08-29 16:03:43 +08:00
nthu1080112244 f5604b4ad4 [debug] fix typing error 2022-08-29 15:51:03 +08:00
peterlu14 5d772b9d5b Merge remote-tracking branch 'origin/dev/EISReplayFix' into release/v1.3.4/battery&replayEIS 2022-08-29 15:50:26 +08:00
nthu1080112244 857184392c [update] brush delay = 0 2022-08-29 15:46:51 +08:00
nthu1080112244 6c1304bcea [debug] fix specific integral key in bug 2022-08-29 11:40:49 +08:00
nthu1080112244 bcdaecca77 [debug] resolve replay cycle select bug 2022-08-29 11:13:19 +08:00
nthu1080112244 a5330c71dc [debug] fix some typing error 2022-08-29 10:12:41 +08:00
nthu1080112244 a8b6937b72 [update] new setting table, new replay layout 2022-08-26 16:53:23 +08:00
sss28072637 e69e42ac63 [update] adjust the formula of calculating battery, add battery icon & percentage 2022-08-24 17:55:38 +08:00
peterlu14 01f0f45bdd [update] sg_filter scale with sample rate & volt step 2022-08-24 13:27:25 +08:00
ROY 0719284f24 [update] fix VOLT_VSCAN scale 2022-08-23 11:37:02 +08:00
sss28072637 0cecf9abec [update] add battery display 2022-08-22 18:07:06 +08:00
nthu1080112244 93a0ea9b24 Merge branch 'release/v1.3.2/replay_new_function' into dev/EISReplayFix 2022-08-22 17:25:47 +08:00
nthu1080112244 0a7ecfb060 [debug] add comment 2022-08-22 16:40:34 +08:00
nthu1080112244 7642e41d58 [debug] remove annoying console log 2022-08-22 16:16:21 +08:00
nthu1080112244 a0050047d0 [debug] captured chart fix 2022-08-22 16:12:02 +08:00
peterlu14 d3fcf78b45 [refresh] realtime parameter refresh 2022-08-22 11:40:05 +08:00
peterlu14 0d279cb0bf [debug] fix capture data clear problem 2022-08-22 11:38:40 +08:00
peterlu14 44989dd7f7 [debug] fix scheduler parameter not refresh & default MODE = 0 2022-08-22 11:37:56 +08:00
nthu1080112244 07c38de627 [fix] fix real time display 2022-08-22 10:15:12 +08:00
peterlu14 e4c2018e12 Merge remote-tracking branch 'origin/dev/scheduler-function' into release/v1.3.3/merge_scheduler 2022-08-19 18:56:45 +08:00
peterlu14 a0fea97ca7 [update] differential 2022-08-19 18:56:12 +08:00
nthu1080112244 347e1b647f [update] fix add chart option & display bar 2022-08-19 18:16:29 +08:00
108000207 20d94f8c09 [debug] project table library bug (auto connect) 2022-08-19 17:57:06 +08:00
108000207 eb80489c41 [update] scheduler cycle UI 2022-08-19 17:11:37 +08:00
108000207 d337afd7b9 [update] show cycle number on project running 2022-08-19 16:54:20 +08:00
peterlu14 82f46030a3 [update] fix realtime unit function type 2022-08-19 16:17:57 +08:00
peterlu14 8052dfcbf4 [update] file table fix 2022-08-19 15:55:14 +08:00
nthu1080112244 3030b46a64 Merge remote-tracking branch 'origin/dev/source_channel' into dev/repalyControlPanelNew 2022-08-19 14:28:21 +08:00
108000207 ec7edb6bd9 Merge remote-tracking branch 'origin/dev/drag_task' into dev/scheduler-function 2022-08-18 18:25:05 +08:00
unknown eca51be1f8 [update] get source from different mode (some bugs need to be fixed) 2022-08-18 18:21:44 +08:00
108000207 4ac9fe32d1 [update] remove cycle save condition 2022-08-18 18:16:38 +08:00
108000207 46def3dab3 [update] change the UI of scheduler cycle 2022-08-18 17:38:12 +08:00
unknown b560670ada Merge remote-tracking branch 'origin/release/v1.3.2/replay_new_function-hide_project' into dev/drag_task 2022-08-18 14:59:16 +08:00
unknown e7786e6c8c [update] complete drag task function 2022-08-18 14:51:59 +08:00
nthu1080112244 bdd9113b80 [update] real time grid setting 2022-08-17 17:58:58 +08:00
unknown 60d4b63d6b [update] drag task (remain some bugs need to be fixed) 2022-08-17 17:57:52 +08:00
peterlu14 56559738c4 Revert "[update] realtime chart default unit determine by mode now"
This reverts commit fc269f972a.
2022-08-17 15:37:06 +08:00
peterlu14 7639d495b9 Merge branch 'release/v1.3.2/replay_new_function' into release/v1.3.2/replay_new_function-hide_project 2022-08-17 15:23:26 +08:00
108000207 d08f49548b [update] scheduler cycle v1 ( support nest cycle) 2022-08-17 11:58:32 +08:00
ROY 99f51f4307 Merge remote-tracking branch 'origin/release/v1.3.2/replay_new_function' into dev/sync-parameter 2022-08-17 10:54:29 +08:00
peterlu14 001f7139eb [update] fix file table 2022-08-16 20:27:35 +08:00
peterlu14 27bb612bd8 [update] add eis global mode 2022-08-16 19:51:35 +08:00
peterlu14 f5ce74f308 [update] EIS add VOLT_VSCAN and time_duration 2022-08-16 19:51:31 +08:00
108000207 c85c7b0285 [update] fix cycle count 2022-08-16 14:34:18 +08:00
ROY dec4ad1093 [update] realtime nA support mode [10, 11] 2022-08-16 11:32:14 +08:00
ROY e2735f7782 Merge remote-tracking branch 'origin/release/v1.3.2/replay_new_function' into dev/sync-parameter 2022-08-16 11:30:50 +08:00
108000207 3c14cc552f Merge remote-tracking branch 'origin/dev/scheduler' into dev/scheduler-function 2022-08-16 11:16:58 +08:00
nthu1080112244 e3267fdb3a [update] new version control panel 2022-08-16 10:10:46 +08:00
peterlu14 fe723ae897 Merge remote-tracking branch 'origin/dev/delete_actions' into dev/scheduler 2022-08-15 19:10:37 +08:00
peterlu14 fc269f972a [update] realtime chart default unit determine by mode now 2022-08-15 19:06:16 +08:00
sss28072637 c12c4e8fff [update] complete delete actions and the function of swap task 2022-08-15 18:19:50 +08:00
peterlu14 05abfd122a [debug] fix file-table folder show working mode error 2022-08-15 18:12:04 +08:00
JayC319 39bb196db7 message 2022-08-15 17:51:58 +08:00
JayC319 df34998b51 Merge remote-tracking branch 'origin/release/v1.3.2/replay_new_function' into dev/sync-parameter 2022-08-15 17:44:33 +08:00
peterlu14 567d7595cf Merge remote-tracking branch 'origin/dev/delete_actions' into release/v1.3.2/replay_new_function 2022-08-15 14:26:50 +08:00
108000207 a312a32ddc Merge remote-tracking branch 'origin/dev/delete_actions' into dev/scheduler-function 2022-08-15 14:01:48 +08:00
sss28072637 2167f9ef06 [update] complete delete actions, default parameter 2022-08-15 12:01:57 +08:00
108000207 4005961b8a Merge remote-tracking branch 'origin/release/v1.3.2/replay_new_function-hide_project' into dev/scheduler-function 2022-08-15 09:34:37 +08:00
108000207 8cb9ac007e [update] add scheduler cycle at condition, for setting cycle, cycle_next, and cycle_count 2022-08-15 09:31:21 +08:00
peterlu14 41907d5151 Merge branch 'release/v1.3.2/replay_new_function' into release/v1.3.2/replay_new_function-hide_project 2022-08-14 19:30:29 +08:00
peterlu14 68e0edfcdd [update] fix captured failed 2022-08-14 19:09:24 +08:00
peterlu14 4d5f6afffb [update] hide project 2022-08-13 22:43:44 +08:00
peterlu14 07c3f6c9a6 [update] file show working mode 2022-08-13 22:41:00 +08:00
peterlu14 7fb30ffa0a [update] remove replay Axis option cycle 2022-08-13 22:05:14 +08:00
peterlu14 d501d2e01d [update] change default unit & change idiot to not support 2022-08-13 21:53:00 +08:00
peterlu14 99d903dcbf [debug] fix init Time-X Graph change xAxis to other cause chart crush problem (cost lots time) 2022-08-13 21:52:24 +08:00
peterlu14 599838adc5 [debug] fix init not showing data 2022-08-13 21:51:05 +08:00
peterlu14 c9593e2a6e [update] remove old code & refreshformatter no need to refreshChart 2022-08-13 21:50:24 +08:00
peterlu14 16e3e49168 [debug] fix cycle not showing & data null & rules followed by controlPanel 2022-08-13 20:38:45 +08:00
peterlu14 fb0d8bd3f2 [update] replay hide old methods 2022-08-12 21:34:33 +08:00
peterlu14 2f1fe88a60 [update] remove 456456 2022-08-12 21:10:28 +08:00
peterlu14 1eca3c0e72 [update] chart ui resize & mac address to uppercase 2022-08-12 21:09:57 +08:00
peterlu14 1f72708e69 [update] chart name uppercase 2022-08-12 21:08:20 +08:00
peterlu14 8efeb6572d Merge remote-tracking branch 'origin/dev/replayControlPanelFix' into release/v1.3.1/issue_fixed 2022-08-12 19:00:23 +08:00
nthu1080112244 3fce79d6c9 [update] replay control panel & real time layout 2022-08-12 18:57:42 +08:00
peterlu14 52d93f7fad Merge remote-tracking branch 'origin/dev/adjust_button' into release/v1.3.1/issue_fixed 2022-08-12 18:51:33 +08:00
sss28072637 4178842ba3 [update] update button icon 2022-08-12 18:06:33 +08:00
sss28072637 625908053b [fix] fix select-box of device 2022-08-12 11:05:48 +08:00
peterlu14 94eb83ec24 [update] fix replay legend label not showing 2022-08-11 20:33:45 +08:00
peterlu14 4bd25148de [update] hide overview chart legend name 2022-08-11 19:14:37 +08:00
sss28072637 17feeb893e [update] device automatically connect when clicking project 2022-08-11 18:19:28 +08:00
peterlu14 f6b66f0114 [update] hide control panel 2022-08-11 17:36:39 +08:00
108000207 402dd3a66b [debug] fix the bug of project(scheduler): change task but not refresh real-time axis 2022-08-11 15:36:47 +08:00
peterlu14 a256112c6b [update] refresh timer speed up 2022-08-11 15:20:14 +08:00
sss28072637 0ad6b39f96 [update] add button of each task & add close btn 2022-08-11 15:18:11 +08:00
peterlu14 bad7406b10 [update] remove duplicate router 2022-08-11 13:33:05 +08:00
peterlu14 957e806abb [debug] fix last data not show 2022-08-11 13:32:38 +08:00
peterlu14 0824a6b534 [update] remove max limit & short max range 2022-08-11 11:20:45 +08:00
peterlu14 95f1e05b7e [debug] fix databufferstream not clear problem 2022-08-11 11:19:30 +08:00
peterlu14 1fae8538e8 Merge branch 'dev/debug' into release/v1.3.0/replay-capture-sgFilter 2022-08-11 01:04:28 +08:00
peterlu14 f92ba3d098 Merge remote-tracking branch 'origin/dev/scheduler-function' into release/v1.3.0/replay-capture-sgFilter 2022-08-11 01:04:25 +08:00
peterlu14 28b6ee9aa8 Merge remote-tracking branch 'origin/dev/task_button_scheduler' into release/v1.3.0/replay-capture-sgFilter 2022-08-11 01:04:08 +08:00
peterlu14 1a028c1595 Merge remote-tracking branch 'origin/dev/replayControlPanelFix' into release/v1.3.0/replay-capture-sgFilter 2022-08-11 01:02:25 +08:00
peterlu14 b3a745252f [update] add show datastream buffer in dev mode 2022-08-11 00:59:14 +08:00
peterlu14 d229e1be28 [update] add debug button (show data) 2022-08-11 00:51:58 +08:00
peterlu14 c95bc79096 [update] rename developer mode & bind key 2022-08-10 23:56:38 +08:00
peterlu14 ac19737527 [update] default time unit ms -> s 2022-08-10 22:21:18 +08:00
peterlu14 69e4af91af [update] remove x-axis interval and select all buttons & resize grid and dataZoom and asixLabel 2022-08-10 22:20:54 +08:00
peterlu14 cd961f70f9 [warning] remove warning of e-charts update 2022-08-10 22:13:53 +08:00
nthu1080112244 fc5c222dc7 [update] unit and functional can works 2022-08-10 18:09:38 +08:00
sss28072637 ff3a9061de [update] add setting button to the row of Task 2022-08-10 17:59:33 +08:00
108000207 89e80a67af [update] add the router for Project(scheduler) 2022-08-10 14:02:44 +08:00
nthu1080112244 868577de7d [update] new comtrol panel block 2022-08-10 12:06:35 +08:00
sss28072637 82dfb8a5ff Merge branch 'release/v1.3.0/replay-capture-sgFilter' of https://gitlab.com/wisetop/controller/wisetopvue into release/v1.3.0/replay-capture-sgFilter 2022-08-09 17:49:08 +08:00
peterlu14 8b7b92bffb [update] add eis ca mode 2022-08-09 14:54:32 +08:00
peterlu14 1b38bd1c00 [debug] fix library rename cause scheduler not showing problem 2022-08-09 14:53:12 +08:00
peterlu14 e2e0b5609a [update] add -sync-parameter 2022-08-09 14:18:38 +08:00
77 changed files with 3408 additions and 1454 deletions
+509 -545
View File
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -15,14 +15,15 @@
"dependencies": {
"@fontsource/source-code-pro": "^4.5.0",
"@fontsource/source-sans-pro": "^4.5.1",
"@hyjiacan/vue-slideout": "^2.5.9",
"@types/jest": "^24.0.11",
"amcharts3": "^3.21.14",
"ammap3": "^3.21.14",
"approximate-number": "^2.0.0",
"asva-executors": "^0.1.22",
"axios": "^0.21.4",
"axios": "^0.21.1",
"babel-polyfill": "^6.26.0",
"chart.js": "^2.9.4",
"chart.js": "^2.9.3",
"core-js": "3",
"detect-browser": "^4.8.0",
"echarts": "^5.3.3",
+3
View File
@@ -2,6 +2,9 @@
<html>
<head>
<meta charset="utf-8">
<!-- <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" /> -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
+1 -1
View File
@@ -15,7 +15,7 @@ export default {
// Temporary config for 2.1.
contextConfig: {
gradient: true,
shadow: 'lg', // 3 states: 'sm', 'lg', undefined (no shadow).
shadow: 'lg', // 3 states: 'sm', 'sddssslg', undefined (no shadow).
invertedColor: false,
},
}
+7 -2
View File
@@ -30,6 +30,9 @@ import 'vue-toastification/dist/index.css'
import api from '@/data/api/index'
import localforage from 'localforage'
import SlideOut from '@hyjiacan/vue-slideout'
import '@hyjiacan/vue-slideout/lib/slideout.css'
import '../metrics'
import '../registerServiceWorker'
@@ -72,8 +75,6 @@ let MqttUrl
// for developer
if (process.env.NODE_ENV === 'development') {
MqttUrl = 'ws://192.168.5.66:8083'
// MqttUrl = 'ws://192.168.5.42:8083'
// MqttUrl = 'ws://192.168.5.240:8080'
// MqttUrl = 'ws://192.168.5.57:8083'
// MqttUrl = 'ws://192.168.5.57:8080'
} else {
@@ -103,6 +104,10 @@ Vue.use(Toast)
// Vue.use(VueMqtt, 'ws://' + '192.168.151.125' + ':8083')
Vue.use(VueMqtt, MqttUrl)
Vue.use(SlideOut, {
// set default props here
})
Vue.prototype.API = api
Vue.prototype.GLOBAL = global_
+4
View File
@@ -0,0 +1,4 @@
<svg width="55" height="30" viewBox="0 0 55 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="55" height="30" rx="15" fill="#45589E"/>
<path d="M10.8849 20V9.81818H13.0376V18.2251H17.4027V20H10.8849ZM22.2388 20.1491C21.4666 20.1491 20.7987 19.9851 20.2353 19.657C19.6751 19.3255 19.2426 18.8648 18.9377 18.2749C18.6328 17.6816 18.4803 16.9938 18.4803 16.2116C18.4803 15.4228 18.6328 14.7334 18.9377 14.1435C19.2426 13.5502 19.6751 13.0895 20.2353 12.7614C20.7987 12.4299 21.4666 12.2642 22.2388 12.2642C23.0111 12.2642 23.6773 12.4299 24.2374 12.7614C24.8008 13.0895 25.235 13.5502 25.54 14.1435C25.8449 14.7334 25.9973 15.4228 25.9973 16.2116C25.9973 16.9938 25.8449 17.6816 25.54 18.2749C25.235 18.8648 24.8008 19.3255 24.2374 19.657C23.6773 19.9851 23.0111 20.1491 22.2388 20.1491ZM22.2488 18.5085C22.6001 18.5085 22.8934 18.4091 23.1287 18.2102C23.3641 18.008 23.5414 17.733 23.6607 17.3849C23.7833 17.0369 23.8446 16.6409 23.8446 16.1967C23.8446 15.7526 23.7833 15.3565 23.6607 15.0085C23.5414 14.6605 23.3641 14.3854 23.1287 14.1832C22.8934 13.9811 22.6001 13.88 22.2488 13.88C21.8941 13.88 21.5958 13.9811 21.3539 14.1832C21.1152 14.3854 20.9346 14.6605 20.812 15.0085C20.6926 15.3565 20.633 15.7526 20.633 16.1967C20.633 16.6409 20.6926 17.0369 20.812 17.3849C20.9346 17.733 21.1152 18.008 21.3539 18.2102C21.5958 18.4091 21.8941 18.5085 22.2488 18.5085ZM30.8148 23.0227C30.1287 23.0227 29.5404 22.9283 29.0499 22.7393C28.5627 22.5537 28.1749 22.3002 27.8865 21.9787C27.5982 21.6572 27.4109 21.2959 27.3248 20.8949L29.2836 20.6314C29.3432 20.7839 29.4377 20.9264 29.5669 21.0589C29.6962 21.1915 29.8669 21.2976 30.079 21.3771C30.2944 21.46 30.5563 21.5014 30.8645 21.5014C31.3252 21.5014 31.7047 21.3887 32.003 21.1634C32.3046 20.9413 32.4554 20.5684 32.4554 20.0447V18.6477H32.3659C32.2731 18.8598 32.1339 19.0604 31.9483 19.2493C31.7627 19.4382 31.5241 19.5923 31.2324 19.7116C30.9408 19.831 30.5927 19.8906 30.1884 19.8906C29.615 19.8906 29.093 19.758 28.6223 19.4929C28.155 19.2244 27.7821 18.8151 27.5037 18.2649C27.2286 17.7114 27.0911 17.0121 27.0911 16.1669C27.0911 15.3018 27.2319 14.5793 27.5137 13.9993C27.7954 13.4193 28.1699 12.9851 28.6373 12.6967C29.1079 12.4084 29.6233 12.2642 30.1834 12.2642C30.611 12.2642 30.9689 12.3371 31.2573 12.483C31.5456 12.6255 31.7776 12.8045 31.9533 13.0199C32.1323 13.232 32.2698 13.4408 32.3659 13.6463H32.4455V12.3636H34.5485V20.0746C34.5485 20.7242 34.3894 21.2678 34.0712 21.7053C33.753 22.1428 33.3122 22.4709 32.7488 22.6896C32.1886 22.9117 31.544 23.0227 30.8148 23.0227ZM30.8596 18.2997C31.2009 18.2997 31.4893 18.2152 31.7246 18.0462C31.9632 17.8738 32.1455 17.6286 32.2715 17.3104C32.4007 16.9889 32.4654 16.6044 32.4654 16.157C32.4654 15.7095 32.4024 15.3217 32.2765 14.9936C32.1505 14.6622 31.9682 14.4053 31.7296 14.223C31.4909 14.0407 31.2009 13.9496 30.8596 13.9496C30.5115 13.9496 30.2182 14.044 29.9796 14.233C29.7409 14.4186 29.5603 14.6771 29.4377 15.0085C29.315 15.34 29.2537 15.7228 29.2537 16.157C29.2537 16.5978 29.315 16.9789 29.4377 17.3004C29.5636 17.6186 29.7443 17.8655 29.9796 18.0412C30.2182 18.2135 30.5115 18.2997 30.8596 18.2997ZM38.2921 9.81818L40.3453 13.2884H40.4249L42.4881 9.81818H44.9192L41.812 14.9091L44.9888 20H42.513L40.4249 16.5249H40.3453L38.2573 20H35.7914L38.9782 14.9091L35.851 9.81818H38.2921Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg width="55" height="30" viewBox="0 0 55 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="55" height="30" rx="15" fill="#E34A4A"/>
<path d="M10.8849 20V9.81818H13.0376V18.2251H17.4027V20H10.8849ZM22.2388 20.1491C21.4666 20.1491 20.7987 19.9851 20.2353 19.657C19.6751 19.3255 19.2426 18.8648 18.9377 18.2749C18.6328 17.6816 18.4803 16.9938 18.4803 16.2116C18.4803 15.4228 18.6328 14.7334 18.9377 14.1435C19.2426 13.5502 19.6751 13.0895 20.2353 12.7614C20.7987 12.4299 21.4666 12.2642 22.2388 12.2642C23.0111 12.2642 23.6773 12.4299 24.2374 12.7614C24.8008 13.0895 25.235 13.5502 25.54 14.1435C25.8449 14.7334 25.9973 15.4228 25.9973 16.2116C25.9973 16.9938 25.8449 17.6816 25.54 18.2749C25.235 18.8648 24.8008 19.3255 24.2374 19.657C23.6773 19.9851 23.0111 20.1491 22.2388 20.1491ZM22.2488 18.5085C22.6001 18.5085 22.8934 18.4091 23.1287 18.2102C23.3641 18.008 23.5414 17.733 23.6607 17.3849C23.7833 17.0369 23.8446 16.6409 23.8446 16.1967C23.8446 15.7526 23.7833 15.3565 23.6607 15.0085C23.5414 14.6605 23.3641 14.3854 23.1287 14.1832C22.8934 13.9811 22.6001 13.88 22.2488 13.88C21.8941 13.88 21.5958 13.9811 21.3539 14.1832C21.1152 14.3854 20.9346 14.6605 20.812 15.0085C20.6926 15.3565 20.633 15.7526 20.633 16.1967C20.633 16.6409 20.6926 17.0369 20.812 17.3849C20.9346 17.733 21.1152 18.008 21.3539 18.2102C21.5958 18.4091 21.8941 18.5085 22.2488 18.5085ZM30.8148 23.0227C30.1287 23.0227 29.5404 22.9283 29.0499 22.7393C28.5627 22.5537 28.1749 22.3002 27.8865 21.9787C27.5982 21.6572 27.4109 21.2959 27.3248 20.8949L29.2836 20.6314C29.3432 20.7839 29.4377 20.9264 29.5669 21.0589C29.6962 21.1915 29.8669 21.2976 30.079 21.3771C30.2944 21.46 30.5563 21.5014 30.8645 21.5014C31.3252 21.5014 31.7047 21.3887 32.003 21.1634C32.3046 20.9413 32.4554 20.5684 32.4554 20.0447V18.6477H32.3659C32.2731 18.8598 32.1339 19.0604 31.9483 19.2493C31.7627 19.4382 31.5241 19.5923 31.2324 19.7116C30.9408 19.831 30.5927 19.8906 30.1884 19.8906C29.615 19.8906 29.093 19.758 28.6223 19.4929C28.155 19.2244 27.7821 18.8151 27.5037 18.2649C27.2286 17.7114 27.0911 17.0121 27.0911 16.1669C27.0911 15.3018 27.2319 14.5793 27.5137 13.9993C27.7954 13.4193 28.1699 12.9851 28.6373 12.6967C29.1079 12.4084 29.6233 12.2642 30.1834 12.2642C30.611 12.2642 30.9689 12.3371 31.2573 12.483C31.5456 12.6255 31.7776 12.8045 31.9533 13.0199C32.1323 13.232 32.2698 13.4408 32.3659 13.6463H32.4455V12.3636H34.5485V20.0746C34.5485 20.7242 34.3894 21.2678 34.0712 21.7053C33.753 22.1428 33.3122 22.4709 32.7488 22.6896C32.1886 22.9117 31.544 23.0227 30.8148 23.0227ZM30.8596 18.2997C31.2009 18.2997 31.4893 18.2152 31.7246 18.0462C31.9632 17.8738 32.1455 17.6286 32.2715 17.3104C32.4007 16.9889 32.4654 16.6044 32.4654 16.157C32.4654 15.7095 32.4024 15.3217 32.2765 14.9936C32.1505 14.6622 31.9682 14.4053 31.7296 14.223C31.4909 14.0407 31.2009 13.9496 30.8596 13.9496C30.5115 13.9496 30.2182 14.044 29.9796 14.233C29.7409 14.4186 29.5603 14.6771 29.4377 15.0085C29.315 15.34 29.2537 15.7228 29.2537 16.157C29.2537 16.5978 29.315 16.9789 29.4377 17.3004C29.5636 17.6186 29.7443 17.8655 29.9796 18.0412C30.2182 18.2135 30.5115 18.2997 30.8596 18.2997ZM38.2921 9.81818L40.3453 13.2884H40.4249L42.4881 9.81818H44.9192L41.812 14.9091L44.9888 20H42.513L40.4249 16.5249H40.3453L38.2573 20H35.7914L38.9782 14.9091L35.851 9.81818H38.2921Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg width="55" height="30" viewBox="0 0 55 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="55" height="30" rx="15" fill="#6CB0A4"/>
<path d="M10.8849 20V9.81818H13.0376V18.2251H17.4027V20H10.8849ZM22.2388 20.1491C21.4666 20.1491 20.7987 19.9851 20.2353 19.657C19.6751 19.3255 19.2426 18.8648 18.9377 18.2749C18.6328 17.6816 18.4803 16.9938 18.4803 16.2116C18.4803 15.4228 18.6328 14.7334 18.9377 14.1435C19.2426 13.5502 19.6751 13.0895 20.2353 12.7614C20.7987 12.4299 21.4666 12.2642 22.2388 12.2642C23.0111 12.2642 23.6773 12.4299 24.2374 12.7614C24.8008 13.0895 25.235 13.5502 25.54 14.1435C25.8449 14.7334 25.9973 15.4228 25.9973 16.2116C25.9973 16.9938 25.8449 17.6816 25.54 18.2749C25.235 18.8648 24.8008 19.3255 24.2374 19.657C23.6773 19.9851 23.0111 20.1491 22.2388 20.1491ZM22.2488 18.5085C22.6001 18.5085 22.8934 18.4091 23.1287 18.2102C23.3641 18.008 23.5414 17.733 23.6607 17.3849C23.7833 17.0369 23.8446 16.6409 23.8446 16.1967C23.8446 15.7526 23.7833 15.3565 23.6607 15.0085C23.5414 14.6605 23.3641 14.3854 23.1287 14.1832C22.8934 13.9811 22.6001 13.88 22.2488 13.88C21.8941 13.88 21.5958 13.9811 21.3539 14.1832C21.1152 14.3854 20.9346 14.6605 20.812 15.0085C20.6926 15.3565 20.633 15.7526 20.633 16.1967C20.633 16.6409 20.6926 17.0369 20.812 17.3849C20.9346 17.733 21.1152 18.008 21.3539 18.2102C21.5958 18.4091 21.8941 18.5085 22.2488 18.5085ZM30.8148 23.0227C30.1287 23.0227 29.5404 22.9283 29.0499 22.7393C28.5627 22.5537 28.1749 22.3002 27.8865 21.9787C27.5982 21.6572 27.4109 21.2959 27.3248 20.8949L29.2836 20.6314C29.3432 20.7839 29.4377 20.9264 29.5669 21.0589C29.6962 21.1915 29.8669 21.2976 30.079 21.3771C30.2944 21.46 30.5563 21.5014 30.8645 21.5014C31.3252 21.5014 31.7047 21.3887 32.003 21.1634C32.3046 20.9413 32.4554 20.5684 32.4554 20.0447V18.6477H32.3659C32.2731 18.8598 32.1339 19.0604 31.9483 19.2493C31.7627 19.4382 31.5241 19.5923 31.2324 19.7116C30.9408 19.831 30.5927 19.8906 30.1884 19.8906C29.615 19.8906 29.093 19.758 28.6223 19.4929C28.155 19.2244 27.7821 18.8151 27.5037 18.2649C27.2286 17.7114 27.0911 17.0121 27.0911 16.1669C27.0911 15.3018 27.2319 14.5793 27.5137 13.9993C27.7954 13.4193 28.1699 12.9851 28.6373 12.6967C29.1079 12.4084 29.6233 12.2642 30.1834 12.2642C30.611 12.2642 30.9689 12.3371 31.2573 12.483C31.5456 12.6255 31.7776 12.8045 31.9533 13.0199C32.1323 13.232 32.2698 13.4408 32.3659 13.6463H32.4455V12.3636H34.5485V20.0746C34.5485 20.7242 34.3894 21.2678 34.0712 21.7053C33.753 22.1428 33.3122 22.4709 32.7488 22.6896C32.1886 22.9117 31.544 23.0227 30.8148 23.0227ZM30.8596 18.2997C31.2009 18.2997 31.4893 18.2152 31.7246 18.0462C31.9632 17.8738 32.1455 17.6286 32.2715 17.3104C32.4007 16.9889 32.4654 16.6044 32.4654 16.157C32.4654 15.7095 32.4024 15.3217 32.2765 14.9936C32.1505 14.6622 31.9682 14.4053 31.7296 14.223C31.4909 14.0407 31.2009 13.9496 30.8596 13.9496C30.5115 13.9496 30.2182 14.044 29.9796 14.233C29.7409 14.4186 29.5603 14.6771 29.4377 15.0085C29.315 15.34 29.2537 15.7228 29.2537 16.157C29.2537 16.5978 29.315 16.9789 29.4377 17.3004C29.5636 17.6186 29.7443 17.8655 29.9796 18.0412C30.2182 18.2135 30.5115 18.2997 30.8596 18.2997ZM35.677 9.81818H38.0882L40.41 14.2031H40.5094L42.8311 9.81818H45.2424L41.5286 16.4006V20H39.3908V16.4006L35.677 9.81818Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg width="55" height="30" viewBox="0 0 55 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="55" height="30" rx="15" fill="#E34A4A"/>
<path d="M10.8849 20V9.81818H13.0376V18.2251H17.4027V20H10.8849ZM22.2388 20.1491C21.4666 20.1491 20.7987 19.9851 20.2353 19.657C19.6751 19.3255 19.2426 18.8648 18.9377 18.2749C18.6328 17.6816 18.4803 16.9938 18.4803 16.2116C18.4803 15.4228 18.6328 14.7334 18.9377 14.1435C19.2426 13.5502 19.6751 13.0895 20.2353 12.7614C20.7987 12.4299 21.4666 12.2642 22.2388 12.2642C23.0111 12.2642 23.6773 12.4299 24.2374 12.7614C24.8008 13.0895 25.235 13.5502 25.54 14.1435C25.8449 14.7334 25.9973 15.4228 25.9973 16.2116C25.9973 16.9938 25.8449 17.6816 25.54 18.2749C25.235 18.8648 24.8008 19.3255 24.2374 19.657C23.6773 19.9851 23.0111 20.1491 22.2388 20.1491ZM22.2488 18.5085C22.6001 18.5085 22.8934 18.4091 23.1287 18.2102C23.3641 18.008 23.5414 17.733 23.6607 17.3849C23.7833 17.0369 23.8446 16.6409 23.8446 16.1967C23.8446 15.7526 23.7833 15.3565 23.6607 15.0085C23.5414 14.6605 23.3641 14.3854 23.1287 14.1832C22.8934 13.9811 22.6001 13.88 22.2488 13.88C21.8941 13.88 21.5958 13.9811 21.3539 14.1832C21.1152 14.3854 20.9346 14.6605 20.812 15.0085C20.6926 15.3565 20.633 15.7526 20.633 16.1967C20.633 16.6409 20.6926 17.0369 20.812 17.3849C20.9346 17.733 21.1152 18.008 21.3539 18.2102C21.5958 18.4091 21.8941 18.5085 22.2488 18.5085ZM30.8148 23.0227C30.1287 23.0227 29.5404 22.9283 29.0499 22.7393C28.5627 22.5537 28.1749 22.3002 27.8865 21.9787C27.5982 21.6572 27.4109 21.2959 27.3248 20.8949L29.2836 20.6314C29.3432 20.7839 29.4377 20.9264 29.5669 21.0589C29.6962 21.1915 29.8669 21.2976 30.079 21.3771C30.2944 21.46 30.5563 21.5014 30.8645 21.5014C31.3252 21.5014 31.7047 21.3887 32.003 21.1634C32.3046 20.9413 32.4554 20.5684 32.4554 20.0447V18.6477H32.3659C32.2731 18.8598 32.1339 19.0604 31.9483 19.2493C31.7627 19.4382 31.5241 19.5923 31.2324 19.7116C30.9408 19.831 30.5927 19.8906 30.1884 19.8906C29.615 19.8906 29.093 19.758 28.6223 19.4929C28.155 19.2244 27.7821 18.8151 27.5037 18.2649C27.2286 17.7114 27.0911 17.0121 27.0911 16.1669C27.0911 15.3018 27.2319 14.5793 27.5137 13.9993C27.7954 13.4193 28.1699 12.9851 28.6373 12.6967C29.1079 12.4084 29.6233 12.2642 30.1834 12.2642C30.611 12.2642 30.9689 12.3371 31.2573 12.483C31.5456 12.6255 31.7776 12.8045 31.9533 13.0199C32.1323 13.232 32.2698 13.4408 32.3659 13.6463H32.4455V12.3636H34.5485V20.0746C34.5485 20.7242 34.3894 21.2678 34.0712 21.7053C33.753 22.1428 33.3122 22.4709 32.7488 22.6896C32.1886 22.9117 31.544 23.0227 30.8148 23.0227ZM30.8596 18.2997C31.2009 18.2997 31.4893 18.2152 31.7246 18.0462C31.9632 17.8738 32.1455 17.6286 32.2715 17.3104C32.4007 16.9889 32.4654 16.6044 32.4654 16.157C32.4654 15.7095 32.4024 15.3217 32.2765 14.9936C32.1505 14.6622 31.9682 14.4053 31.7296 14.223C31.4909 14.0407 31.2009 13.9496 30.8596 13.9496C30.5115 13.9496 30.2182 14.044 29.9796 14.233C29.7409 14.4186 29.5603 14.6771 29.4377 15.0085C29.315 15.34 29.2537 15.7228 29.2537 16.157C29.2537 16.5978 29.315 16.9789 29.4377 17.3004C29.5636 17.6186 29.7443 17.8655 29.9796 18.0412C30.2182 18.2135 30.5115 18.2997 30.8596 18.2997ZM35.677 9.81818H38.0882L40.41 14.2031H40.5094L42.8311 9.81818H45.2424L41.5286 16.4006V20H39.3908V16.4006L35.677 9.81818Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

+9
View File
@@ -0,0 +1,9 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30 15C30 23.2843 23.2843 30 15 30C6.71573 30 0 23.2843 0 15C0 6.71573 6.71573 0 15 0C23.2843 0 30 6.71573 30 15Z" fill="#D6860F"/>
<mask id="mask0_4_143" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="5" y="5" width="20" height="19">
<rect x="5" y="5" width="20" height="19" fill="#D9D9D9"/>
</mask>
<g mask="url(#mask0_4_143)">
<path d="M20.8334 11.3333V9.75001H19.1667V8.16668H20.8334V6.58334H22.5V8.16668H24.1667V9.75001H22.5V11.3333H20.8334ZM7.50004 22.4167C7.04171 22.4167 6.64949 22.2618 6.32337 21.952C5.99671 21.6416 5.83337 21.2688 5.83337 20.8333V11.3333C5.83337 10.8979 5.99671 10.5253 6.32337 10.2155C6.64949 9.90518 7.04171 9.75001 7.50004 9.75001H10.125L11.6667 8.16668H16.6667V9.75001H12.3959L10.875 11.3333H7.50004V20.8333H20.8334V13.7083H22.5V20.8333C22.5 21.2688 22.337 21.6416 22.0109 21.952C21.6842 22.2618 21.2917 22.4167 20.8334 22.4167H7.50004ZM14.1667 19.6458C15.2084 19.6458 16.0939 19.2996 16.8234 18.6072C17.5523 17.9142 17.9167 17.0729 17.9167 16.0833C17.9167 15.0938 17.5523 14.2525 16.8234 13.5595C16.0939 12.8671 15.2084 12.5208 14.1667 12.5208C13.125 12.5208 12.2395 12.8671 11.51 13.5595C10.7812 14.2525 10.4167 15.0938 10.4167 16.0833C10.4167 17.0729 10.7812 17.9142 11.51 18.6072C12.2395 19.2996 13.125 19.6458 14.1667 19.6458ZM14.1667 18.0625C13.5834 18.0625 13.0903 17.8712 12.6875 17.4886C12.2848 17.1059 12.0834 16.6375 12.0834 16.0833C12.0834 15.5292 12.2848 15.0608 12.6875 14.6781C13.0903 14.2955 13.5834 14.1042 14.1667 14.1042C14.75 14.1042 15.2431 14.2955 15.6459 14.6781C16.0487 15.0608 16.25 15.5292 16.25 16.0833C16.25 16.6375 16.0487 17.1059 15.6459 17.4886C15.2431 17.8712 14.75 18.0625 14.1667 18.0625Z" fill="white"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

+6
View File
@@ -0,0 +1,6 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="15" cy="15" r="15" fill="#8D8D8D"/>
<path d="M6.61364 12.0888C6.19934 12.0888 5.8241 11.9822 5.48793 11.7692C5.15412 11.5537 4.88897 11.2377 4.69247 10.821C4.49834 10.402 4.40128 9.88826 4.40128 9.27983C4.40128 8.65483 4.50189 8.13518 4.70312 7.72088C4.90436 7.30421 5.17188 6.9929 5.50568 6.78693C5.84186 6.5786 6.20999 6.47443 6.61009 6.47443C6.91548 6.47443 7.16998 6.52652 7.37358 6.63068C7.57955 6.73248 7.74527 6.86032 7.87074 7.0142C7.99858 7.16572 8.09564 7.31487 8.16193 7.46165H8.2081V4.72727H9.71733V12H8.22585V11.1264H8.16193C8.09091 11.2779 7.99029 11.4283 7.86009 11.5774C7.73224 11.7242 7.56534 11.8461 7.35938 11.9432C7.15578 12.0402 6.9072 12.0888 6.61364 12.0888ZM7.09304 10.8849C7.33688 10.8849 7.54285 10.8187 7.71094 10.6861C7.88139 10.5511 8.0116 10.3629 8.10156 10.1214C8.19389 9.87997 8.24006 9.59706 8.24006 9.27273C8.24006 8.94839 8.19508 8.66667 8.10511 8.42756C8.01515 8.18845 7.88494 8.00379 7.71449 7.87358C7.54403 7.74337 7.33688 7.67827 7.09304 7.67827C6.84446 7.67827 6.63494 7.74574 6.46449 7.88068C6.29403 8.01562 6.16501 8.20265 6.07741 8.44176C5.98982 8.68087 5.94602 8.95786 5.94602 9.27273C5.94602 9.58996 5.98982 9.8705 6.07741 10.1143C6.16738 10.3558 6.2964 10.5452 6.46449 10.6825C6.63494 10.8175 6.84446 10.8849 7.09304 10.8849ZM11.8951 14.0455C11.7033 14.0455 11.5234 14.0301 11.3553 13.9993C11.1896 13.9709 11.0523 13.9342 10.9434 13.8892L11.2843 12.7599C11.4618 12.8144 11.6216 12.844 11.7637 12.8487C11.9081 12.8535 12.0324 12.8203 12.1365 12.7493C12.2431 12.6783 12.3295 12.5575 12.3958 12.3871L12.4846 12.1562L10.5279 6.54545H12.1188L13.248 10.5511H13.3049L14.4448 6.54545H16.0463L13.9263 12.5895C13.8245 12.883 13.686 13.1387 13.5108 13.3565C13.338 13.5767 13.119 13.746 12.8539 13.8643C12.5887 13.9851 12.2691 14.0455 11.8951 14.0455Z" fill="white"/>
<path d="M15.6136 25.0888C15.1993 25.0888 14.8241 24.9822 14.4879 24.7692C14.1541 24.5537 13.889 24.2377 13.6925 23.821C13.4983 23.402 13.4013 22.8883 13.4013 22.2798C13.4013 21.6548 13.5019 21.1352 13.7031 20.7209C13.9044 20.3042 14.1719 19.9929 14.5057 19.7869C14.8419 19.5786 15.21 19.4744 15.6101 19.4744C15.9155 19.4744 16.17 19.5265 16.3736 19.6307C16.5795 19.7325 16.7453 19.8603 16.8707 20.0142C16.9986 20.1657 17.0956 20.3149 17.1619 20.4616H17.2081V17.7273H18.7173V25H17.2259V24.1264H17.1619C17.0909 24.2779 16.9903 24.4283 16.8601 24.5774C16.7322 24.7242 16.5653 24.8461 16.3594 24.9432C16.1558 25.0402 15.9072 25.0888 15.6136 25.0888ZM16.093 23.8849C16.3369 23.8849 16.5429 23.8187 16.7109 23.6861C16.8814 23.5511 17.0116 23.3629 17.1016 23.1214C17.1939 22.88 17.2401 22.5971 17.2401 22.2727C17.2401 21.9484 17.1951 21.6667 17.1051 21.4276C17.0152 21.1884 16.8849 21.0038 16.7145 20.8736C16.544 20.7434 16.3369 20.6783 16.093 20.6783C15.8445 20.6783 15.6349 20.7457 15.4645 20.8807C15.294 21.0156 15.165 21.2027 15.0774 21.4418C14.9898 21.6809 14.946 21.9579 14.946 22.2727C14.946 22.59 14.9898 22.8705 15.0774 23.1143C15.1674 23.3558 15.2964 23.5452 15.4645 23.6825C15.6349 23.8175 15.8445 23.8849 16.093 23.8849ZM21.2253 19.5455L22.2267 21.4524L23.253 19.5455H24.8049L23.2246 22.2727L24.8475 25H23.3027L22.2267 23.1143L21.1685 25H19.606L21.2253 22.2727L19.6628 19.5455H21.2253Z" fill="white"/>
<line x1="6.81281" y1="22.7756" x2="21.9396" y2="7.02154" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

+6
View File
@@ -0,0 +1,6 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="15" cy="15" r="15" fill="#E34A4A"/>
<path d="M6.61364 12.0888C6.19934 12.0888 5.8241 11.9822 5.48793 11.7692C5.15412 11.5537 4.88897 11.2377 4.69247 10.821C4.49834 10.402 4.40128 9.88826 4.40128 9.27983C4.40128 8.65483 4.50189 8.13518 4.70312 7.72088C4.90436 7.30421 5.17188 6.9929 5.50568 6.78693C5.84186 6.5786 6.20999 6.47443 6.61009 6.47443C6.91548 6.47443 7.16998 6.52652 7.37358 6.63068C7.57955 6.73248 7.74527 6.86032 7.87074 7.0142C7.99858 7.16572 8.09564 7.31487 8.16193 7.46165H8.2081V4.72727H9.71733V12H8.22585V11.1264H8.16193C8.09091 11.2779 7.99029 11.4283 7.86009 11.5774C7.73224 11.7242 7.56534 11.8461 7.35938 11.9432C7.15578 12.0402 6.9072 12.0888 6.61364 12.0888ZM7.09304 10.8849C7.33688 10.8849 7.54285 10.8187 7.71094 10.6861C7.88139 10.5511 8.0116 10.3629 8.10156 10.1214C8.19389 9.87997 8.24006 9.59706 8.24006 9.27273C8.24006 8.94839 8.19508 8.66667 8.10511 8.42756C8.01515 8.18845 7.88494 8.00379 7.71449 7.87358C7.54403 7.74337 7.33688 7.67827 7.09304 7.67827C6.84446 7.67827 6.63494 7.74574 6.46449 7.88068C6.29403 8.01562 6.16501 8.20265 6.07741 8.44176C5.98982 8.68087 5.94602 8.95786 5.94602 9.27273C5.94602 9.58996 5.98982 9.8705 6.07741 10.1143C6.16738 10.3558 6.2964 10.5452 6.46449 10.6825C6.63494 10.8175 6.84446 10.8849 7.09304 10.8849ZM11.8951 14.0455C11.7033 14.0455 11.5234 14.0301 11.3553 13.9993C11.1896 13.9709 11.0523 13.9342 10.9434 13.8892L11.2843 12.7599C11.4618 12.8144 11.6216 12.844 11.7637 12.8487C11.9081 12.8535 12.0324 12.8203 12.1365 12.7493C12.2431 12.6783 12.3295 12.5575 12.3958 12.3871L12.4846 12.1562L10.5279 6.54545H12.1188L13.248 10.5511H13.3049L14.4448 6.54545H16.0463L13.9263 12.5895C13.8245 12.883 13.686 13.1387 13.5108 13.3565C13.338 13.5767 13.119 13.746 12.8539 13.8643C12.5887 13.9851 12.2691 14.0455 11.8951 14.0455Z" fill="white"/>
<path d="M15.6136 25.0888C15.1993 25.0888 14.8241 24.9822 14.4879 24.7692C14.1541 24.5537 13.889 24.2377 13.6925 23.821C13.4983 23.402 13.4013 22.8883 13.4013 22.2798C13.4013 21.6548 13.5019 21.1352 13.7031 20.7209C13.9044 20.3042 14.1719 19.9929 14.5057 19.7869C14.8419 19.5786 15.21 19.4744 15.6101 19.4744C15.9155 19.4744 16.17 19.5265 16.3736 19.6307C16.5795 19.7325 16.7453 19.8603 16.8707 20.0142C16.9986 20.1657 17.0956 20.3149 17.1619 20.4616H17.2081V17.7273H18.7173V25H17.2259V24.1264H17.1619C17.0909 24.2779 16.9903 24.4283 16.8601 24.5774C16.7322 24.7242 16.5653 24.8461 16.3594 24.9432C16.1558 25.0402 15.9072 25.0888 15.6136 25.0888ZM16.093 23.8849C16.3369 23.8849 16.5429 23.8187 16.7109 23.6861C16.8814 23.5511 17.0116 23.3629 17.1016 23.1214C17.1939 22.88 17.2401 22.5971 17.2401 22.2727C17.2401 21.9484 17.1951 21.6667 17.1051 21.4276C17.0152 21.1884 16.8849 21.0038 16.7145 20.8736C16.544 20.7434 16.3369 20.6783 16.093 20.6783C15.8445 20.6783 15.6349 20.7457 15.4645 20.8807C15.294 21.0156 15.165 21.2027 15.0774 21.4418C14.9898 21.6809 14.946 21.9579 14.946 22.2727C14.946 22.59 14.9898 22.8705 15.0774 23.1143C15.1674 23.3558 15.2964 23.5452 15.4645 23.6825C15.6349 23.8175 15.8445 23.8849 16.093 23.8849ZM21.2253 19.5455L22.2267 21.4524L23.253 19.5455H24.8049L23.2246 22.2727L24.8475 25H23.3027L22.2267 23.1143L21.1685 25H19.606L21.2253 22.2727L19.6628 19.5455H21.2253Z" fill="white"/>
<line x1="6.81281" y1="22.7756" x2="21.9396" y2="7.02154" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="15" cy="15" r="15" fill="#4597B1"/>
<path d="M15.0199 20.2131C14.8021 21.5199 14.3073 22.5213 13.5355 23.2173C12.7637 23.9134 11.7576 24.2614 10.517 24.2614C10.2424 24.2614 9.98911 24.2495 9.7571 24.2259C9.52036 24.2022 9.28835 24.1619 9.06108 24.1051L9.60085 21.7685C9.72396 21.7969 9.86127 21.8229 10.0128 21.8466C10.1643 21.8703 10.3442 21.8821 10.5526 21.8821C10.9976 21.8821 11.3456 21.759 11.5966 21.5128C11.8523 21.2713 12.0204 20.8949 12.1009 20.3835L13.9972 8.94886C14.2197 7.6089 14.7334 6.58144 15.5384 5.86648C16.3433 5.15151 17.392 4.79403 18.6847 4.79403C18.9356 4.79403 19.1889 4.81297 19.4446 4.85085C19.7003 4.884 19.9702 4.93845 20.2543 5.0142L19.6364 7.27983C19.4991 7.25142 19.3168 7.23011 19.0895 7.21591C18.867 7.2017 18.642 7.1946 18.4148 7.1946C17.9886 7.1946 17.6548 7.30824 17.4134 7.53551C17.1766 7.76278 17.018 8.1179 16.9375 8.60085L15.0199 20.2131Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1010 B

@@ -0,0 +1,4 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="15" cy="15" r="15" fill="#E34A4A"/>
<path d="M15.0199 20.2131C14.8021 21.5199 14.3073 22.5213 13.5355 23.2173C12.7637 23.9134 11.7576 24.2614 10.517 24.2614C10.2424 24.2614 9.98911 24.2495 9.7571 24.2259C9.52036 24.2022 9.28835 24.1619 9.06108 24.1051L9.60085 21.7685C9.72396 21.7969 9.86127 21.8229 10.0128 21.8466C10.1643 21.8703 10.3442 21.8821 10.5526 21.8821C10.9976 21.8821 11.3456 21.759 11.5966 21.5128C11.8523 21.2713 12.0204 20.8949 12.1009 20.3835L13.9972 8.94886C14.2197 7.6089 14.7334 6.58144 15.5384 5.86648C16.3433 5.15151 17.392 4.79403 18.6847 4.79403C18.9356 4.79403 19.1889 4.81297 19.4446 4.85085C19.7003 4.884 19.9702 4.93845 20.2543 5.0142L19.6364 7.27983C19.4991 7.25142 19.3168 7.23011 19.0895 7.21591C18.867 7.2017 18.642 7.1946 18.4148 7.1946C17.9886 7.1946 17.6548 7.30824 17.4134 7.53551C17.1766 7.76278 17.018 8.1179 16.9375 8.60085L15.0199 20.2131Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1010 B

@@ -10,6 +10,7 @@
<language-dropdown class="app-navbar-actions__item"/> -->
<license-check-button :ref="'license_check_button_ref'" @updateLicense="updateLicense"/>
<license-update-modal :title="'Update'" :ref="'license_update_modal_ref'" @refresh="refresh"/>
<va-button @click="reload" icon="fa fa-refresh" flat></va-button>
<profile-dropdown class="app-navbar-actions__item app-navbar-actions__item--profile">
<span>{{userName}}</span>
</profile-dropdown>
@@ -70,6 +71,9 @@ export default {
this.$refs.license_check_button_ref.refresh()
this.$refs.license_update_modal_ref.hide()
},
reload () {
window.location.reload(true)
},
},
}
</script>
@@ -61,6 +61,14 @@ export const navigationRoutes = {
iconClass: 'vuestic-iconset vuestic-iconset-settings',
},
},
{
name: 'project',
displayName: 'Scheduler',
meta: {
iconClass: 'vuestic-iconset vuestic-iconset-tables',
// iconClass: 'vuestic-iconset vuestic-iconset-browse-gallery',
},
},
// {
// name: 'forms',
// displayName: 'menu.forms',
@@ -26,7 +26,7 @@
<div class="flex sm12 xl12 md12 xs12">
<!-- <chart :style="'width: auto; height: 88vhvh;'" :option="options"></chart> -->
<elite-replay-overview-chart v-show="showOverviewChart" :ref="'chart_overview'" class="mb-1" :cardheight="'7vh'" :data="chartOverviewData" @dataZoomEvent="dataZoomEvent($event)"/>
<elite-replay-chart :ref="'chart_detail'" :cardheight="'88vh'" :chartheight="detailchartheight" :data="chartDetailData" @updateIntegralBoundary="updateIntegralBoundary" />
<elite-replay-chart :ref="'chart_detail'" :cardheight="'90vh'" :chartheight="detailchartheight" :data="chartDetailData" @updateIntegralBoundary="updateIntegralBoundary" />
<change-channel-value-min-max :ref="'set_min_max'"/>
</div>
</div>
@@ -79,6 +79,7 @@ export default {
'startTimeCurrent',
'endTimeCurrent',
'sampleMethod',
'controlPanel',
]),
},
props: {
@@ -223,6 +224,8 @@ export default {
channelY: ch,
})
})
// disable overviewData legend
this.chartOverviewData.legend.show = false
this.chartDetailData.xAxis[_gridNumber].axisLabel.show = true
if (this.maxTime < parseInt(meta.time_duration)) {
this.maxTime = parseInt(meta.time_duration)
@@ -371,16 +374,14 @@ export default {
this.hideChartLoading()
},
drawDetailData: async function () {
var panelInfo = this.$refs.top_control_panel.getPanelInfo()
// brush setting write at here, due to mounted won't show the brush
this.chartDetailData.brush = {
toolbox: ['rect', 'clear'],
// toolbox: ['rect', 'polygon', 'lineX', 'lineY', 'keep', 'clear'],
xAxisIndex: 0,
// throttleType: 'debounce',
// throttleDelay: 5,
throttleType: 'debounce',
throttleDelay: 0,
}
console.log('panelInfo: ', panelInfo) // TODO: update the formatter for tooltips
this.showChartLoading('detail')
const timeDur = this.endTimeCurrent - this.startTimeCurrent
let _gridNumber = 0
@@ -393,7 +394,7 @@ export default {
})
let scale = '1'
if (this.axisXDataType.description === 'Time') {
if (this.controlPanel.x.axis.description === 'Time') {
scale = await this.computeResampleScale(metaInfo, timeDur)
}
// elite的sample rate不像neulive這麼高,因此試試scale = 100 or 1000時不要再sampling一次了,不然有些形狀(e.g. peak)會不一樣
@@ -412,11 +413,11 @@ export default {
this.currentScale = scale
this.chartDetailData.series[_gridNumber].data.length = 0
let dataListX
const channelX = parseInt(this.axisXDataType.id)
if (this.axisXDataType.description !== 'Time') {
const channelX = parseInt(this.controlPanel.x.axis.channel)
if (this.controlPanel.x.axis.description !== 'Time') {
dataListX = this.dataInfo[meta][channelX][scale]
}
const channelY = parseInt(this.axisYDataType.id)
const channelY = parseInt(this.controlPanel.y.axis.channel)
const dataListY = this.dataInfo[meta][channelY][scale]
const isThisModeHasCycle = this.GLOBAL.hasCycleMode(metaInfo.parameter_set.MODE, metaInfo.device.library_name)
@@ -463,7 +464,7 @@ export default {
for (let i = startIndex; i <= endIndex; i++) {
const data = await this.getData(parseInt(scale), this.sampleMethod, dataListY[i].id, channelY, metaInfo)
let dataX
if (this.axisXDataType.description !== 'Time') {
if (this.controlPanel.x.axis.description !== 'Time') {
dataX = await this.getData(parseInt(scale), this.sampleMethod, dataListX[i].id, channelX, metaInfo)
}
var deltaX = 0
@@ -565,7 +566,7 @@ export default {
}
}
if (this.axisXDataType.description === 'Time') {
if (this.controlPanel.x.axis.description === 'Time') {
this.chartDetailData.xAxis[_gridNumber].min = _startTime
this.chartDetailData.xAxis[_gridNumber].max = _endTime
} else {
@@ -575,7 +576,7 @@ export default {
_gridNumber += 1
}
if (this.axisXDataType.description !== 'Time') {
if (this.controlPanel.x.axis.description !== 'Time') {
this.showOverviewChart = false
this.detailchartheight = '88vh'
// this.$refs.chart_detail.updateChartHeight()
@@ -607,33 +608,65 @@ export default {
}
},
changeAxis (gridIndex) {
// if (this.initDone) {
// const libName = this.metaList[gridIndex].device.library_name
// let xType
// let xValue
// if (this.axisXDataType.description === 'Time') {
// xType = 'Time'
// } else {
// if (libName === 'EliteZM15' || libName.includes('Elite_EDC')) {
// xType = 'Elite'
// } else if (libName.includes('EIS')) {
// xType = 'EliteEIS'
// }
// xValue = this.axisXDataType.id + 1
// }
// this.updateRegisteredChart({
// chartAllData: this.chartData,
// chartID: this.chartDetailData.chartID,
// gridIndex: gridIndex,
// deviceNameX: xType,
// deviceIDX: this.metaList[gridIndex].name,
// channelX: xValue,
// deviceNameY: libName.includes('EIS') ? 'EliteEIS' : 'Elite',
// deviceIDY: '',
// channelY: this.axisYDataType.id + 1,
// })
// console.log({
// chartAllData: this.chartData,
// chartID: this.chartDetailData.chartID,
// gridIndex: gridIndex,
// deviceNameX: xType,
// deviceIDX: this.metaList[gridIndex].name,
// channelX: xValue,
// deviceNameY: libName.includes('EIS') ? 'EliteEIS' : 'Elite',
// deviceIDY: '',
// channelY: this.axisYDataType.id + 1,
// })
// }
// if (this.axisXDataType.description === 'Time') {
// this.drawOverviewData()
// }
// this.drawDetailData() // reDraw
// tang
if (this.initDone) {
const libName = this.metaList[gridIndex].device.library_name
let xType
let xValue
if (this.axisXDataType.description === 'Time') {
xType = 'Time'
} else {
if (libName === 'EliteZM15' || libName.includes('Elite_EDC')) {
xType = 'Elite'
} else if (libName.includes('EIS')) {
xType = 'EliteEIS'
}
xValue = this.axisXDataType.id + 1
}
const xType = (this.controlPanel.x.axis.description === 'Time') ? 'Time' : ((libName === 'EliteZM15' || libName.includes('Elite_EDC') ? 'Elite' : 'EliteEIS'))
const xChannel = (this.controlPanel.x.axis.channel === -1) ? undefined : this.controlPanel.x.axis.channel + 1
this.updateRegisteredChart({
chartAllData: this.chartData,
chartID: this.chartDetailData.chartID,
gridIndex: gridIndex,
deviceNameX: xType,
deviceIDX: this.metaList[gridIndex].name,
channelX: xValue,
channelX: xChannel,
deviceNameY: libName.includes('EIS') ? 'EliteEIS' : 'Elite',
deviceIDY: '',
channelY: this.axisYDataType.id + 1,
channelY: this.controlPanel.y.axis.channel + 1,
})
}
if (this.axisXDataType.description === 'Time') {
if (this.controlPanel.x.axis.description === 'Time') {
this.drawOverviewData()
}
this.drawDetailData() // reDraw
@@ -656,7 +689,7 @@ export default {
}
if (rawData[prevIndex][0] >= boundary.x_start && rawData[prevIndex][0] <= boundary.x_end &&
rawData[index][0] >= boundary.x_start && rawData[index][0] <= boundary.x_end) {
deltaX = Number(rawData[index][0]) - Number(rawData[prevIndex][0])
deltaX = Math.abs(Number(rawData[index][0]) - Number(rawData[prevIndex][0]))
if (rawData[index][1] > boundary.y_end) rawData[index][1] = boundary.y_end
else if (rawData[index][1] < boundary.y_start) {
continue
@@ -107,14 +107,14 @@ export default {
async mounted () {
this.resizeTimer = setInterval(this.resize, 1000)
// brush set at here won't work
/* this.data.brush = {
this.data.brush = {
toolbox: ['rect', 'polygon', 'lineX', 'lineY', 'keep', 'clear'],
xAxisIndex: 0,
throttleType: 'debounce',
throttleDelay: 5,
} */
throttleDelay: 0,
}
this.$refs.chart_ref.chart.on('brushSelected', (params) => {
if (params.batch[0].areas.length !== 0) {
if (params.batch[0] && params.batch[0].areas.length !== 0) {
var boundary = {
x_start: Number(params.batch[0].areas[0].coordRange[0][0].toFixed(4)),
x_end: Number(params.batch[0].areas[0].coordRange[0][1].toFixed(4)),
@@ -12,58 +12,66 @@
<delete-file />
</div>
</div>
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0">
<p class="display-6"> X-axis </p>
<p class="display-6"> X-Axis </p>
</div>
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<change-axis :ref="'change_axis_x'" axis="x" @changeAxis="changeAxis" @changeUnit="changeUnit" @clearCycle="clearCycle"/>
<control-axis
:ref="'axis_x'"
coordinate="x"
@changeAxis="changeAxis"
/>
</div>
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<change-unit :ref="'change_unit_x'" axis="x" @refreshChart="refreshChart"/>
<control-unit
:ref="'unit_x'"
coordinate="x"
@changeUnit="changeUnit"
style="width: 75px;"
/>
</div>
</div>
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0" />
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<change-scale :ref="'change_scale_x'" axis="x" @refreshChart="refreshChart" @clearCycle="clearCycle" @changeAxis="changeAxis" @changeFunctional="changeFunctional"/>
</div>
<div class="flex sm5 xl5 md5 xs5 px-0 py-0">
<abs-toggle :ref="'abs_x'" axis="x" @changeAxis="changeAxis"/>
<control-funct
:ref="'funct_x'"
coordinate="x"
@changeFunct="changeFunct"
/>
</div>
</div>
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0">
<p class="display-6"> Y-axis </p>
<p class="display-6"> Y-Axis </p>
</div>
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<change-axis :ref="'change_axis_y'" axis="y" @changeAxis="changeAxis" @changeUnit="changeUnit" @clearCycle="clearCycle"/>
<control-axis
:ref="'axis_y'"
coordinate="y"
@changeAxis="changeAxis"
/>
</div>
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<change-unit :ref="'change_unit_y'" axis="y" @refreshChart="refreshChart"/>
<control-unit
:ref="'unit_y'"
coordinate="y"
@changeUnit="changeUnit"
style="width: 75px;"
/>
</div>
</div>
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0" />
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<change-scale :ref="'change_scale_y'" axis="y" @refreshChart="refreshChart" @clearCycle="clearCycle" @changeAxis="changeAxis" @changeFunctional="changeFunctional"/>
</div>
<div class="flex sm5 xl5 md5 xs5 px-0 py-0">
<abs-toggle :ref="'abs_y'" axis="y" @changeAxis="changeAxis"/>
<control-funct
:ref="'funct_y'"
coordinate="y"
@changeFunct="changeFunct"/>
</div>
</div>
<!-- <va-button @click="switchCollapse"></va-button>
<va-collapse class="mb-2" :isOpenDefault="false" v-model="innerCollapse">
<span slot="header">Specific Integral</span>
<div slot="body">
<div>
<specific-integral :ref="'specific_integral'" @setBrushBoundary="setBrushBoundary" />
</div>
</div>
</va-collapse> -->
<specific-integral :ref="'specific_integral'" @setBrushBoundary="setBrushBoundary" />
<specific-integral :ref="'specific_integral'" @setBrushBoundary="setBrushBoundary"/>
<div class="flex-container mb-2">
<div class="flex sm10 xl10 md10 xs10 px-0 py-0">
<change-window-start-and-size :ref="'change_window_start_and_size'" @changeOverviewDataZoom="changeOverviewDataZoom"/>
@@ -81,11 +89,10 @@
<script>
import ShowResampleRate from '@/components/analysis/replay/toolbox/ShowResampleRate.vue'
import ChangeAxis from '@/components/analysis/replay/toolbox/ChangeAxis.vue'
import ChangeUnit from '@/components/analysis/replay/toolbox/ChangeUnit.vue'
import ChangeScale from '@/components/analysis/replay/toolbox/ChangeScale.vue'
import controlAxis from '@/components/analysis/replay/toolbox/ControlAxis'
import controlUnit from '@/components/analysis/replay/toolbox/ControlUnit'
import controlFunct from '@/components/analysis/replay/toolbox/ControlFunct'
import ChangeCycle from '@/components/analysis/replay/toolbox/ChangeCycle.vue'
import AbsToggle from '@/components/analysis/replay/toolbox/AbsToggle.vue'
import SpecificIntegral from '@/components/analysis/replay/toolbox/SpecificIntegral.vue'
import DownloadFile from '@/components/analysis/replay/toolbox/DownloadFile.vue'
import DeleteFile from '@/components/analysis/replay/toolbox/DeleteFile.vue'
@@ -93,17 +100,20 @@ import EditFileName from '@/components/analysis/replay/toolbox/EditFileName.vue'
import ShowParameter from '@/components/analysis/replay/toolbox/ShowParameter.vue'
import LockDataZoom from '@/components/analysis/replay/toolbox/LockDataZoom.vue'
import ChangeWindowStartAndSize from '@/components/analysis/replay/toolbox/ChangeWindowStartAndSize.vue'
import { mapMutations } from 'vuex'
import { mapFields } from 'vuex-map-fields'
import { tableRouter } from '@/components/analysis/replay/toolbox/EliteReplayTable'
import configRouter from '@/components/analysis/replay/toolbox/configTable'
import types from '@/store/modules/analysis/replay/types'
export default {
name: 'top-control-panel',
components: {
ShowResampleRate,
ChangeAxis,
ChangeUnit,
ChangeScale,
controlAxis,
controlUnit,
controlFunct,
ChangeCycle,
AbsToggle,
SpecificIntegral,
DownloadFile,
DeleteFile,
@@ -114,38 +124,93 @@ export default {
},
computed: {
...mapFields('replay', [
'chartData',
'metaList',
'showCyclePanel',
'controlPanel',
]),
},
props: {
},
async created () {
},
data () {
return {
deviceName: '',
libraryName: '',
showCycle: false,
innerCollapse: false,
tableRouter,
configRouter,
}
},
mqtt: {
},
methods: {
...mapMutations('replay', [types.chart.updateAxisLabel]),
// initialize control buttons
init () {
this.deviceName = this.metaList[0].device.library_name
this.$refs.change_unit_x.init(this.deviceName)
this.$refs.change_unit_y.init(this.deviceName)
this.$refs.change_axis_x.init(this.deviceName)
this.$refs.change_axis_y.init(this.deviceName)
this.$refs.change_scale_x.init(this.deviceName)
this.$refs.change_scale_y.init(this.deviceName)
this.$refs.abs_x.init(this.deviceName)
this.$refs.abs_y.init(this.deviceName)
// get config information
this.libraryName = this.metaList[0].device.library_name
const setting = this.GLOBAL.getDefaultChartTypeByMode(this.metaList[0].parameter_set.MODE, this.libraryName)
this.controlPanel.x.axis = this.configRouter.getAxis(this.libraryName, setting[0], setting[1])
this.controlPanel.y.axis = this.configRouter.getAxis(this.libraryName, setting[2], setting[3])
this.controlPanel.FSM = this.configRouter.getFSM(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
// initialize other blocks
this.$refs.axis_x.init(this.libraryName, setting[0])
this.$refs.axis_y.init(this.libraryName, setting[2])
this.$refs.unit_x.init(this.controlPanel.x.axis.description)
this.$refs.unit_y.init(this.controlPanel.y.axis.description)
this.$refs.funct_x.init(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
this.$refs.funct_y.init(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
this.$refs.change_cycle.init()
this.$refs.edit_file_name.init()
this.$refs.show_param.init(this.deviceName)
this.$refs.show_param.init(this.libraryName)
this.$refs.change_window_start_and_size.init()
this.refreshFormatter('x')
this.refreshFormatter('y')
this.$emit('changeFunctional', 'x', 'Linear')
this.$emit('changeFunctional', 'y', 'Linear')
this.$emit('changeAxis', 0)
this.$refs.specific_integral.checkMeaning(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
this.$refs.specific_integral.setDisplayParam(this.controlPanel.x.axis.description, this.controlPanel.x.unit, this.controlPanel.y.axis.description, this.controlPanel.y.unit)
},
/* changeXXX: activate when pressing XXX button */
// trigger when changing the axis type
changeAxis (gridIndex) {
this.controlPanel.FSM = this.configRouter.getFSM(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
// initialize other blocks
this.$refs.unit_x.init(this.controlPanel.x.axis.description)
this.$refs.unit_y.init(this.controlPanel.y.axis.description)
this.$refs.funct_x.init(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
this.$refs.funct_y.init(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
this.$refs.change_cycle.init()
this.refreshFormatter('x')
this.refreshFormatter('y')
this.$emit('changeFunctional', 'x', 'Linear')
this.$emit('changeFunctional', 'y', 'Linear')
this.$emit('changeAxis', gridIndex)
this.$refs.specific_integral.checkMeaning(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
this.$refs.specific_integral.setDisplayParam(this.controlPanel.x.axis.description, this.controlPanel.x.unit, this.controlPanel.y.axis.description, this.controlPanel.y.unit)
},
// trigger when changing the unit
changeUnit (coordinate) {
this.refreshFormatter(coordinate)
this.$refs.specific_integral.refreshDisplayParam(this.controlPanel.x.axis.description, this.controlPanel.x.unit, this.controlPanel.y.axis.description, this.controlPanel.y.unit)
},
// trigger when press the functional button
changeFunct (coordinate) {
if (coordinate === 'y') {
this.controlPanel.y.axis.description = this.controlPanel.FSM[this.controlPanel.y.funct]
this.$refs.unit_y.init(this.controlPanel.y.axis.description)
this.$refs.specific_integral.checkMeaning(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
this.refreshFormatter(coordinate)
}
this.$emit('changeFunctional', coordinate, this.controlPanel[coordinate].funct)
this.$emit('changeAxis', 0)
},
/* refreshXXX: passively called by changeXXX function to refresh some setting */
// refresh all formatters of charts
refreshFormatter (coordinate) {
this.updateAxisLabelChart({
chartID: 1,
axis: coordinate,
type: this.controlPanel[coordinate].axis.description,
axisIndex: 0,
})
},
changeOverviewDataZoom () {
this.$emit('changeOverviewDataZoom')
@@ -153,43 +218,12 @@ export default {
refreshChart (options) {
this.$emit('refreshChart', options)
},
changeFunctional (axis, functional) {
this.$emit('changeFunctional', axis, functional)
},
changeAxis (gridIndex) {
this.$emit('changeAxis', gridIndex)
},
changeUnit (axis) {
if (axis === 'x') {
this.$refs.change_unit_x.changeUnitByAxis()
} else if (axis === 'y') {
this.$refs.change_unit_y.changeUnitByAxis()
}
},
getPanelInfo () {
var panelInfo = {
axis_x: this.$refs.change_axis_x.getChannelByAxis(),
axis_y: this.$refs.change_axis_y.getChannelByAxis(),
scale_x: this.$refs.change_scale_x.getScaleByAxis(),
scale_y: this.$refs.change_scale_y.getScaleByAxis(),
unit_x: this.$refs.change_unit_x.getUnitByAxis(),
unit_y: this.$refs.change_unit_y.getUnitByAxis(),
}
// console.log('panelInfo: ', panelInfo)
return panelInfo
},
clearCycle () {
this.$refs.change_cycle.clear()
},
setBrushBoundary (boundary) {
this.$emit('setBrushBoundary', boundary)
},
/* switchCollapse () {
this.innerCollapse = this.innerCollapse ? false : true
console.log(this.innerCollapse)
}, */
},
mounted () {
},
}
</script>
@@ -46,7 +46,7 @@ export default {
},
computed: {
...mapFields('', [
'developer_mode',
'developerMode',
]),
...mapFields('taskContent', [
'chartData',
@@ -49,7 +49,9 @@ export default {
'axisYDataType',
'axisXLabelScale',
'axisYLabelScale',
'showCyclePanel',
'showWhichCycles',
'controlPanel',
]),
},
watch: {
@@ -76,21 +78,20 @@ export default {
return sortedCycleList
},
init () {
this.showWhichCycles = '1'
this.cycleNum = this.metaList[this.metaIndex].parameter_set.CYCLE_NUMBER
const meta = this.metaList[this.metaIndex]
this.metaID = meta.id
this.isThisModeHasCycle = this.GLOBAL.hasCycleMode(this.metaList[this.metaIndex].parameter_set.MODE, meta.device.library_name)
if (this.isThisModeHasCycle === true) {
this.showCyclePanel = true
this.showPanel = true
} else {
this.showCyclePanel = false
this.showPanel = false
}
},
clear () {
this.showWhichCycles = '1'
},
async setCycle () {
console.log('setCycle')
if (this.isThisModeHasCycle === true) {
const dataCycleList = this.recInfo[this.metaID][this.cycleDataID][this.currentScale]
const cycleDataList = []
@@ -105,15 +106,14 @@ export default {
const cycleDict = this.getCycleDictRec()(cycleDataList)
this.cycleNum = Object.keys(cycleDict).length
let dataXList
if (this.axisXDataType.description !== 'Time') {
dataXList = this.recInfo[this.metaID][this.axisXDataType.id][this.currentScale]
if (this.controlPanel.x.axis.description !== 'Time') {
dataXList = this.recInfo[this.metaID][this.controlPanel.x.axis.channel][this.currentScale]
}
const dataYList = this.recInfo[this.metaID][this.axisYDataType.id][this.currentScale]
const dataYList = this.recInfo[this.metaID][this.controlPanel.y.axis.channel][this.currentScale]
const filteredData = []
let counter = 0
for (let sliceIndex = 0; sliceIndex < this.cycleNum; sliceIndex++) {
// console.log(this.slices)
if (this.slices() === '' || this.slices().includes((sliceIndex + 1).toString())) {
// slice data
const value = cycleDict[sliceIndex + 1]
@@ -129,36 +129,18 @@ export default {
endIndex = i
}
}
for (let i = startIndex; i <= endIndex; i++) {
const dataY = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataYList[i].id, this.axisYDataType.id, this.metaList[this.metaIndex])
if (this.axisXDataType.description !== 'Time') {
const dataX = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataXList[i].id, this.axisXDataType.id, this.metaList[this.metaIndex])
const dataY = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataYList[i].id, this.controlPanel.y.axis.channel, this.metaList[this.metaIndex])
if (this.controlPanel.x.axis.description !== 'Time') {
const dataX = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataXList[i].id, this.controlPanel.x.axis.channel, this.metaList[this.metaIndex])
for (let j = 0, len = dataY.length; j < len; j++) {
if (parseInt(dataY[j][0]) >= startTime && parseInt(dataY[j][0]) <= endTime) {
let x
let y
if (this.axisXLabelScale.description === 'Log') {
x = Math.abs(dataX[j][1])
} else if (this.axisXLabelScale.description === 'Linear') {
x = dataX[j][1]
}
if (this.axisYLabelScale.description === 'Log') {
y = Math.abs(dataY[j][1])
} else if (this.axisYLabelScale.description === 'Linear') {
y = dataY[j][1]
}
filteredData.push([x, y])
filteredData.push([dataX[j][1], dataY[j][1]])
}
}
} else {
for (let j = 0, len = dataY.length; j < len; j++) {
if (parseInt(dataY[j][0]) >= startTime && parseInt(dataY[j][0]) <= endTime) {
if (this.axisYLabelScale.description === 'Log') {
dataY[j][1] = Math.abs(dataY[j][1])
} else if (this.axisYLabelScale.description === 'Linear') {
// do nothing
}
filteredData.push(dataY[j])
}
}
@@ -170,14 +152,13 @@ export default {
seriesIndex: this.metaIndex,
data: filteredData,
})
if (this.axisXDataType.description === 'Time') {
if (this.controlPanel.x.axis.description === 'Time') {
if (counter === 0) {
this.chartData[this.chartID].xAxis[this.metaIndex].min = startTime
}
this.chartData[this.chartID].xAxis[this.metaIndex].max = endTime
counter++
}
// this.$emit('refreshChart', this.chartData[this.chartID])
}
}
}
@@ -196,11 +177,6 @@ export default {
...mapMutations('replay', [types.chart.updateSeries]),
...mapGetters('replay', [types.rec.getCycleDict]),
},
mounted () {
},
destroyed () {
},
}
</script>
@@ -0,0 +1,56 @@
<template>
<div>
<va-select
v-model="controlPanel[coordinate].axis"
class="va-select-without-margin"
:options="axisOption"
text-by="description"
key-by="description"
:noClear='true'
@input="changeAxis()"
/>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
import { tableRouter } from '@/components/analysis/replay/toolbox/EliteReplayTable'
import configRouter from '@/components/analysis/replay/toolbox/configTable'
export default {
name: 'controlAxis',
props: {
coordinate: {
type: String, // x or y
},
},
data () {
return {
axisOption: [],
tableRouter,
configRouter,
}
},
computed: {
...mapFields('replay', [
'controlPanel',
]),
},
methods: {
init (library, settingType) {
this.axisOption = this.configRouter.getAxisOption(library, settingType, this.coordinate)
},
changeAxis () {
this.$emit('changeAxis', 0)
},
},
}
</script>
<style lang="scss">
.va-select-without-margin {
.va-select {
margin-bottom: 0;
}
}
</style>
@@ -0,0 +1,50 @@
<template>
<div class="flex row">
<va-radio-button
v-for="(funct, index) in functOption"
v-model="controlPanel[coordinate].funct"
:key="index"
:option="funct"
@input="changeFunct()"
/>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
import { tableRouter } from '@/components/analysis/replay/toolbox/EliteReplayTable'
import configRouter from '@/components/analysis/replay/toolbox/configTable'
export default {
name: 'controlFunct',
props: {
coordinate: {
type: String, // x or y
},
},
data () {
return {
funct: '',
functOption: [],
tableRouter,
configRouter,
}
},
computed: {
...mapFields('replay', [
'controlPanel',
]),
},
methods: {
init (xAxis, yAxis) {
this.controlPanel[this.coordinate].funct = 'Linear'
this.functOption = this.configRouter.getFunctOption(xAxis, yAxis, this.coordinate)
},
changeFunct () {
this.$emit('changeFunct', this.coordinate)
},
},
}
</script>
@@ -0,0 +1,57 @@
<template>
<div>
<va-select
v-model="controlPanel[coordinate].unit"
class="va-select-without-margin"
:options="unitOption"
:noClear='true'
@input="changeUnit()"
/>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
import { tableRouter } from '@/components/analysis/replay/toolbox/EliteReplayTable'
import configRouter from '@/components/analysis/replay/toolbox/configTable'
export default {
name: 'controlUnit',
props: {
coordinate: {
type: String, // x or y
},
},
data () {
return {
unit: '',
unitOption: [],
tableRouter,
configRouter,
}
},
computed: {
...mapFields('replay', [
'controlPanel',
]),
},
methods: {
init (axis) {
this.controlPanel[this.coordinate].unit = this.configRouter.getUnit(axis)
this.unitOption = this.configRouter.getUnitOption(axis)
},
changeUnit () {
this.$emit('changeUnit', this.coordinate)
},
},
}
</script>
<style lang="scss">
.va-select-without-margin {
.va-select {
margin-bottom: 0;
}
}
</style>
@@ -0,0 +1,209 @@
// library definition
// const libraryInfo = {
// EDC: {
// x: ['Time',
// 'Current',
// 'Voltage',
// 'Resistance',
// ],
// y: ['Current',
// 'Voltage',
// 'Resistance',
// ],
// },
// }
// axis information
const axisInfo = {
// axis type
Time: {
name: 'Time',
channel: -1,
option: {
auto: 1,
},
defaultUnit: 'auto',
downloadUnit: 'auto',
},
Current: {
name: 'Current',
channel: 0,
option: {
nA: 1,
uA: 1e3,
mA: 1e6,
A: 1e9,
},
defaultUnit: 'mA',
downloadUnit: 'A',
},
Voltage: {
name: 'Voltage',
channel: 1,
option: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'V',
},
Resistance: {
name: 'Resistance',
channel: 2,
option: {
: 1,
Ω: 1e3,
: 1e6,
: 1e9,
},
defaultUnit: 'Ω',
downloadUnit: 'Ω',
},
Cycle: {
name: 'Cycle',
channel: 3,
option: {
cycle: 1,
},
defaultUnit: 'cycle',
downloadUnit: 'cycle',
},
Charge: {
name: 'Charge',
channel: -1,
option: {
nAh: 3600 * 1e6,
uAh: 1600 * 1e9,
mAh: 3600 * 1e12,
Ah: 3600 * 1e15,
},
defaultUnit: 'mAh',
downloadUnit: 'mAh',
},
Power: {
name: 'Power',
channel: -1,
option: {
mW: 1e12,
W: 1e15,
kW: 1e18,
},
defaultUnit: 'W',
downloadUnit: 'W',
},
Transconductance: {
name: 'Transconductance',
channel: -1,
option: {
'mA/V': 1,
'A/V': 1e3,
'kA/V': 1e6,
},
defaultUnit: 'A/V',
downloadUnit: 'A/V',
},
Impedance: {
name: 'Impedance',
chanel: 6,
option: {
: 1e-3,
Ω: 1,
: 1e3,
: 1e6,
},
downloadUnit: 'Ω',
defaultUnit: 'Ω',
},
None: {
name: 'not support',
channel: -1,
option: {
none: 1,
},
defaultUnit: 'none',
downloadUnit: 'none',
},
}
export const tableRouter = {
getChannel: (axis) => {
return axisInfo[axis].channel
},
getDefaultUnit: (axis) => {
return axisInfo[axis].defaultUnit
},
getOption: (axis) => {
return axisInfo[axis].option
},
getTable: (xAxis, xFunct, yAxis, yFunct) => {
var xTable = axisInfo[xAxis]
var yTable = axisInfo.None
if (yFunct === 'Linear' || yFunct === 'Log') {
yTable = axisInfo[yAxis]
} else if (yFunct === 'Integral') {
if (xAxis === 'Time' && yAxis === 'Current') {
yTable = axisInfo.Charge
} else if (xAxis === 'Current' && yAxis === 'Voltage') {
yTable = axisInfo.Power
} else if (xAxis === 'Voltage' && yAxis === 'Current') {
yTable = axisInfo.Power
}
} else if (yFunct === 'Differential') {
if (xAxis === 'Current' && yAxis === 'Voltage') {
yTable = axisInfo.Resistance
} else if (xAxis === 'Voltage' && yAxis === 'Current') {
yTable = axisInfo.Transconductance
}
}
return [xTable, yTable]
},
getFunct (xAxis, yAxis, axis) {
let xTable = ['']
let yTable = ['']
if (xAxis === 'Time') {
xTable = ['Linear']
if (yAxis === 'Current') {
yTable = ['Linear', 'Log', 'Integral']
} else {
yTable = ['Linear', 'Log']
}
} else {
xTable = ['Linear', 'Log']
if ((xAxis === 'Voltage' && yAxis === 'Current') || (xAxis === 'Current' && yAxis === 'Voltage')) {
yTable = ['Linear', 'Log', 'Integral', 'Differential']
} else {
yTable = ['Linear', 'Log']
}
}
if (axis === 'x') return xTable
else return yTable
},
// axisLabel formatter
autoTimeFormatter (val) {
let label = ''
const hour = parseInt(val / 3.6e9)
const minute = parseInt((val % 3.6e9) / 1000000 / 60)
const second = parseInt((val % 6e7) / 1000000)
const millisecond = parseInt((val % 1e6) / 1000)
if (hour > 0) {
label += hour + ' h '
}
if (minute > 0) {
label += minute + ' m '
}
if (second > 0) {
label += second + ' s '
}
if (millisecond > 0) {
label += millisecond + ' ms '
}
if (hour === 0 && minute === 0 && second === 0 && millisecond === 0) {
label += ' 0 ms '
}
return label
},
}
@@ -1,171 +1,177 @@
<template>
<div>
<div class="flex-container mb-2">
<va-input
v-model="this.specificIntegral"
:label="$t('Specific Integral')"
/>
<div class="flex sm5 xl5 md5 xs5 px-0 py-0">
<va-button
v-if="!keyBoundary"
v-model="this.keyBoundary"
@click="switchBoundary()"
class="round-button px-1 py-1"
>
Draw
</va-button>
<va-button
v-if="keyBoundary"
v-model="this.keyBoundary"
@click="switchBoundary()"
class="round-button px-1 py-1"
>
Input
</va-button>
<div class="flex sm2 xl2 md2 xs2 px-0 py-0">
<p class="display-6" v-if="ifMeaning"> Area </p>
</div>
<div
class="row flex sm10 xl10 md10 xs10"
v-show="ifMeaning"
>
<div class="xs6 sm6 lg6 xl6">
<va-input
v-model="specificIntegral"
label="Integral value"
disabled
>
<p slot="append" style="margin-right: 0;" small>
{{ integralResult }}
</p>
</va-input>
</div>
<div class="xs2 sm2 lg2 xl2">
<va-select
v-model="integralUnit"
:options="integralOption"
@input="refreshScale"
style="width: 75px;"
class="va-select-without-margin"
noClear
/>
</div>
</div>
</div>
<div v-if="!keyBoundary">
<div>
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0" />
<div class="flex sm2 xl2 md2 xs2 px-0 py-0">
<p class="display-6"> Range </p>
</div>
<va-input
v-model="this.boundary.x_start"
:label="$t('X Start')"
/>
v-model="x_start"
label="X Start"
@focus="userEnter()"
@blur="userEnter()"
@keyup.enter="setBrushBoundary"
>
<p slot="append" style="margin-right: 0;" small>
{{ xUnit }}
</p>
</va-input>
<va-input
v-model="this.boundary.x_end"
:label="$t('X End')"
/>
v-model="x_end"
label="X End"
@focus="userEnter()"
@blur="userEnter()"
@keyup.enter="setBrushBoundary"
>
<p slot="append" style="margin-right: 0;" small>
{{ xUnit }}
</p>
</va-input>
</div>
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0" />
<div class="flex sm2 xl2 md2 xs2 px-0 py-0">
</div>
<va-input
v-model="this.boundary.y_start"
:label="$t('Y Start')"
/>
v-model="y_start"
label="Y Start"
@focus="userEnter()"
@blur="userEnter()"
@keyup.enter="setBrushBoundary"
>
<p slot="append" style="margin-right: 0;" small>
{{ yUnit }}
</p>
</va-input>
<va-input
v-model="this.boundary.y_end"
:label="$t('Y End')"
/>
</div>
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0" />
<va-button class="mb-2" @click="setBrushBoundary" small>
Set Integral Boundary
</va-button>
</div>
</div>
<div v-if="keyBoundary">
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0" />
<va-input
@keyup.enter="setBrushBoundary()"
@blur="setBrushBoundary()"
v-model="boundaryXstart"
:label="$t('X Start')"
/>
<va-input
@keyup.enter="setBrushBoundary()"
@blur="setBrushBoundary()"
v-model="boundaryXend"
:label="$t('X End')"
/>
</div>
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0" />
<va-input
@keyup.enter="setBrushBoundary()"
@blur="setBrushBoundary()"
v-model="boundaryYstart"
:label="$t('Y Start')"
/>
<va-input
@keyup.enter="setBrushBoundary()"
@blur="setBrushBoundary()"
v-model="boundaryYend"
:label="$t('Y End')"
/>
</div>
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0" />
<va-button class="mb-2" @click="setBrushBoundary" small>
Set Integral Boundary
</va-button>
v-model="y_end"
label="Y End"
@focus="userEnter()"
@blur="userEnter()"
@keyup.enter="setBrushBoundary"
>
<p slot="append" style="margin-right: 0;" small>
{{ yUnit }}
</p>
</va-input>
</div>
</div>
</div>
</template>
<script>
import { tableRouter } from '@/components/analysis/replay/toolbox/EliteReplayTable'
import configRouter from '@/components/analysis/replay/toolbox/configTable'
export default {
name: 'SpecificIntegral',
components: {
},
computed: {
displayType () {
return {
x: this.axisXLabelScale.description === 'Log' ? 'log' : 'value',
y: this.axisYLabelScale.description === 'Log' ? 'log' : 'value',
}
},
},
props: {
},
created () {
},
data () {
return {
specificIntegral: 0,
boundary: {},
boundaryXstart: 0,
boundaryXend: 0,
boundaryYstart: 0,
boundaryYend: 0,
keyBoundary: false,
x_start: 0,
x_end: 0,
y_start: 0,
y_end: 0,
xUnit: '',
yUnit: '',
xScale: '',
yScale: '',
integralResult: '',
integralUnit: '',
integralOption: [],
integralTable: {},
integralScale: '',
ifMeaning: true,
ifUserKeyIn: false,
tableRouter,
configRouter,
}
},
mqtt: {
},
methods: {
refreshScale () {
this.integralScale = this.configRouter.getUnitScale(this.integralResult)[this.integralUnit]
},
userEnter () {
this.ifUserKeyIn = !this.ifUserKeyIn
},
getSpecificIntegral (specificIntegral, boundary) {
this.specificIntegral = specificIntegral
this.specificIntegral = (this.specificIntegral * 1e-12).toFixed(4) + 'mW'
// this.specificIntegral = (this.specificIntegral * 1e-15).toFixed(4) + 'W'
if (!this.keyBoundary) {
this.boundary = boundary
this.specificIntegral = specificIntegral / this.integralScale
if (!this.ifUserKeyIn) {
this.x_start = (boundary.x_start / this.xScale).toFixed(3)
this.x_end = (boundary.x_end / this.xScale).toFixed(3)
this.y_start = (boundary.y_start / this.yScale).toFixed(3)
this.y_end = (boundary.y_end / this.yScale).toFixed(3)
}
},
switchBoundary () {
this.keyBoundary = !this.keyBoundary
// if (this.boundary !== {})
this.boundaryXstart = this.boundary.x_start
this.boundaryXend = this.boundary.x_end
this.boundaryYstart = this.boundary.y_start
this.boundaryYend = this.boundary.y_end
},
setBrushBoundary () {
if (isNaN(this.x_start)) this.x_start = 0
if (isNaN(this.x_end)) this.x_start = 0
if (isNaN(this.xy_start)) this.y_start = 0
if (isNaN(this.y_end)) this.y_end = 0
var boundary = {
x_start: Number(this.boundaryXstart),
x_end: Number(this.boundaryXend),
y_start: Number(this.boundaryYstart),
y_end: Number(this.boundaryYend),
x_start: Number(this.x_start) * this.xScale,
x_end: Number(this.x_end) * this.xScale,
y_start: Number(this.y_start) * this.yScale,
y_end: Number(this.y_end) * this.yScale,
}
this.$emit('setBrushBoundary', boundary)
},
},
async mounted () {
},
destroyed () {
},
watch: {
setDisplayParam (xAxis, xUnit, yAxis, yUnit) {
const xScaleOption = this.configRouter.getUnitScale(xAxis)
const yScaleOption = this.configRouter.getUnitScale(yAxis)
const integralResult = this.configRouter.getFSM(xAxis, yAxis).Integral
this.xUnit = xUnit
this.yUnit = yUnit
this.xScale = xScaleOption[xUnit]
this.yScale = yScaleOption[yUnit]
this.integralResult = integralResult
this.integralUnit = this.configRouter.getUnit(integralResult)
this.integralOption = this.configRouter.getUnitOption(integralResult)
this.integralScale = this.configRouter.getUnitScale(integralResult)[this.integralUnit]
},
refreshDisplayParam (xAxis, xUnit, yAxis, yUnit) {
const xScaleOption = this.configRouter.getUnitScale(xAxis)
const yScaleOption = this.configRouter.getUnitScale(yAxis)
this.xUnit = xUnit
this.yUnit = yUnit
this.xScale = xScaleOption[xUnit]
this.yScale = yScaleOption[yUnit]
},
checkMeaning (xAxis, yAxis) {
const functOption = this.configRouter.getFunctOption(xAxis, yAxis)
this.ifMeaning = functOption.includes('Integral')
},
},
}
</script>
<style lang="scss">
/* .round-button {
border-radius: 12px;
} */
</style>
@@ -0,0 +1,405 @@
// object saving library name mapping table
const libraryNameMappingTable = {
EliteZM15: 'EliteEDC',
'Elite_EDC_1.4': null,
'Elite_EDC_1.5': 'EliteEDC',
'Elite_EDC_1.5re': 'EliteEDC',
'Elite_EDC_1.5r2': 'EliteEDC',
'Elite_BAT_1.0': 'EliteEDC',
'Elite_EIS_1.0': 'EliteEIS',
'Elite_EIS_1.1': 'EliteEIS',
'Elite_EIS_MINI_1.0': 'EliteEIS',
'Elite_TRIG_0.1': null,
'Elite_MEGAFLY_0.1': null,
}
// object saving setting type mapping table
const settingTypeMappingTable = {
EliteEDC: {
Time: {
description: 'Time',
channel: undefined,
},
Elite: {
1: {
description: 'Current',
channel: 0,
},
2: {
description: 'Voltage',
channel: 1,
},
3: {
description: 'Resistance',
channel: 2,
},
// 4: {
// description: 'Cycle',
// channel: 3,
// },
},
},
EliteEIS: {
Time: {
description: 'Time',
channel: undefined,
},
Elite: {
1: {
description: 'Current',
channel: 0,
},
2: {
description: 'Voltage',
channel: 1,
},
3: {
description: 'Resistance',
channel: 2,
},
},
EliteEIS: {
3: {
description: 'Frequency',
channel: 2,
},
5: {
description: 'Z_imag',
channel: 4,
},
6: {
description: 'Z_real',
channel: 5,
},
7: {
description: 'Impedance',
channel: 6,
},
8: {
description: 'Phase',
channel: 7,
},
9: {
description: 'Current',
channel: 8,
},
10: {
description: 'Gain_Level',
channel: 9,
},
},
},
}
// object saving unit information mapping table
const unitInfoMappingTable = {
// Time
Time: {
name: 'Time',
channel: -1,
option: {
auto: 1,
us: 1,
ms: 1e3,
s: 1e6,
min: 60 * 1e6,
hour: 3600 * 1e6,
},
defaultUnit: 'auto',
downloadUnit: 'auto',
},
// Elite
Current: {
name: 'Current',
channel: 0,
option: {
nA: 1,
uA: 1e3,
mA: 1e6,
A: 1e9,
},
defaultUnit: 'mA',
downloadUnit: 'A',
},
Voltage: {
name: 'Voltage',
channel: 1,
option: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'V',
},
Resistance: {
name: 'Resistance',
channel: 2,
option: {
: 1,
Ω: 1e3,
: 1e6,
: 1e9,
},
defaultUnit: 'Ω',
downloadUnit: 'Ω',
},
// Elite after Integral
Charge: {
name: 'Charge',
channel: -1,
option: {
nAh: 3600 * 1e6,
uAh: 1600 * 1e9,
mAh: 3600 * 1e12,
Ah: 3600 * 1e15,
},
defaultUnit: 'mAh',
downloadUnit: 'mAh',
},
Power: {
name: 'Power',
channel: -1,
option: {
mW: 1e12,
W: 1e15,
kW: 1e18,
},
defaultUnit: 'W',
downloadUnit: 'W',
},
// Elite after Differential
Transconductance: {
name: 'Transconductance',
channel: -1,
option: {
'mA/V': 1,
'A/V': 1e3,
'kA/V': 1e6,
},
defaultUnit: 'A/V',
downloadUnit: 'A/V',
},
// EliteEIS
Frequency: {
name: 'Frequency',
chanel: 2,
option: {
mHz: 1,
Hz: 1e3,
kHz: 1e6,
MHz: 1e9,
},
downloadUnit: 'Hz',
defaultUnit: 'Hz',
},
Z_imag: {
name: 'Z_imag',
chanel: 4,
option: {
: 1e-3,
Ω: 1,
: 1e3,
: 1e6,
},
downloadUnit: 'Ω',
defaultUnit: 'Ω',
},
Z_real: {
name: 'Z_real',
chanel: 5,
option: {
: 1e-3,
Ω: 1,
: 1e3,
: 1e6,
},
downloadUnit: 'Ω',
defaultUnit: 'Ω',
},
Impedance: {
name: 'Impedance',
chanel: 6,
option: {
: 1e-3,
Ω: 1,
: 1e3,
: 1e6,
},
downloadUnit: 'Ω',
defaultUnit: 'Ω',
},
Phase: {
name: 'Phase',
chanel: 7,
option: {
'°': 1,
},
downloadUnit: '°',
defaultUnit: '°',
},
Gain_Level: {
name: 'Gain Level',
chanel: 9,
option: {
'#': 1,
},
downloadUnit: '#',
defaultUnit: '#',
},
undefined: {
name: 'not support',
channel: -1,
option: {
none: 1,
},
defaultUnit: 'none',
downloadUnit: 'none',
},
}
// object saving specific functional information mapping table
const functInfoMappingTable = {
// Time
Time: {
},
// Elite
Current: {
Time: {
Linear: 'Current',
Log: 'Current',
Integral: 'Charge',
},
Voltage: {
Linear: 'Current',
Log: 'Current',
Integral: 'Power',
Differential: 'Impedance',
},
},
Voltage: {
Current: {
Linear: 'Voltage',
Log: 'Voltage',
Integral: 'Power',
Differential: 'Transconductance',
},
},
Resistance: {
},
// EliteEIS
Frequency: {
},
Z_imag: {
},
Z_real: {
},
Impedance: {
},
Phase: {
},
Gain_Level: {
},
None: {
},
}
/**
* return axis description and channel by library, type and index
* @param {String} library
* @param {String} type
* @param {String} index
* @returns {Object} : configuration
*/
function getAxis (library, type, index) {
// some physical property || Time
return settingTypeMappingTable[libraryNameMappingTable[library]][type][index] || settingTypeMappingTable[libraryNameMappingTable[library]][type]
}
/**
* retrun default unit by physical property
* @param {String} axis
* @returns {Object} : unit
*/
function getUnit (axis) {
return unitInfoMappingTable[axis].defaultUnit
}
/**
* return axis option by library, type
* @param {String} library
* @param {String} type
* @param {String} coordinate
* @returns {Object} : axisOption
*/
function getAxisOption (library, type, coordinate) {
if (type === 'Time') type = 'Elite'
const axisOption = Object.values(settingTypeMappingTable[libraryNameMappingTable[library]][type]).map((setting) => {
return setting
})
if (coordinate === 'x') {
axisOption.unshift({
description: 'Time',
channel: undefined,
})
}
return axisOption
}
/**
* retrun option of unit by physical property
* @param {String} axis
* @returns {Object} : unitOption
*/
function getUnitOption (axis) {
return Object.keys(unitInfoMappingTable[axis].option)
}
/**
* retrun a dictionary of scale corresponding to unit by physical property
* @param {String} axis
* @returns {Object} : unitScale
*/
function getUnitScale (axis) {
return unitInfoMappingTable[axis].option
}
/**
* retrun option of functionl by both axis physical property
* @param {String} xAxis
* @param {String} yAxis
* @param {String} coordinate
* @returns {Object} : functOption
*/
function getFunctOption (xAxis, yAxis, coordinate) {
if (coordinate === 'x') return ['Linear', 'Log']
else if (functInfoMappingTable[yAxis] === undefined) return ['Linear', 'Log']
else if (functInfoMappingTable[yAxis][xAxis] === undefined) return ['Linear', 'Log']
else return Object.keys(functInfoMappingTable[yAxis][xAxis])
}
/**
* retrun functional correponding physics property
* @param {String} xAxis
* @param {String} yAxis
* @returns {Object} : functOption
*/
function getFSM (xAxis, yAxis) {
return functInfoMappingTable[yAxis][xAxis] || {
Linear: yAxis,
Log: yAxis,
}
}
const configRouter = {
getAxis,
getUnit,
getAxisOption,
getUnitOption,
getUnitScale,
getFunctOption,
getFSM,
}
export default configRouter
+1 -1
View File
@@ -1,6 +1,5 @@
<template>
<div class="devices-overview">
<div >
<va-card
v-for="controller in controllerList" :key="controller.id"
@@ -518,6 +517,7 @@ export default {
async mounted () {
await taskInfo.updateTaskInfo()
await this.getControllerList()
this.GLOBAL.refreshCache()
this.pageMqttSub()
this.pageInitPub()
+1 -1
View File
@@ -68,7 +68,7 @@ export default {
this.$refs.file_ref.currentInfo = initCollection.data[0]
const folders = await api.collection.getByParent('folder', initCollection.data[0].id)
const files = await api.meta.getAttrByParent('folder', initCollection.data[0].id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-created_at')
const files = await api.meta.getAttrByParent('folder', initCollection.data[0].id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-parameter_set-created_at')
file.updateFileList(folders)
file.updateFileList(files)
+22 -3
View File
@@ -178,6 +178,9 @@
/>
{{ props.rowData.name }}
</template>
<template slot="parameter_set" slot-scope="props">
{{ getWorkingMode(props.rowData) }}
</template>
<template slot="created_at" slot-scope="props">
{{transDate(props.rowData.created_at)}}
</template>
@@ -234,6 +237,7 @@ import { file } from '../../../data/file/File'
import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
import api from '../../../data/api/index'
import SdCardButton from '../sdcard/SdCardButton.vue'
import configTable from '@/data/config-table/index.js'
export default {
name: 'FileTable',
@@ -315,6 +319,13 @@ export default {
// titleClass: 'text-center',
// dataClass: 'text-center',
// },
{
name: '__slot:parameter_set',
title: 'Working Mode',
width: '10%',
titleClass: 'text-center',
dataClass: 'text-center',
},
{
name: '__slot:created_at',
title: 'create time',
@@ -416,7 +427,7 @@ export default {
// call getfolder api and update
const folders = await api.collection.getByParent('folder', info.id)
const files = await api.meta.getAttrByParent('folder', info.id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-created_at')
const files = await api.meta.getAttrByParent('folder', info.id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-parameter_set-created_at')
file.updateFileList(folders)
file.updateFileList(files)
@@ -436,7 +447,7 @@ export default {
this.currentInfo = item
// call getfolder api and update
const folders = await api.collection.getByParent('folder', item.id)
const files = await api.meta.getAttrByParent('folder', item.id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-created_at')
const files = await api.meta.getAttrByParent('folder', item.id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-parameter_set-created_at')
file.updateFileList(folders)
file.updateFileList(files)
@@ -457,7 +468,7 @@ export default {
if (initCollection.data.length === 1) {
this.currentInfo = initCollection.data[0]
const folders = await api.collection.getByParent('folder', initCollection.data[0].id)
const files = await api.meta.getAttrByParent('folder', initCollection.data[0].id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-created_at')
const files = await api.meta.getAttrByParent('folder', initCollection.data[0].id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-parameter_set-created_at')
file.updateFileList(folders)
file.updateFileList(files)
this.fileLists = file.getFileList()
@@ -760,6 +771,14 @@ export default {
})
}
},
getWorkingMode: function (rowData) {
try {
if (rowData.type === 'folder') return ''
return configTable.getModeConfig(rowData.device.library_name, rowData.parameter_set.MODE).name
} catch {
return ''
}
},
},
async mounted () {
const controllerList = await api.controller.getAll()
+21 -5
View File
@@ -4,17 +4,30 @@
<project-manager/>
</div>
<div
:class="(taskViewPanel.show || projectManagerPanel.show)
:class="(projectManagerPanel.show)
? cardStyle.medium
: cardStyle.large
">
<!-- :class="(taskViewPanel.show || projectManagerPanel.show)
? (taskViewPanel.show && projectManagerPanel.show)
? cardStyle.small
: cardStyle.medium
: cardStyle.large
">
"> -->
<project-view @start_project="startProject($event)" @stop_project="stopProject($event)" @save_project="saveProject($event)"/>
</div>
<div :class="cardStyle.small" v-show="taskViewPanel.show">
<!-- <div :class="cardStyle.small" v-show="taskViewPanel.show">
<project-task/>
</div>
</div> -->
<slide-out
dock="right"
:mask-color="'rgba(0, 0, 0, 0)'"
:visible.sync="taskViewPanel.show"
:title="(taskViewPanel.type === 1) ? 'Device' : (taskViewPanel.type === 3) ? 'Condition' : (taskViewPanel.type === 4) ? 'Parameter' : ''"
resizable
>
<project-task/>
</slide-out>
</div>
</template>
@@ -157,20 +170,23 @@ export default {
...mapActions('project',
[
types.project.update,
types.project.addDevice,
],
),
},
async mounted () {
await this.initPage()
console.log('controllerID', taskInfo.getTaskInfo().controllerID)
// console.log('controllerID', taskInfo.getTaskInfo().controllerID)
/** get connect device list */
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'get_device_info_all/0',
}))
const project = await this.API.project.getAll()
// console.log('project: ', project)
this.projectConfigList.length = 0
this.projectConfigList.push(...project.data)
// console.log('projectConfigList: ', this.projectConfigList)
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'get_running_project/0',
@@ -1,9 +1,33 @@
<template>
<div>
<va-card style="height: 90vh; overflow: auto; display: block;">
<va-card style="height: 88vh; overflow: auto; display: block;">
<template slot="header">
<va-icon name="fa fa-bluetooth-b mr-3" color="primary"/>
<h5 class="mt-0 mb-0">PROJECTS</h5>
<div class="row">
<div class="flex d-flex xs5 sm5 lg5 xl5">
<va-icon name="fa fa-bluetooth-b" color="primary"/>
<h5 class="mb-0">PROJECTS</h5>
</div>
<div class="flex xs7 sm7 lg7 xl7" style="text-align: right;">
<!-- <va-button v-if="projectConfigList.length !== 0" class="ma-0 circle-button" @click="closePanel"> -->
<va-icon v-if="projectConfigList.length !== 0" @click.native="closePanel"
name="fa fa-times"
color="black"
/>
<!-- </va-button> -->
</div>
</div>
<!-- <div class="flex d-flex xl5 lg5 sm5 xs5 ma-0">
<va-icon name="fa fa-bluetooth-b mr-3" color="primary"/>
<h5 class="mb-0">PROJECTS</h5>
</div>
<div class="flex d-flex xl7 lg7 sm7 xs7 ma-0" style="text-align: right;">
<va-button v-if="projectConfigList.length !== 0" class="pa-0 ma-0 circle-button" small color="dark" @click="closePanel">
<va-icon
name="fa fa-times"
color="white"
/>
</va-button>
</div> -->
</template>
<div class="flex d-flex m12 xs12 md12 xl12">
<div>
@@ -44,6 +68,7 @@ export default {
'projectList',
'projectConfigList',
'runningProjectList',
'projectManagerPanel',
]),
},
data () {
@@ -63,9 +88,16 @@ export default {
types.project.create,
],
),
closePanel: function () {
this.projectManagerPanel.show = !this.projectManagerPanel.show
},
},
mounted () {
this.projectList = this.projectConfigList
},
}
</script>
<style>
</style>
+1 -1
View File
@@ -1,6 +1,6 @@
<template>
<div>
<va-card style="height: 90vh; overflow: auto;">
<va-card style="height: 88vh; overflow: auto;">
<project-task-config></project-task-config>
</va-card>
</div>
@@ -1,15 +1,16 @@
<template>
<div class="flex sm12 xl12 md12 xs12">
<div class="task-config__header-separator mb-1">
<!-- <div class="task-config__header-separator mb-1">
<div class="task-config__header-text">
<span>Action &#38; Condition</span>
<va-button class="circle-button" small color="dark" @click="closePanel">
<va-icon
name="fa fa-times"
color="white"
/>
</va-button>
</div>
</div>
<div>
<!-- <div v-for="(action, actionKey) in this.getSelectTask.action" :key="actionKey">
{{ getDeviceProject(action.target).name }} {{ action.type }} {{ getConditionTask(action.condition[0]).value }}
</div> -->
</div>
</div> -->
<span>Device</span>
<div class="flex d-flex" v-if="Object.keys(registeredDevice).length > 0">
<div v-for="(device, deviceKey) in registeredDevice" :key="deviceKey">
@@ -30,7 +31,23 @@
<div v-if="settingStep >= 2">
<span>Condition</span>
<div v-for="(condition, key) in conditionObj" :key="key">
<div class="flex d-flex align--center">
<!-- <div v-if="key === 'cycle' || key === 'cycle_next'" class="flex d-flex align--center"> -->
<div v-if="key === 'cycle_next'" class="flex d-flex align--center">
<!-- <va-checkbox v-model="condition.select"></va-checkbox> -->
<span class="mr-1">{{ condition.prefix }}</span>
<!-- <input class="mr-1" :type="condition.type" v-model="condition.value"/> -->
<va-select
@click.native="updateTaskOptions()"
:label="''"
v-model="conditionObj.cycle_next.value"
textBy="description"
class="va-select-without-margin"
:options="taskOptionsKeys"
:noClear='false'
/>
<span>{{ condition.suffix }}</span>
</div>
<div v-else class="flex d-flex align--center">
<va-checkbox v-model="condition.select"></va-checkbox>
<span class="mr-1">{{ condition.prefix }}</span>
<input class="mr-1" :type="condition.type" v-model="condition.value"/>
@@ -76,6 +93,7 @@ export default {
...mapFields('project', [
'taskSelectKey',
'taskViewPanel',
]),
},
data () {
@@ -91,10 +109,18 @@ export default {
conditionTemplate: newConditionTemplate(),
conditionList: [],
taskOptions: {},
taskOptionsKeys: [],
project: {},
device: {},
task: {},
}
},
methods: {
closePanel: function () {
this.taskViewPanel.show = !(this.taskViewPanel.show)
},
selectDevice: function (deviceKey) {
this.settingStep = 1
this.deviceSelect = deviceKey
@@ -126,6 +152,10 @@ export default {
}
},
save: function () {
// create fake start previous done
const fakeStartActionUUID = this.GLOBAL.getUUID()
const fakeAction = this.createAction(fakeStartActionUUID, 'start', this.deviceSelect)
const actionUUID = this.GLOBAL.getUUID()
const newAction = this.createAction(actionUUID, this.actionSelect, this.deviceSelect)
@@ -135,32 +165,73 @@ export default {
}
for (const key in this.conditionObj) {
if (this.conditionObj[key].select) {
const conditionUUID = this.GLOBAL.getUUID()
const newCondition = this.createCondition(conditionUUID, key, 'equal', this.conditionObj[key].value)
if (key === 'cycle') {
// use 'cycle' and 'cycle_next' to set the default to condition: previous_task_done & after_task_run 0
if (this.conditionObj[key].select) {
const conditionUUID = this.GLOBAL.getUUID()
const newCondition = this.createCondition(conditionUUID, 'previous_task_done', 'equal', '')
this.setConditionTask({ condition: newCondition })
newAction[actionUUID].condition.push(conditionUUID)
}
} else if (key === 'cycle_next') {
if (this.conditionObj.cycle.select) {
const conditionUUID = this.GLOBAL.getUUID()
const newCondition = this.createCondition(conditionUUID, 'after_task_run', 'equal', '0')
this.setConditionTask({ condition: newCondition })
newAction[actionUUID].condition.push(conditionUUID)
}
} else {
if (this.conditionObj[key].select) {
// create fake condition
const fakeConditionUUID = this.GLOBAL.getUUID()
const fakeCondition = this.createCondition(fakeConditionUUID, 'previous_task_done', 'equal', '')
this.setConditionTask({ condition: fakeCondition })
fakeAction[fakeStartActionUUID].condition.push(fakeConditionUUID)
this.setConditionTask({ condition: newCondition })
newAction[actionUUID].condition.push(conditionUUID)
const conditionUUID = this.GLOBAL.getUUID()
const newCondition = this.createCondition(conditionUUID, key, 'equal', this.conditionObj[key].value)
this.setConditionTask({ condition: newCondition })
newAction[actionUUID].condition.push(conditionUUID)
}
}
}
this.setActionTask({ action: newAction })
this.setActionTask({ action: fakeAction })
if (this.conditionObj.cycle_next !== undefined) {
this.setCycleTask({ cycle: Number(this.conditionObj.cycle.value), cycle_next: this.conditionObj.cycle_next.value, cycle_next_uuid: this.taskOptions[this.conditionObj.cycle_next.value] })
}
this.reset()
},
updateTaskOptions: function () {
for (var idx = 0; idx < this.project.task.length; idx++) {
this.taskOptions[this.project.task[idx].name] = this.project.task[idx].uuid
}
this.taskOptionsKeys = Object.keys(this.taskOptions)
},
...mapActions('project', [
types.task.setCondition,
types.task.setAction,
types.task.setCycle,
]),
},
mounted () {
const project = this.getSelectProject
const device = this.getAllDeviceProject
const task = this.getSelectTask
// const project = this.getSelectProject
// const device = this.getAllDeviceProject
// const task = this.getSelectTask
this.project = this.getSelectProject
this.device = this.getAllDeviceProject
this.task = this.getSelectTask
for (var idx = 0; idx < this.project.task.length; idx++) {
this.taskOptions[this.project.task[idx].name] = this.project.task[idx].uuid
}
this.taskOptionsKeys = Object.keys(this.taskOptions)
console.log('project', project)
console.log('task', task)
// console.log('project', this.project)
// console.log('task', this.task)
this.registeredDevice = device
this.registeredDevice = this.device
},
}
</script>
@@ -1,10 +1,16 @@
<template>
<div class="flex sm12 xl12 md12 xs12">
<div class="task-config__header-separator mb-1">
<!-- <div class="task-config__header-separator mb-1">
<div class="task-config__header-text">
<span >Device</span>
<span> Device </span>
<va-button class="circle-button" small color="dark" @click="closePanel">
<va-icon
name="fa fa-times"
color="white"
/>
</va-button>
</div>
</div>
</div> -->
<div>
<va-list fit class="mb-2">
<va-item v-for="(device, index) in getSelectProject.device" :key="index" >
@@ -57,6 +63,7 @@ export default {
...mapFields('project', [
'taskSelectKey',
'taskViewPanel',
]),
},
data () {
@@ -68,6 +75,7 @@ export default {
// if select single task
if (this.taskSelectKey !== undefined) {
device.isSelect = event
// console.log('device.isSelect: ', device.isSelect)
device.isSelect.includes(String(this.taskSelectKey)) === true
? this.getSelectTask.device.push(key)
: this.getSelectTask.device = this.getSelectTask.device.filter(item => item !== key)
@@ -90,6 +98,9 @@ export default {
}
}
},
closePanel: function () {
this.taskViewPanel.show = !(this.taskViewPanel.show)
},
},
mounted () {
},
@@ -1,15 +1,22 @@
<template>
<div class="flex sm12 xl12 md12 xs12">
<div class="task-config__header-separator mb-1">
<!-- <div class="task-config__header-separator mb-1">
<div class="task-config__header-text">
<span >Parameter Set</span>
<va-button class="circle-button" small color="dark" @click="closePanel">
<va-icon
name="fa fa-times"
color="white"
/>
</va-button>
</div>
</div>
</div> -->
<div>
<device-parameter-recording
:ref="'device_parameter_ref'"
:parameter="parameter"
:library="'EliteEDC1.5'"
:library="'Elite_EDC_1.5'"
:place="'scheduler'"
@setParameter="setParameter"
@setParameterWithDebounce="setParameterWithDebounce"
/>
@@ -54,6 +61,9 @@ export default {
}
},
methods: {
closePanel: function () {
this.taskViewPanel.show = !(this.taskViewPanel.show)
},
selectDevice: function (device) {
this.deviceSelected = device
},
@@ -81,7 +91,11 @@ export default {
// get Device
this.device = this.getDeviceProject(this.deviceSelectKey)
// get Config
this.config = configTable.getConfig(this.device.library.value)
if (typeof this.device.library === 'string') { // string
this.config = configTable.getConfig(this.device.library)
} else { // object
this.config = configTable.getConfig(this.device.library.value)
}
// create default parameter
const defaultValue = {}
for (const key in this.config) {
@@ -97,6 +111,8 @@ export default {
const modeOption = this.$refs.device_parameter_ref.workingModeOptions.find(ele => ele.id === param.MODE)
this.$refs.device_parameter_ref.workingModeSelectChange(modeOption)
this.parameter = Object.assign(this.parameter, Object.values(parameterSet)[0])
} else {
this.setParameter('MODE', 0)
}
},
...mapActions('project',
@@ -109,5 +125,22 @@ export default {
// init parameter
this.resetParameter()
},
watch: {
// refresh parameter when click different task's parameter
taskSelectKey: {
handler: function () {
this.parameter = {}
this.parameterUUID = ''
this.resetParameter()
},
},
deviceSelectKey: {
handler: function () {
this.parameter = {}
this.parameterUUID = ''
this.resetParameter()
},
},
},
}
</script>
@@ -505,7 +505,7 @@ export default {
// },
// {
// id: 11,
// description: 'Cali ADC - test',
// description: 'Cali Mode - test',
// },
// {
// id: 12,
@@ -576,6 +576,10 @@ export default {
value: 1,
label: 'Vin',
},
{
value: 2,
label: 'Vout',
},
],
startVoltNumber: null,
stopVoltNumber: null,
@@ -1,6 +1,6 @@
<template>
<div>
<elite-parameter-recording-elitezm15 :ref="'rec_ref_2'" :deviceID="deviceID" @parameterChange="parameterChange"/>
<elite-parameter-recording-elitezm15 :ref="'rec_ref_2'" :deviceID="deviceID" @parameterChange="parameterChange" :place="'scheduler'"/>
<!-- <elite-parameter-recording v-if="eliteVer=='1'" :ref="'rec_ref_1'" :deviceID="deviceID"/>
<elite-parameter-recording-elitezm15 v-else-if="eliteVer=='2'" :ref="'rec_ref_2'" :deviceID="deviceID"/>
<elite-parameter-recording-elite-e-i-s v-else-if="eliteVer=='4'" :ref="'rec_ref_4'" :deviceID="deviceID"/>
+36 -2
View File
@@ -1,6 +1,6 @@
<template>
<div>
<va-card style="height: 90vh; overflow: auto; display: block;">
<va-card style="height: 88vh; overflow: auto; display: block;">
<template slot="header">
<va-icon name="fa fa-bluetooth-b mr-3" color="primary"/>
<h5 class="mt-0 mb-0"> {{ getSelectProject ? getSelectProject.name : '' }}</h5>
@@ -26,7 +26,7 @@
import ProjectMenu from '@/components/project/view/menu/ProjectMenu'
import ProjectTable from '@/components/project/view/table/ProjectTable'
import { mapFields } from 'vuex-map-fields'
import { mapGetters } from 'vuex'
import { mapGetters, mapActions } from 'vuex'
import types from '@/store/modules/project/types'
export default {
@@ -42,7 +42,9 @@ export default {
...mapFields('project', [
'lockMode',
'projectList',
'deviceConnectList',
'projectSelectIndex',
'projectLibrary',
]),
},
data () {
@@ -59,6 +61,38 @@ export default {
save: function () {
this.$emit('save_project', this.getSelectProject)
},
...mapActions('project',
[
types.project.update,
types.project.addDevice,
],
),
},
watch: {
projectSelectIndex: {
handler: async function () {
// console.log('device', this.deviceConnectList)
for (const device of this.deviceConnectList) {
var newDevice = {
uuid: this.GLOBAL.getUUID(),
name: device.mac_address,
product: device.device_name,
library: device.library_name,
connectDevice: device,
isSelect: [],
}
await this.addDeviceProject({ device: newDevice })
if (device.library_name !== undefined) {
this.projectLibrary = device.library_name
}
}
},
},
},
async mounted () {
// console.log('mounted')
// console.log(this.deviceConnectList)
// console.log(this.deviceConnectList.length)
},
}
</script>
@@ -16,13 +16,14 @@
<th align="center" @click="openConfig(1)">device</th>
<th align="center">action and condition</th>
<th align="center">parameter</th>
<th v-if="lockMode" align="center">cycle</th>
<th align="center"></th>
</tr>
</thead>
<tbody>
<template v-for="(task, taskIndex) in getSelectProject.task">
<tr v-if="task.device.length === 0" :key="taskIndex" height="80px">
<!-- <tbody> -->
<vuedraggable :disabled="lockMode === true" class="draggable" v-model="getSelectProject.task" @start="() => {}" @end="() => {}" tag="tbody" animation="500">
<template class="item" v-for="(task, taskIndex) in getSelectProject.task">
<tr v-if="task.device && task.device.length === 0" :key="'empty' + taskIndex" height="80px" @click="() => { focus = taskIndex }">
<td v-if="lockMode === false">
<va-checkbox
v-model="tableColumn.checked"
@@ -36,19 +37,19 @@
{{ task.name }}
</td>
<td align="center">
<va-button :flat="true" @click="openConfig(1, taskIndex)" small>Device</va-button>
<va-button :flat="true" @click="openConfig(1, taskIndex)" small>Add Device</va-button>
</td>
<td align="center">
<va-button :flat="true" @click="openConfig(3, taskIndex)" small>Add event</va-button>
<va-button :flat="true" @click="openConfig(3, taskIndex)" small>+ New Action/Condition</va-button>
</td>
<td align="center">
<va-button :flat="true" @click="openConfig(4, taskIndex)" small>ParameterSet</va-button>
<va-button :flat="true" @click="openConfig(4, taskIndex)" small>Add Parameter</va-button>
</td>
<td align="center">
<va-icon class="fa fa-close" @click.native="() => deleteTask({ index: taskIndex})"></va-icon>
</td>
</tr>
<tr v-for="(deviceUUID) in task.device" :key="taskIndex + deviceUUID" height="80px">
<tr :class="taskIndex === focus ? 'table-row-focus' : ''" v-else v-for="(deviceUUID) in task.device" :key="taskIndex + deviceUUID" height="80px" @click="() => { focus = taskIndex }">
<td v-if="lockMode === false">
<va-checkbox
v-model="tableColumn.checked"
@@ -68,39 +69,90 @@
/>
</div>
<div v-else>
<!-- <vuedraggable class="draggable">
{{ task.name }}
</vuedraggable> -->
{{ task.name }}
</div>
</td>
<td align="center" @click="openConfig(1, taskIndex, deviceUUID)">
<div >
<span>{{ getDeviceProject(deviceUUID) && getDeviceProject(deviceUUID).name }}</span>
<!-- device -->
<td align="center">
<div v-if="task.device && task.device.length === 0">
<va-button :flat="true" @click="openConfig(1, taskIndex, deviceUUID)" small>
Add device
</va-button>
</div>
<div v-else>
<va-button :flat="true" @click="openConfig(1, taskIndex, deviceUUID)" small>
<span>{{ getDeviceProject(deviceUUID) && getDeviceProject(deviceUUID).name }}</span>
</va-button>
</div>
</td>
<td align="center" @click="openConfig(3, taskIndex, deviceUUID)">
<div class="flex">
<!-- device end -->
<!-- action -->
<td align="center">
<div v-if="Object.keys(task.action).length === 0">
<va-button :flat="true" @click="openConfig(3, taskIndex, deviceUUID)" small>
Add event
</va-button>
</div>
<div v-else class="flex">
<div v-for="(action, actionKey) in task.action" :key="actionKey">
<div v-if="action.target === deviceUUID">
<div v-for="conditionKey in action.condition" :key="conditionKey">
{{ action.type }} {{ task.condition[conditionKey].type }} {{ task.condition[conditionKey].value }}
<div small v-if="action.type !== 'cycle' && action.type !== 'start'">
{{ action.type }} {{ task.condition[conditionKey].type }} {{ task.condition[conditionKey].value }}
<va-icon class="fa fa-close" @click.native="delAction(task, actionKey, conditionKey)"/>
</div>
<div small v-else-if="action.type == 'cycle' && task.condition[conditionKey].type === 'previous_task_done'">
{{ action.type }} go to {{ task.cycle_next }} run {{ task.cycle }} times
<va-icon class="fa fa-close" @click.native="delAction(task, actionKey, conditionKey)"/>
</div>
</div>
</div>
</div>
<va-button :flat="true" @click="openConfig(3, taskIndex, deviceUUID)" small>
+ New Action/Condition
</va-button>
</div>
</td>
<td align="center" @click="openConfig(4, taskIndex, deviceUUID)">
<div class="flex d-flex">
<div class="flex">
<!-- action end -->
<td align="center">
<div v-if="Object.keys(task.parameter_set).length === 0">
<va-button :flat="true" @click="openConfig(4, taskIndex, deviceUUID)" small>
Add Parameter
</va-button>
</div>
<va-button :flat="true" @click="openConfig(4, taskIndex, deviceUUID)" v-else class="flex d-flex">
<div class="flex" small>
<div v-for="(parameterSet, parameterSetKey) in getParameterSetTask(taskIndex, deviceUUID)" :key="parameterSetKey">
<div v-for="(parameter, parameterKey) in parameterSet" :key="parameterKey">
<span v-if="parameterKey !== 'target'"> {{ parameterName(parameterKey) }} : {{ parameterValue(parameterKey, parameter) }} </span>
<span v-if="parameterKey !== 'target'">
<div small>
{{ parameterName(parameterKey) }} : {{ parameterValue(parameterKey, parameter) }}
</div>
</span>
</div>
</div>
</div>
</div>
</va-button>
</td>
<td align="center" v-if="lockMode === false">
<va-icon v-if="String(taskIndex) !== '0'" class="fa fa-toggle-up" @click.native="swapTask(taskIndex, 0)"/>
<va-icon v-if="parseInt(taskIndex) !== getSelectProject.task.length - 1" class="fa fa-toggle-down" @click.native="swapTask(taskIndex, 1)"/>
<va-icon class="fa fa-close" @click.native="() => deleteTask({ index: taskIndex})"></va-icon>
</td>
<td align="center" v-if="lockMode === true">
<div v-if="task.cycle > 0 && task.status === 2 && task.cycle_count === 0">
{{ task.cycle }}/{{ task.cycle }}
</div>
<div v-else-if="task.cycle > 0">
{{ task.cycle_count }}/{{ task.cycle }}
</div>
</td>
<td v-if="lockMode === true && Object.values(task.condition).findIndex(ele => ele.type == 'until_button_trigger') != -1 && task.status === 1">
<va-button icon="fa fa-play" @click="trigger_button(getSelectProject)" flat></va-button>
<td/>
<td align="center" v-if="lockMode === true">
<!-- {{ task.status }} -->
<fulfilling-bouncing-circle-spinner
@@ -113,7 +165,8 @@
</td>
</tr>
</template>
</tbody>
</vuedraggable>
<!-- </tbody> -->
</table>
</div>
</div>
@@ -124,11 +177,14 @@ import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/types'
import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
import configTable from '@/data/config-table/index'
import vuedraggable from 'vuedraggable'
import { taskInfo } from '@/data/task/TaskInfo'
export default {
name: 'project-table',
components: {
FulfillingBouncingCircleSpinner,
vuedraggable,
},
computed: {
config () {
@@ -157,9 +213,83 @@ export default {
name: -1,
checked: [],
},
focus: -1,
}
},
methods: {
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
dragEnd: function (event) {
console.log('event', event)
console.log('from', event.oldDraggableIndex)
console.log('to', event.newDraggableIndex)
const newTaskList = JSON.parse(JSON.stringify(this.getSelectProject.task))
console.log('this.getSelectProject.task', newTaskList, this.getSelectProject.task)
const b = newTaskList[event.oldDraggableIndex]
const a = newTaskList[event.newDraggableIndex]
console.log('a', a)
console.log('b', b)
console.log('b.device.length', b.device.length)
if (b && b.device.length === 0) return
console.log('1')
// newTaskList.splice(event.newDraggableIndex, 1, this.getSelectProject.task[event.oldDraggableIndex])
if (a === undefined) return
console.log('2')
// newTaskList.splice(event.oldDraggableIndex, 1, a)
newTaskList.filter(ele => ele != null)
console.log('newTaskList', newTaskList)
// this.getSelectProject.task = newTaskList
},
swapTask: function (taskIndex, upDown) {
taskIndex = parseInt(taskIndex)
if (upDown === 0) {
const a = this.getSelectProject.task[taskIndex]
this.getSelectProject.task.splice(taskIndex, 1, this.getSelectProject.task[taskIndex - 1])
this.getSelectProject.task.splice(taskIndex - 1, 1, a)
} else {
const a = this.getSelectProject.task[taskIndex]
this.getSelectProject.task.splice(taskIndex, 1, this.getSelectProject.task[taskIndex + 1])
this.getSelectProject.task.splice(taskIndex + 1, 1, a)
}
},
delSelected: function () {
for (const indexSelected of this.tableColumn.checked) {
this.deleteTask({ index: indexSelected })
}
},
delAction: function (task, actionKey, conditionKey) {
// console.log(action)
// console.log(conditionKey)
// console.log(action.condition[0])
// console.log(action.condition.length)
// for (let i = 0; i < action.condition.length; i++) {
// if (String(action.condition[i]) === String(conditionKey)) {
// delete action.condition[i]
// break
// }
// }
const _action = JSON.parse(JSON.stringify(task.action))
const _condition = JSON.parse(JSON.stringify(task.condition))
// console.log(Object.keys(_task.action))
delete _action[actionKey]
delete _condition[conditionKey]
// delete _task.action[actionKey]
// delete _task.condition[conditionKey]
// console.log(Object.keys(_task.action))
task.action = _action
task.condition = _condition
console.log('task', task)
// delete action.condition[0]
},
trigger_button: function (projectID) {
console.log('project', projectID)
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'set_project/0',
project: projectID.uuid,
content: 'test',
}))
},
switchInput: function (tag, index) {
this.tableColumn[tag] >= 0
? this.tableColumn[tag] = -1
@@ -177,7 +307,7 @@ export default {
openConfig (type, taskIndex, deviceKey) {
console.log(type, taskIndex, deviceKey, this.taskViewPanel.type, this.taskSelectKey, this.deviceSelectKey)
if (!this.lockMode) {
if (this.taskViewPanel.type === type && this.taskSelectKey === taskIndex && this.deviceSelectKey === deviceKey) {
if (this.taskViewPanel.type === type && this.taskSelectKey === taskIndex && this.deviceSelectKey === deviceKey && this.taskViewPanel.show === true) {
this.taskSelectKey = ''
this.taskViewPanel.type = -1
this.taskViewPanel.show = false
@@ -191,25 +321,29 @@ export default {
}
},
parameterName (name) {
if (name === 'MODE') {
return 'Mode'
if (this.config !== undefined && Object.keys(this.config) !== 0) {
if (name === 'MODE') {
return 'Mode'
}
if (typeof this.config[name].showName === 'function') {
return this.config[name].showName()
}
return this.config[name].showName
}
if (typeof this.config[name].showName === 'function') {
return this.config[name].showName()
}
return this.config[name].showName
},
parameterValue (name, value) {
if (name === 'MODE') {
return this.config.MODE[value].name
}
if (this.config[name].type === 'number') {
const scale = this.config[name].unit[this.config[name].defaultUnit]
return `${this.config[name].outputReadabilityData(value, scale)} ${this.config[name].defaultUnit}`
} else if (this.config[name].type === 'array') {
return `${this.config[name].outputReadabilityData(value)}`
} else if (this.config[name].type === 'none') {
return ''
if (this.config !== undefined && Object.keys(this.config) !== 0) {
if (name === 'MODE') {
return this.config.MODE[value].name
}
if (this.config[name].type === 'number') {
const scale = this.config[name].unit[this.config[name].defaultUnit]
return `${this.config[name].outputReadabilityData(value, scale)} ${this.config[name].defaultUnit}`
} else if (this.config[name].type === 'array') {
return `${this.config[name].outputReadabilityData(value)}`
} else if (this.config[name].type === 'none') {
return ''
}
}
},
...mapActions('project', [
@@ -222,6 +356,28 @@ export default {
</script>
<style lang="scss">
.draggable {
width: 500px;
margin: auto;
}
// .item {
// height: 40px;
// line-height: 40px;
// margin-bottom: 20px;
// background-color: skyblue;
// text-align: center;
// color: #ffffff;
// cursor: move;
// }
.table-row-focus {
background: #ebedff;
border: 1px solid #dbdcf0;
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.25);
border-radius: 5px;
}
.markup-tables {
width: 100%;
+57 -6
View File
@@ -1,6 +1,5 @@
<template>
<div class="task-content">
<va-modal
v-model="showShutdownModal"
size="small"
@@ -29,7 +28,7 @@
<div class="flex sm12 xl12 md12 xs12">
<task-devices-new :ref="'devices_ref'" @add="addDevice($event)" @remove="removeDevice($event)" @refreshSetting="refreshChartSetting($event)" class="pa-0" />
</div>
<div class="flex sm12 xl12 md12 xs12" v-if="developer_mode">
<div class="flex sm12 xl12 md12 xs12" v-if="developerMode">
<task-formula :ref="'formula_ref'" @add="addFormula($event)" @remove="removeFormula($event)" class="pa-0" />
</div>
</div>
@@ -129,7 +128,7 @@ export default {
'deviceListNew',
]),
...mapFields('', [
'developer_mode',
'developerMode',
]),
},
data () {
@@ -144,13 +143,29 @@ export default {
showDeviceSetting: true,
chartAreaClass: ['flex', 'xs12', 'sm12', 'md12', 'xl8', 'pa-0'],
getParmDone: false,
batteryInterval: {},
}
},
mqtt: {
async '+/device_battery/+' (data, topic) {
const deviceBattery = JSON.parse(String.fromCharCode.apply(null, data)).data
const device = this.deviceListNew.find(ele => ele.memory_board === deviceBattery.device)
device.battery = deviceBattery.battery
},
async '+/get_device_info_all/+' (data, topic) {
// console.log('get_device_info_all', String.fromCharCode.apply(null, data))
this.deviceListNew = JSON.parse(String.fromCharCode.apply(null, data)).data
// console.log(this.deviceListNew)
for (let i = 0; i < this.deviceListNew.length; i++) {
const curDevice = this.deviceListNew[i]
if ((curDevice.memory_board in this.batteryInterval) === false) {
this.batteryInterval[curDevice.memory_board] = setInterval(() => { this.getBattery(curDevice) }, 60000)
}
}
// console.log(this.batteryInterval)
// console.log(this.deviceListNew)
// await taskInfo.deviceInfo(String.fromCharCode.apply(null, data), this.deviceList)
// console.log('this.deviceList 0', this.deviceList)
@@ -299,12 +314,25 @@ export default {
}))
this.pageToast('The device [' + taskInfo.getDeviceIDByRaw(parseInt(mes[1])) + '] mission is done.')
break
case 'project':
// refresh real-time page when going to next task
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'get_device_info_all/0',
}))
this.pageToast(mes[1])
break
default:
break
}
},
},
methods: {
getBattery: function (device) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_battery/0',
device: device.memory_board,
}))
},
mqttSub: function (val) {
this.$mqtt.subscribe(val)
},
@@ -322,6 +350,7 @@ export default {
this.mqttSub(id + '/device_parameter/+')
this.mqttSub(id + '/device_parameter_value/+')
this.mqttSub(id + '/device_sd_card_status/+')
this.mqttSub('+/device_battery/+')
},
pageMqttUnSub: function (id) {
for (const device in taskInfo.getTaskInfo().deviceList) {
@@ -334,6 +363,7 @@ export default {
this.mqttUnSub(id + '/device_parameter/+')
this.mqttUnSub(id + '/device_parameter_value/+')
this.mqttUnSub(id + '/device_sd_card_status/+')
this.mqttUnSub('+/device_battery/+')
},
pageInit: async function () {
if (await this.$refs.devices_ref != null) {
@@ -365,7 +395,7 @@ export default {
continue
}
// device is running refresh chart
if (device.status === 1 && this.chartData[chart].captured !== true) {
if (this.chartData[chart].captured !== true) {
this.taskContentChartRefreshData({
chartID: chart,
deviceList: this.deviceListNew,
@@ -591,6 +621,10 @@ export default {
path: '/',
})
},
switchMode: function () {
console.log('switch mode', this.developerMode)
this.developerMode = !this.developerMode
},
...mapActions('taskContent', [
taskTypes.chart.initCustomizedFromCache,
@@ -609,14 +643,27 @@ export default {
async mounted () {
const devMode = this.$route.params.mode
if (devMode === 'dev') {
this.developer_mode = true
this.developerMode = true
}
await taskInfo.updateTaskInfo(this.$route.params.taskID)
this.GLOBAL.refreshCache()
this.pageMqttSub(taskInfo.getTaskInfo().controllerID)
await this.pageInit()
this.dataRefreshTimer = setInterval(this.refreshData, 1000)
this.dataRefreshTimer = setInterval(this.refreshData, 100)
var switchModeHander = function (switchMode, e) {
if (e.shiftKey && e.metaKey && e.keyCode === 83) {
switchMode()
}
if (e.shiftKey && e.ctrlKey && e.keyCode === 83) {
switchMode()
}
}
// eslint-disable-next-line no-undef
window.addEventListener('keydown', switchModeHander.bind(_, this.switchMode))
},
destroyed () {
taskInfo.destroyed(this.deviceList)
@@ -625,6 +672,10 @@ export default {
}
clearInterval(this.dataRefreshTimer)
this.pageMqttUnSub(taskInfo.getTaskInfo().controllerID)
for (var interval in this.batteryInterval) {
clearInterval(this.batteryInterval[interval])
}
},
}
+110 -86
View File
@@ -3,10 +3,13 @@
<va-card>
<template slot="header">
<div class="row flex sm12 xl12 md12 xs12 align--center my-0 py-0">
<div class="flex sm5 xl5 md5 xs5 px-0 mx-0">
<h5 class="mt-0 mb-0"><va-icon name="fa fa-area-chart mr-3" color="primary"/>{{ nameCard }}</h5>
<div class="flex sm1 xl1 md1 xs1 px-0 mx-0">
<h5 class="mt-0 mb-0" style="">{{ nameCard }}</h5>
</div>
<div class="flex sm7 xl7 md7 xs7 pa-0 ma-0" style="text-align: right;">
<div class="flex sm9 xl9 md9 xs9 px-0 " style="margin-left: -5px; color: #9aa4af;">
<p class="mt-0 mb-0">{{ chartInfo }}</p>
</div>
<div class="flex sm2 xl2 md2 xs2 pa-0 ma-0" style="text-align: right;">
<va-button class="pa-0 ma-0 circle-button" small color="dark" @click="remove()">
<va-icon
name="fa fa-times"
@@ -14,14 +17,6 @@
/>
</va-button>
</div>
<div class="flex xl10">
<canvas-chart-real-time-calculation :chartID="chartID" @refreshData="refreshData" @switchModeButton="switchModeButton" @getClicked="getClicked" ref="'cal_ref'" />
</div>
<div class="flex xl2">
<va-button :disabled="calClicked" color="#f5aa3b" @click="captureChart" small>
CAPTURE
</va-button>
</div>
</div>
</template>
<va-tabs v-model="tabValue" class="mb-3" style="width: 100%; min-width: 100px;">
@@ -34,76 +29,95 @@
</va-tabs>
<div v-if="tabValue == 0" >
<div v-if="chartData[chartID].legend.data.length != 0">
<canvas-chart-real-time-display
:chartID="chartID" ref="CanvasChartRealTimeDisplay"
/>
<div class="row flex xl12 lg12 sm12 xs12 ma-0 pa-0">
<!-- <div class="flex xl1 lg1 sm0 xs0 ma-0 pa-0"> -->
<div class="flex ma-0 pa-0">
</div>
<!-- <div class="flex xl7 lg7 sm7 xs7 ma-0 pa-0"> -->
<div class="flex ma-0 pa-0">
<canvas-chart-real-time-display
:chartID="chartID" ref="CanvasChartRealTimeDisplay"
/>
</div>
<!-- <div class="flex xl4 lg4 sm4 xs4 ma-0 pa-0"> -->
<div class="flex ma-0 pa-0">
<canvas-chart-real-time-calculation :chartID="chartID" @refreshData="refreshData" @switchModeButton="switchModeButton" @getClicked="getClicked" @captureChart="captureChart" ref="'cal_ref'" />
</div>
</div>
<div class="flex" v-if="developerMode">
<div v-for="(data, device) in dataStreamBuffer.getByChartID(chartID)" :key="device">
<div v-for="(i, channel) in data" :key="channel">
{{ device }} {{ channel }} {{ i.length }} first data: {{ (i[0] !== undefined) && i[0][0] }} last data: {{ (i[i.length-1] !== undefined) && i[i.length-1][i[i.length-1].length-1]}}
</div>
</div>
</div>
<!-- <div class="row flex align--left ma-0 pa-0">
<va-input
v-if="chartData[chartID].chartXMode === 'time'"
class="mx-1"
@keyup.enter="timeIntervalChange(timeIntervalInput)"
@blur="timeIntervalChange(timeIntervalInput)"
v-model="timeIntervalInput"
:label="'time-grid'"
>
<p slot="append" style="margin-right: 0;" small>
ms
</p>
</va-input>
<va-input
v-if="chartData[chartID].chartXMode === 'value'"
class="mx-1"
@keyup.enter="xIntervalChange(xIntervalInput)"
@blur="xIntervalChange(xIntervalInput)"
v-model="xIntervalInput"
:label="'x-grid'"
>
<p slot="append" style="margin-right: 0;" small>
{{chartData[chartID].chartXUnit}}
</p>
</va-input>
<va-input
class="mx-1"
@keyup.enter="yIntervalChange(yIntervalInput)"
@blur="yIntervalChange(yIntervalInput)"
v-model="yIntervalInput"
:label="'y-grid'"
>
<p slot="append" style="margin-right: 0;" small>
{{chartData[chartID].chartYUnit}}
</p>
</va-input>
<va-input
v-if="chartData[chartID].chartDevice === 'neulive'"
class="mx-1"
@keyup.enter="threeAxisIntervalChange(threeAxisIntervalInput)"
@blur="threeAxisIntervalChange(threeAxisIntervalInput)"
v-model="threeAxisIntervalInput"
:label="'3axis-grid'"
>
<p slot="append" style="margin-right: 0;" small>
g
</p>
</va-input>
</div> -->
<!-- chart -->
<chart :key="taskContentChartKey" :ref="'chart_ref'" :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" :option="data" @dataZoom="updateZoom" :auto-resize="true"></chart>
</div>
</div>
<div v-else-if="tabValue == 1" :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" >
<canvas-chart-source :chartID="chartID" @addSource="addSource()" />
<canvas-chart-source :chartID="chartID" />
</div>
<div v-else :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" >
</div>
<div v-if="this.$refs.chart_ref != null">
<!-- <div v-if="this.$refs.chart_ref != null">
<va-button small class="mb-3" @click="selectAllSeries">
SELECT ALL
</va-button>
<va-button small class="mb-3" @click="inverseSelectAllSeries">
INVERSE SELECT
</va-button>
</div>
<div class="row flex align--left ma-0 pa-0">
<va-input
v-if="chartData[chartID].chartXMode === 'time'"
class="mx-1"
@keyup.enter="timeIntervalChange(timeIntervalInput)"
@blur="timeIntervalChange(timeIntervalInput)"
v-model="timeIntervalInput"
:label="'time-grid'"
>
<p slot="append" style="margin-right: 0;" small>
ms
</p>
</va-input>
<va-input
v-if="chartData[chartID].chartXMode === 'value'"
class="mx-1"
@keyup.enter="xIntervalChange(xIntervalInput)"
@blur="xIntervalChange(xIntervalInput)"
v-model="xIntervalInput"
:label="'x-grid'"
>
<p slot="append" style="margin-right: 0;" small>
{{chartData[chartID].chartXUnit}}
</p>
</va-input>
<va-input
class="mx-1"
@keyup.enter="yIntervalChange(yIntervalInput)"
@blur="yIntervalChange(yIntervalInput)"
v-model="yIntervalInput"
:label="'y-grid'"
>
<p slot="append" style="margin-right: 0;" small>
{{chartData[chartID].chartYUnit}}
</p>
</va-input>
<va-input
v-if="chartData[chartID].chartDevice === 'neulive'"
class="mx-1"
@keyup.enter="threeAxisIntervalChange(threeAxisIntervalInput)"
@blur="threeAxisIntervalChange(threeAxisIntervalInput)"
v-model="threeAxisIntervalInput"
:label="'3axis-grid'"
>
<p slot="append" style="margin-right: 0;" small>
g
</p>
</va-input>
</div>
<div class="row flex ma-0 pa-0" v-if="developer_mode === true">
</div> -->
<div class="row flex ma-0 pa-0" v-if="developerMode === true">
<canvas-chart-filter :chartID="chartID" :filterIndex="0" />
<canvas-chart-filter :chartID="chartID" :filterIndex="1" />
<canvas-chart-filter :chartID="chartID" :filterIndex="2" />
@@ -123,6 +137,8 @@ import CanvasChartRealTimeDisplay from '@/components/task/content/chart/CanvasCh
import { mapActions } from 'vuex'
import taskTypes from '@/store/modules/task/content/types'
import CanvasChartRealTimeCalculation from './CanvasChartRealTimeCalculation.vue'
import { dataStreamBuffer } from '@/data/task/DataStreamBuffer'
import configTable from '@/data/config-table/index.js'
export default {
name: 'CanvasChart',
@@ -155,8 +171,15 @@ export default {
},
},
computed: {
chartInfo () {
if (this.data === undefined || this.data === null) return ''
if (this.data.mappingID === undefined || this.data.mappingID === '-1') return ''
const device = this.deviceListNew.find(ele => String(ele.memory_board) === String(this.data.mappingID))
const deviceMode = configTable.getModeConfig(device.library_name, device.configuration.MODE).name
return `${device.name}_[${device.memory_board}] | MAC_${device.mac_address.toUpperCase()} | ${this.data.createdBy} chart: ${deviceMode}`
},
...mapFields('', [
'developer_mode',
'developerMode',
]),
...mapFields('taskContent', [
'chartData',
@@ -183,6 +206,7 @@ export default {
dataZoomEnd: 100,
captured: false,
calClicked: false,
dataStreamBuffer: dataStreamBuffer,
}
},
methods: {
@@ -190,13 +214,15 @@ export default {
this.calClicked = clicked
},
captureChart: function () {
// count same ID in chartData
const captureTimes = String(Object.keys(this.chartData).filter(ele => ele.includes(String(this.data.chartID))).length)
const newData = Object.assign({}, this.data)
this.chartData[String(newData.chartID) + '-1'] = newData
this.chartData[String(newData.chartID) + '-1'].captured = true
this.chartData[String(newData.chartID) + '-1'].cardName = this.chartData[String(newData.chartID) + '-1'].cardName + ' - captured'
this.chartData[String(newData.chartID) + '-1'].chartID = String(newData.chartID) + '-1'
this.chartData[String(this.data.chartID) + '-' + captureTimes] = newData
this.chartData[String(this.data.chartID) + '-' + captureTimes].captured = true
this.chartData[String(this.data.chartID) + '-' + captureTimes].cardName += ' - captured -' + captureTimes
this.chartData[String(this.data.chartID) + '-' + captureTimes].createdBy = 'capture'
this.chartData[String(this.data.chartID) + '-' + captureTimes].chartID = String(this.data.chartID) + '-' + captureTimes
this.taskContentChartPanelKey++
// console.log(this.chartData[String(newData.chartID) + '-1'])
},
updateZoom: function (e) {
// console.log(e)
@@ -208,7 +234,7 @@ export default {
this.dataZoomEnd = e.end
}
},
timeIntervalChange: function (val) {
timeIntervalChange: async function (val) {
if (!isNaN(parseInt(val))) {
this.chartData[this.chartID].xAxis.forEach(x => {
if (x.type === 'time') {
@@ -219,10 +245,11 @@ export default {
this.timeIntervalInput = 'auto'
this.chartData[this.chartID].xAxis.forEach(x => {
if (x.type === 'time') {
x.interval = 500 * 1000
x.interval = null
}
})
}
await this.taskContentChartSaveToCache({ controllerID: taskInfo.getTaskInfo().controllerID })
},
xIntervalChange: async function (val) {
if (!isNaN(parseInt(val))) {
@@ -250,13 +277,13 @@ export default {
} else {
y.interval = val * 1000
}
const maxList = []
const minList = []
// TODO: follow this way to iterate the deviceID
y.seriesIndex.forEach(i => {
maxList.push(Math.max(...this.chartData[this.chartID].series[i].data.map(p => p[1])))
minList.push(Math.min(...this.chartData[this.chartID].series[i].data.map(p => p[1])))
})
// const maxList = []
// const minList = []
// y.seriesIndex.forEach(i => {
// maxList.push(Math.max(...this.chartData[this.chartID].series[i].data.map(p => p[1])))
// minList.push(Math.min(...this.chartData[this.chartID].series[i].data.map(p => p[1])))
// })
// const max = Math.max(maxList)
// const min = Math.min(minList)
// const center = (max + min) / 2
@@ -267,12 +294,10 @@ export default {
}
})
} else {
this.timeIntervalInput = 'auto'
this.yIntervalInput = 'auto'
this.chartData[this.chartID].yAxis.forEach(y => {
if (parseInt(y.channel) <= 255) {
// y.interval = null
// y.max = 'dataMax'
// y.min = 'dataMin'
y.interval = null
}
})
}
@@ -375,7 +400,6 @@ export default {
this.data.dataZoom[0].end = this.dataZoomEnd
this.data.dataZoom[1].start = this.data.dataZoom[0].start
this.data.dataZoom[1].end = this.data.dataZoom[0].end
// console.log(this.data.dataZoom)
this.$refs.CanvasChartRealTimeDisplay.matchData(this.data)
},
switchModeButton: function (dataMode, gridIndex, channelIndex) {
@@ -1,29 +1,42 @@
<template>
<div>
<div class="row xs12 sm12 lg10 xl10 pa-2">
<va-button v-if="integralClicked && (mode_name==='Chronoamperometric' || mode_name==='I-T Graph' || mode_name==='I-V Curve')" color="danger" class="mb-2" @click="clickIntegral" small>
To Raw Mode
<div class="xs12 sm12 lg12 xl12" style="text-align: end;">
<!-- <img v-if="!integralClicked && (mode_name==='Chronoamperometric' || mode_name==='I-T Graph' || mode_name==='I-V Curve')" src='@/assets/img/toolbox/integral.svg' @click="clickIntegral"> -->
<va-button :flat="true" class="pa-0 ma-0 mr-2" v-if="xlogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="danger" @click="clickXLog" small>
<!-- To Raw Mode -->
<img src='@/assets/img/toolbox/LogX_clicked.svg'>
</va-button>
<va-button :disabled="disableInt" v-if="!integralClicked && (mode_name==='Chronoamperometric' || mode_name==='I-T Graph' || mode_name==='I-V Curve')" color="primary" class="mb-2" @click="clickIntegral" small>
To Integral Mode
<va-button :flat="true" class="pa-0 ma-0 mr-2" :disabled="disableLog" v-if="!xlogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="#ffffff" @click="clickXLog" small>
<!-- To log Mode (x-axis) -->
<img src='@/assets/img/toolbox/LogX.svg'>
</va-button>
<va-button v-if="xlogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="danger" class="mb-2" @click="clickXLog" small>
To Raw Mode
<va-button :flat="true" class="pa-0 ma-0 mr-2" v-if="ylogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="danger" @click="clickYLog" small>
<!-- To Raw Mode -->
<img src='@/assets/img/toolbox/LogY_clicked.svg'>
</va-button>
<va-button :disabled="disableLog" v-if="!xlogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="primary" class="mb-2" @click="clickXLog" small>
To log Mode (x-axis)
<va-button :flat="true" :disabled="disableLog" class="pa-0 ma-0 mr-2" v-if="!ylogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="#ffffff" @click="clickYLog" small>
<!-- To log Mode (y-axis) -->
<img src='@/assets/img/toolbox/LogY.svg'>
</va-button>
<va-button v-if="ylogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="danger" class="mb-2" @click="clickYLog" small>
To Raw Mode
<va-button :flat="true" class="pa-0 ma-0 mr-2" v-if="integralClicked && (mode_name==='Chronoamperometric' || mode_name==='I-T Graph' || mode_name==='I-V Curve')" color="danger" @click="clickIntegral" small>
<!-- To Raw Mode -->
<img src='@/assets/img/toolbox/integral_clicked.svg'>
</va-button>
<va-button :disabled="disableLog" v-if="!ylogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="primary" class="mb-2" @click="clickYLog" small>
To log Mode (y-axis)
<va-button class="pa-0 ma-0 mr-2" :flat="true" :disabled="disableInt" v-if="!integralClicked && (mode_name==='Chronoamperometric' || mode_name==='I-T Graph' || mode_name==='I-V Curve')" color="#ffffff" @click="clickIntegral" small>
<!-- To Integral Mode -->
<img src='@/assets/img/toolbox/integral.svg'>
</va-button>
<va-button v-if="diffClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="danger" class="mb-2" @click="clickDiff" small>
To Raw Mode
<va-button :flat="true" class="pa-0 ma-0 mr-2" v-if="diffClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="danger" @click="clickDiff" small>
<!-- To Raw Mode -->
<img src='@/assets/img/toolbox/dx_clicked.svg'>
</va-button>
<va-button :disabled="disableDiff" v-if="!diffClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="primary" class="mb-2" @click="clickDiff" small>
To Differential Mode
<va-button :flat="true" :disabled="disableDiff" class="pa-0 ma-0 mr-2" v-if="!diffClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="#ffffff" @click="clickDiff" small>
<!-- To Differential Mode -->
<img src='@/assets/img/toolbox/dx.svg'>
</va-button>
<va-button :flat="true" :disabled="calClicked" class="pa-0 ma-0" color="#ffffff" @click="captureChart" small>
<!-- CAPTURE -->
<img src='@/assets/img/toolbox/capture.svg'>
</va-button>
</div>
<div class="row xs12 sm12 lg6 xl6 pa-2" v-if="diffClicked">
@@ -47,7 +60,7 @@
import { mapFields } from 'vuex-map-fields'
import { mapActions } from 'vuex'
import taskTypes from '@/store/modules/task/content/types'
import paramTable from '@/data/config-table/index'
import configTable from '@/data/config-table/index'
// import newTooltip from '@/factories/chart/tooltipFactory'
import { getTimeFormatter } from '@/store/modules/task/content/actions/chartAct'
import sgFilter from '@/data/SGFilter'
@@ -64,18 +77,17 @@ export default {
},
computed: {
...mapFields('', [
'developer_mode',
'developerMode',
]),
...mapFields('taskContent', [
'chartData',
'taskContentChartKey',
'taskContentChartPanelKey',
'deviceListNew',
]),
},
data () {
return {
info: null,
paramTable: paramTable,
rawData: null,
mode_name: '',
xName: '',
@@ -88,6 +100,7 @@ export default {
disableDiff: false,
disableLog: false,
disableInt: false,
calClicked: false,
sgFilterArgument: {
windowSize: 5,
polynomial: 3,
@@ -107,6 +120,12 @@ export default {
},
},
methods: {
captureChart: function () {
this.$emit('captureChart')
},
getClicked: function (clicked) {
this.calClicked = clicked
},
// Do arithmetic operations triggered by button(raw, integral, log)
watchHandler: function () {
// this.data need to be deep copy from rawData, since we don't want to modify the source(chartData[])
@@ -221,19 +240,23 @@ export default {
const dataX = []
const dataY = []
const time = []
for (index = 0; index < dataLength; index++) {
const dsample = 1
const m = parseInt((this.sgFilterArgument.windowSize - 1) / 2)
for (index = 0; index < dataLength; index += dsample) {
dataX.push(seriesData[index][0])
dataY.push(seriesData[index][1])
dataY.push(seriesData[index][1] * 1e-9)
time.push(seriesData[index][2])
}
// console.log(time[time.length - 1], time[0])
// console.log(dataX.length, time[time.length - 1] - time[0], dataX.length * 1e6 / (time[time.length - 1] - time[0]))
// console.log('dataX', dataX)
// console.log('dataY', dataY)
// console.log('time', time)
const filteredData = sgFilter(dataY, this.sgFilterArgument.windowSize, this.sgFilterArgument.polynomial)
// console.log('filterdData', filteredData)
const filteredData = sgFilter(dataY, this.sgFilterArgument.windowSize, this.sgFilterArgument.polynomial, this.getSampleRate())
for (index = 0; index < dataLength; index++) {
_data.push([dataX[index], filteredData[index], time[index]])
for (index = 0; index < filteredData.length; index++) {
_data.push([dataX[index + m], filteredData[index], time[index + m]])
}
// for (index = 0; index < dataLength; index++) {
@@ -261,29 +284,26 @@ export default {
const dataRaw = this.data.series[0].data
if (this.integralClicked || this.xlogClicked || this.ylogClicked || this.diffClicked) {
this.data.series[0].data = _data
this.$emit('getClicked', true)
this.getClicked(true)
// console.log(this.data.series[0].data[this.data.series[0].data.length - 1])
} else {
this.$emit('getClicked', false)
this.getClicked(false)
}
this.data.xAxis[0].type = 'value'
if (this.xName !== 'TIME') {
// console.log('not time')
this.data.xAxis[0].max = (value) => {
if (value.max < 0) {
return value.max - 0.1 * value.max
return value.max - 0.05 * value.max
}
if (value.max + 0.1 * value.max > 5e6) {
return 5e6
}
return value.max + 0.1 * value.max
return value.max + 0.05 * value.max
}
this.data.yAxis[0].max = (value) => {
if (value.max < 0) {
return value.max - 0.1 * value.max
return value.max - 0.05 * value.max
}
return value.max + 0.1 * value.max
return value.max + 0.05 * value.max
}
}
if (this.integralClicked) {
@@ -400,13 +420,27 @@ export default {
var value = this.data.series[0].data[(this.data.series[0].data).length - 1][1]
return this.yName + ': ' + value + ' ' + this.yUnit
},
getSampleRate: function () {
try {
const deviceMappingID = this.chartData[this.chartID].mappingID
const device = this.deviceListNew.find(ele => ele.memory_board === deviceMappingID)
const deviceConfig = configTable.getConfig(deviceMappingID)
const voltStep = deviceConfig.VOLT_STEP.outputReadabilityData(device.configuration.VOLT_STEP)
const sampleRate = deviceConfig.SAMPLE_RATE.outputReadabilityData(device.configuration.SAMPLE_RATE)
return (1 / (voltStep / 1000)) * sampleRate
} catch (e) {
console.log('getSampleRateERROR', e)
return 1
}
},
...mapActions('taskContent', [
taskTypes.chart.saveToCache,
]),
},
async mounted () {
this.rawData = this.chartData[this.chartID]
// const test = [3.0, 12.9, 22.6, 32.10000000000001, 41.4, 50.5, 59.400000000000006, 68.1, 76.6, 84.9, 93.0, 100.9, 108.60000000000001, 116.1, 123.39999999999999, 130.5, 137.4, 144.10000000000002, 150.6, 156.9, 163.0, 168.9, 174.60000000000002, 180.10000000000002, 185.4, 190.5, 195.39999999999998, 200.1, 204.59999999999997, 208.90000000000003, 213.0, 216.89999999999998, 220.59999999999997, 224.09999999999997, 227.40000000000003, 230.5, 233.39999999999998, 236.1, 238.6, 240.90000000000003, 243.0, 244.9, 246.6, 248.10000000000002, 249.40000000000003, 250.5, 251.40000000000003, 252.09999999999997, 252.6, 252.9, 253.0, 252.90000000000003, 252.59999999999997, 252.10000000000002, 251.39999999999998, 250.5, 249.39999999999992, 248.09999999999997, 246.60000000000002, 244.89999999999998, 243.0, 240.89999999999992, 238.59999999999997, 236.10000000000002, 233.39999999999992, 230.5, 227.39999999999992, 224.10000000000002, 220.60000000000002, 216.89999999999992, 213.0, 208.89999999999986, 204.5999999999999, 200.10000000000002, 195.39999999999998, 190.5, 185.39999999999998, 180.0999999999999, 174.60000000000002, 168.89999999999998, 163.0, 156.89999999999998, 150.5999999999999, 144.10000000000002, 137.39999999999998, 130.5, 123.40000000000009, 116.10000000000002, 108.60000000000002, 100.89999999999986, 93.0, 84.90000000000009, 76.60000000000002, 68.10000000000002, 59.399999999999864, 50.5, 41.399999999999864, 32.09999999999991, 22.59999999999991, 12.899999999999977]
// console.log('sgFilter', sgFilter(test, 5, 2, 10))
// console.log('x', this.rawData.xAxis.length)
// if (this.mode_name === 'I-V Curve') {
// this.rawData.xAxis[0].boundaryGap = [0, '5%']
@@ -1,51 +1,88 @@
<template>
<div>
<!-- cycle display -->
<div v-if="data !== null && data.cycle > 0" class="row flex sm12 xl12 md12 xs12 align--center my-0 py-0">
<div style="text-align: right;">
<h1 style="color: #707ee7;"> cycle <span style="color: white; background-color: #707ee7; border-radius: 40%;" class="pa-2">{{ data.cycle }}</span></h1>
</div>
</div>
<div v-for="(chart, chartIndex) in realTime" :key="'c'+chartIndex">
<div v-for="(grid, gridIndex) in chart" :key="'s'+gridIndex" class="row ma-0 pa-0">
<div class="col flex xs0 sm0 lg0 md0 xl0 xxl1"/>
<div class="col flex xs2 sm2 lg2 md2 xl2 xxl1" pa-0 ma-0>
<p color="primary" style="text-align: right;">{{ grid.name }}</p>
</div>
<!-- value (y-axis) -->
<div class="col flex sm2 xl2 md2 xs2">
<!-- Whole Real-time Display Tool here -->
<div v-for="(plot, plotIndex) in realTime" :key="plotIndex">
<div v-for="(curve, curveIndex) in plot" :key="plotIndex + '-' + curveIndex" class="row ma-0 pa-0">
<!-- cycle -->
<div class="mt-1" style="width: 75px;" v-show="data !== null && data.cycle > 0">
<va-input
label="y-value"
disable="disable"
v-model="grid.yValue"
label="cycle no."
v-model="data.cycle"
disabled
/>
</div>
<!-- unit (y-axis) -->
<div class="col flex sm2 xl2 md2 xs2">
<va-select
label="y-unit"
v-model="grid.yUnit"
:options="grid.yUnitOption"
noClear
/>
<!-- y-axis -->
<div class="d-flex flex-row mt-1 ml-1">
<!-- value (y-axis) -->
<div style="width: 75px;">
<va-input
label="y-axis"
v-model="curve.yValue"
disabled
/>
</div>
<!-- unit (y-axis) -->
<div style="width: 75px;">
<va-select
v-model="curve.yUnit"
:options="curve.yUnitOption"
@input="changeUnit('y', plotIndex, curveIndex)"
noClear
/>
</div>
</div>
<div class="col flex sm1 xl1 md1 xs1"></div>
<!-- value (x-axis) -->
<div class="col flex sm2 xl2 md2 xs2">
<va-input
label="x-value"
disable="disable"
v-model="grid.xValue"
/>
<!-- x-axis -->
<div class="d-flex flex-row mt-1 ml-1">
<!-- value (x-axis) -->
<div style="width: 75px;">
<va-input
label="x-axis"
v-model="curve.xValue"
disabled
/>
</div>
<!-- unit (x-axis) -->
<div style="width: 75px;">
<va-select
v-model="curve.xUnit"
:options="curve.xUnitOption"
@input="changeUnit('x', plotIndex, curveIndex)"
noClear
/>
</div>
</div>
<!-- unit (x-axis) -->
<div class="col flex sm2 xl2 md2 xs2">
<va-select
label="x-unit"
v-model="grid.xUnit"
:options="grid.xUnitOption"
noClear
/>
<!-- intervel -->
<div class="d-flex flex-row mt-1 ml-1">
<!-- interval (y-axis) -->
<div class="ml-1" style="width: 80px;">
<va-input
v-show="!curveIndex"
v-model="curve.yInterval"
label="y-grid"
@focus="$event.target.select()"
@keyup.enter="setInterval('y', plotIndex, curveIndex, curve.yInterval)"
@blur="setInterval('y', plotIndex, curveIndex, curve.yInterval)"
>
<p slot="append" style="margin-right: 0;" small>
{{ curve.yUnit }}
</p>
</va-input>
</div>
<!-- interval (x-axis) -->
<div class="ml-1" style="width: 80px;">
<va-input
v-show="!curveIndex"
v-model="curve.xInterval"
label="x-grid"
@focus="$event.target.select()"
@keyup.enter="setInterval('x', plotIndex, curveIndex, curve.xInterval)"
@blur="setInterval('x', plotIndex, curveIndex, curve.xInterval)"
>
<p slot="append" style="margin-right: 0;" small>
{{ curve.xUnit }}
</p>
</va-input>
</div>
</div>
</div>
</div>
@@ -57,6 +94,9 @@ import { mapFields } from 'vuex-map-fields'
import { chartRouter } from './CanvasChartTable'
import configTable from '@/data/config-table/index.js'
import newTooltip from '@/factories/chart/tooltipFactory'
import { mapActions } from 'vuex'
import { taskInfo } from '../../../../data/task/TaskInfo'
import taskTypes from '@/store/modules/task/content/types'
export default {
name: 'CanvasChartRealTimeDisplay',
@@ -81,105 +121,122 @@ export default {
}
},
methods: {
// for user to choose wanted unit
setUnit: function (gridIndex, channelIndex) {
// store the setting in cache
...mapActions('taskContent', [
taskTypes.chart.saveToCache,
]),
getDeviceMode: function () {
const device = this.deviceListNew.find(ele => String(ele.memory_board) === String(this.chartData[this.chartID].mappingID))
if (device === undefined) return
return device.configuration.MODE
},
// set a new display tool
setRealTime: function (plotIndex, curveIndex) {
// construct realTime object, i.e., record the coressponding value and unit
// the formate imitates the data.gridSource
if (this.data !== undefined && this.data.gridSource !== undefined) {
const _xPhysicsQuantity = this.data.gridSource[gridIndex][channelIndex].name.split('_')[0].at(-1)
const _yPhysicsQuantity = this.data.gridSource[gridIndex][channelIndex].name.split('_')[1].at(-1)
let _xPhysicsQuantity = this.data.gridSource[plotIndex][curveIndex].name.split('_')[0].split('-').at(-1)
let _yPhysicsQuantity = this.data.gridSource[plotIndex][curveIndex].name.split('_')[1].split('-').at(-1)
// Potential
if (_xPhysicsQuantity === 'P') _xPhysicsQuantity = 'V'
if (_yPhysicsQuantity === 'P') _yPhysicsQuantity = 'V'
const [_xAxis, _yAxis] = this.chartRouter.getChartTable(_xPhysicsQuantity, _yPhysicsQuantity)
const _realTime = JSON.parse(JSON.stringify(this.realTime))
const _newChannel = {}
const _newCurve = {}
// set name, sourceIndex in data.series
_newChannel.name = this.data.gridSource[gridIndex][channelIndex].name
_newChannel.seriesSource = this.data.series.findIndex((ele) => ele.name === _newChannel.name)
_newCurve.name = this.data.gridSource[plotIndex][curveIndex].name
_newCurve.seriesSource = this.data.series.findIndex((ele) => ele.name === _newCurve.name)
// set x-axis
_newChannel.xValue = 0
_newChannel.xUnit = _xAxis.default.defaultUnit
_newChannel.xScale = _xAxis.default.unit
_newChannel.xUnitOption = Object.keys(_xAxis.default.unit)
_newChannel.xName = _xAxis.default.name
_newCurve.xValue = 0
_newCurve.xUnit = (typeof _xAxis.default.defaultUnit === 'function') ? _xAxis.default.defaultUnit(this.getDeviceMode()) : _xAxis.default.defaultUnit
_newCurve.xScaleOption = _xAxis.default.unit
_newCurve.xUnitOption = Object.keys(_xAxis.default.unit)
_newCurve.xName = _xAxis.default.name
_newCurve.xInterval = 'auto'
// set y-axis
_newChannel.yValue = 0
_newChannel.yUnit = _yAxis.default.defaultUnit
_newChannel.yScale = _yAxis.default.unit
_newChannel.yUnitOption = Object.keys(_yAxis.default.unit)
_newChannel.yName = _yAxis.default.name
_newCurve.yValue = 0
_newCurve.yUnit = (typeof _yAxis.default.defaultUnit === 'function') ? _yAxis.default.defaultUnit(this.getDeviceMode()) : _yAxis.default.defaultUnit
_newCurve.yScaleOption = _yAxis.default.unit
_newCurve.yUnitOption = Object.keys(_yAxis.default.unit)
_newCurve.yName = _yAxis.default.name
_newCurve.yInterval = 'auto'
// set functional
_newChannel.functional = 'default'
_newCurve.functional = 'default'
// padding
while (gridIndex >= _realTime.length) {
while (plotIndex >= _realTime.length) {
_realTime.push([])
}
while (channelIndex >= _realTime[gridIndex].length) {
_realTime[gridIndex].push({})
while (curveIndex >= _realTime[plotIndex].length) {
_realTime[plotIndex].push({})
}
// merge the additional part into original part
_realTime[gridIndex][channelIndex] = _newChannel
_realTime[plotIndex][curveIndex] = _newCurve
this.realTime = _realTime
}
},
// set the interval size keyed by user
setInterval: async function (axis, plotIndex, curveIndex, val) {
if (!isNaN(val)) {
const scaleOption = this.realTime[plotIndex][curveIndex][axis + 'ScaleOption']
const unit = this.realTime[plotIndex][curveIndex][axis + 'Unit']
this.chartData[this.chartID][axis + 'Axis'][plotIndex].interval = val * scaleOption[unit]
} else {
this.chartData[this.chartID][axis + 'Axis'][plotIndex].interval = 'hi' // I know it looks weird, but this one is necessesary
this.chartData[this.chartID][axis + 'Axis'][plotIndex].interval = null
this.realTime[plotIndex][curveIndex][axis + 'Interval'] = 'auto'
}
await this.taskContentChartSaveToCache({ controllerID: taskInfo.getTaskInfo().controllerID })
},
// record the latest data as the real time value
updateValue: function () {
if ((this.realTime.length === 0)) {
return
}
for (let gridIndex = 0; gridIndex < this.realTime.length; gridIndex++) {
for (let channelIndex = 0; channelIndex < this.realTime[gridIndex].length; channelIndex++) {
for (let plotIndex = 0; plotIndex < this.realTime.length; plotIndex++) {
for (let curveIndex = 0; curveIndex < this.realTime[plotIndex].length; curveIndex++) {
// miss the source of data -> try to find the source
if (this.realTime[gridIndex][channelIndex].seriesSource === -1) {
this.realTime[gridIndex][channelIndex].seriesSource = this.data.series.findIndex((ele) => ele.name === this.realTime[gridIndex][channelIndex].name)
if (this.realTime[plotIndex][curveIndex].seriesSource === -1) {
this.realTime[plotIndex][curveIndex].seriesSource = this.data.series.findIndex((ele) => ele.name === this.realTime[plotIndex][curveIndex].name)
}
// the device is active now --> update the real time value
if (this.data.series[this.realTime[gridIndex][channelIndex].seriesSource] !== undefined && this.data.series[this.realTime[gridIndex][channelIndex].seriesSource].data !== undefined && this.data.series[this.realTime[gridIndex][channelIndex].seriesSource].data.length > 0) {
this.realTime[gridIndex][channelIndex].xValue = (this.data.series[this.realTime[gridIndex][channelIndex].seriesSource].data.at(-1)[0] / this.realTime[gridIndex][channelIndex].xScale[this.realTime[gridIndex][channelIndex].xUnit]).toFixed(3)
this.realTime[gridIndex][channelIndex].yValue = (this.data.series[this.realTime[gridIndex][channelIndex].seriesSource].data.at(-1)[1] / this.realTime[gridIndex][channelIndex].yScale[this.realTime[gridIndex][channelIndex].yUnit]).toFixed(3)
}
}
}
},
// match the number of real time display bar to data.gridSource
matchChart: function () {
for (let gridIndex = 0; gridIndex < this.data.gridSource.length; gridIndex++) {
if (this.data.gridSource[gridIndex] !== undefined) {
for (let channelIndex = 0; channelIndex < this.data.gridSource[gridIndex].length; channelIndex++) {
if (gridIndex >= this.realTime.length) {
this.setUnit(gridIndex, channelIndex)
} else if (channelIndex >= this.realTime[gridIndex].length) {
this.setUnit(gridIndex, channelIndex)
}
if (this.data.series[this.realTime[plotIndex][curveIndex].seriesSource] !== undefined &&
this.data.series[this.realTime[plotIndex][curveIndex].seriesSource].data !== undefined &&
this.data.series[this.realTime[plotIndex][curveIndex].seriesSource].data.length > 0) {
this.realTime[plotIndex][curveIndex].xValue = (this.data.series[this.realTime[plotIndex][curveIndex].seriesSource].data.at(-1)[0] / this.realTime[plotIndex][curveIndex].xScaleOption[this.realTime[plotIndex][curveIndex].xUnit]).toFixed(3)
this.realTime[plotIndex][curveIndex].yValue = (this.data.series[this.realTime[plotIndex][curveIndex].seriesSource].data.at(-1)[1] / this.realTime[plotIndex][curveIndex].yScaleOption[this.realTime[plotIndex][curveIndex].yUnit]).toFixed(3)
}
}
}
},
// match the formatter to current unit and functional
matchFormatter: function () {
for (let gridIndex = 0; gridIndex < this.realTime.length; gridIndex++) {
for (let channelIndex = 0; channelIndex < this.realTime[gridIndex].length; channelIndex++) {
if (channelIndex === 0) {
const _xUnit = this.realTime[gridIndex][channelIndex].xUnit
const _yUnit = this.realTime[gridIndex][channelIndex].yUnit
const _xScale = this.realTime[gridIndex][channelIndex].xScale[this.realTime[gridIndex][channelIndex].xUnit]
const _yScale = this.realTime[gridIndex][channelIndex].yScale[this.realTime[gridIndex][channelIndex].yUnit]
updateFormatter: function () {
for (let plotIndex = 0; plotIndex < this.realTime.length; plotIndex++) {
for (let curveIndex = 0; curveIndex < this.realTime[plotIndex].length; curveIndex++) {
if (curveIndex === 0) {
const _xUnit = this.realTime[plotIndex][curveIndex].xUnit
const _yUnit = this.realTime[plotIndex][curveIndex].yUnit
const _xScale = this.realTime[plotIndex][curveIndex].xScaleOption[this.realTime[plotIndex][curveIndex].xUnit]
const _yScale = this.realTime[plotIndex][curveIndex].yScaleOption[this.realTime[plotIndex][curveIndex].yUnit]
// update xAxis.formatter
if (this.realTime[gridIndex][channelIndex].xName === 'Time') {
this.data.xAxis[gridIndex].axisLabel.formatter = this.timeFormatter
if (this.realTime[plotIndex][curveIndex].xName === 'Time') {
this.data.xAxis[plotIndex].axisLabel.formatter = this.timeFormatter
} else {
this.data.xAxis[gridIndex].axisLabel.formatter = function (val) {
return parseFloat(val / _xScale).toFixed(2) + _xUnit
this.data.xAxis[plotIndex].axisLabel.formatter = function (val) {
return parseFloat(val / _xScale).toFixed(3) + _xUnit
}
}
// update yAxis.formatter
if (this.realTime[gridIndex][channelIndex].yName === 'Time') {
this.data.yAxis[gridIndex].axisLabel.formatter = this.timeFormatter
if (this.realTime[plotIndex][curveIndex].yName === 'Time') {
this.data.yAxis[plotIndex].axisLabel.formatter = this.timeFormatter
} else {
this.data.yAxis[gridIndex].axisLabel.formatter = function (val) {
return parseFloat(val / _yScale).toFixed(2) + _yUnit
this.data.yAxis[plotIndex].axisLabel.formatter = function (val) {
return parseFloat(val / _yScale).toFixed(3) + _yUnit
}
}
// update tooltip.formatter
@@ -188,30 +245,52 @@ export default {
}
}
},
changeUnit: function (axis, plotIndex, curveIndex) {
this.updateValue()
this.updateFormatter()
this.setInterval(axis, plotIndex, curveIndex, 'auto')
},
// match the number of real time display bar to data.gridSource
matchChart: function () {
for (let plotIndex = 0; plotIndex < this.data.gridSource.length; plotIndex++) {
if (this.data.gridSource[plotIndex] !== undefined) {
for (let curveIndex = 0; curveIndex < this.data.gridSource[plotIndex].length; curveIndex++) {
if (plotIndex >= this.realTime.length) {
this.setRealTime(plotIndex, curveIndex)
} else if (curveIndex >= this.realTime[plotIndex].length) {
this.setRealTime(plotIndex, curveIndex)
}
}
}
}
},
// match the data to operated data in CanvasChart.vue
matchData: function (canvasChartData) {
this.data = canvasChartData
},
// match the functional to operated data in CanvasChart.vue
matchFunctional: function (newFunctional, gridIndex, channelIndex) {
if (this.realTime[gridIndex][channelIndex] === undefined) return
if (this.realTime[gridIndex][channelIndex].functional === newFunctional) return
const _currChannel = this.realTime[gridIndex][channelIndex]
const _xPhysicsQuantity = this.data.gridSource[gridIndex][channelIndex].name.split('_')[0].at(-1)
const _yPhysicsQuantity = this.data.gridSource[gridIndex][channelIndex].name.split('_')[1].at(-1)
matchFunctional: function (newFunctional, plotIndex, curveIndex) {
if (this.realTime[plotIndex][curveIndex] === undefined) return
if (this.realTime[plotIndex][curveIndex].functional === newFunctional) return
const _currCurve = this.realTime[plotIndex][curveIndex]
let _xPhysicsQuantity = this.data.gridSource[plotIndex][curveIndex].name.split('_')[0].split('-').at(-1)
let _yPhysicsQuantity = this.data.gridSource[plotIndex][curveIndex].name.split('_')[1].split('-').at(-1)
// Potential
if (_xPhysicsQuantity === 'P') _xPhysicsQuantity = 'V'
if (_yPhysicsQuantity === 'P') _yPhysicsQuantity = 'V'
const [_xAxis, _yAxis] = this.chartRouter.getChartTable(_xPhysicsQuantity, _yPhysicsQuantity)
_currChannel.functional = newFunctional
_currCurve.functional = newFunctional
// set x-axis
_currChannel.xUnit = _xAxis.default.defaultUnit
_currChannel.xScale = _xAxis.default.unit
_currChannel.xUnitOption = Object.keys(_xAxis.default.unit)
_currChannel.xName = _xAxis.default.name
_currCurve.xUnit = (typeof _xAxis.default.defaultUnit === 'function') ? _xAxis.default.defaultUnit(this.getDeviceMode()) : _xAxis.default.defaultUnit
_currCurve.xScaleOption = _xAxis.default.unit
_currCurve.xUnitOption = Object.keys(_xAxis.default.unit)
_currCurve.xName = _xAxis.default.name
// set y-axis
_currChannel.yUnit = _yAxis[newFunctional].defaultUnit
_currChannel.yScale = _yAxis[newFunctional].unit
_currChannel.yUnitOption = Object.keys(_yAxis[newFunctional].unit)
_currChannel.yName = _yAxis[newFunctional].name
_currCurve.yUnit = (typeof _yAxis[newFunctional].defaultUnit === 'function') ? _yAxis[newFunctional].defaultUnit(this.getDeviceMode()) : _yAxis[newFunctional].defaultUnit
_currCurve.yScaleOption = _yAxis[newFunctional].unit
_currCurve.yUnitOption = Object.keys(_yAxis[newFunctional].unit)
_currCurve.yName = _yAxis[newFunctional].name
},
timeFormatter: function (val) {
let label = ''
@@ -243,16 +322,16 @@ export default {
this.data = this.chartData[this.chartID]
},
watch: {
data: {
'data.series': {
handler: function () {
this.updateValue()
this.matchChart()
},
deep: true,
},
realTime: {
'data.gridSource': {
handler: function () {
this.matchFormatter()
this.matchChart()
this.updateFormatter()
},
deep: true,
},
@@ -90,6 +90,7 @@ import { taskInfo } from '../../../../data/task/TaskInfo'
import { mapFields } from 'vuex-map-fields'
import { mapActions } from 'vuex'
import taskTypes from '@/store/modules/task/content/types'
import configTable from '../../../../data/config-table'
export default {
name: 'canvas-chart-source',
@@ -140,7 +141,8 @@ export default {
deviceSelectX: function () {
const channelOptions = []
const deviceInfo = this.deviceListNew.find(ele => ele.id === this.deviceSelectX.id)
// console.log(val)
// console.log('deviceInfo', deviceInfo.library_name, deviceInfo.configuration.MODE)
// console.log('sourceObj', Object.keys(sourceObj))
if (deviceInfo == null) {
this.channelSelectDisableX = true
} else if (deviceInfo.library_name.includes('Neulive')) {
@@ -182,11 +184,20 @@ export default {
})
this.channelSelectDisableX = false
} else if (deviceInfo.library_name.includes('Elite')) {
const sourceObj = configTable.getChannelConfig(String(deviceInfo.library_name), deviceInfo.configuration.MODE) // [{id:0 channel:'Current'}, {id:1, channel:'Voltage'}, ]
let channelSet
if (deviceInfo.library_name.includes('EIS') && deviceInfo.configuration.MODE === 0) {
channelSet = ['Zimag_Raw', 'Zreal_Raw', 'Frequency', 'Cycle', 'Zimag', 'Zreal', 'Impedance', 'Phase', 'Current', 'Level gain']
} else {
channelSet = deviceInfo.configuration.CHANNEL_LABEL
// channelSet = deviceInfo.configuration.CHANNEL_LABEL
channelSet = []
const keys = Object.keys(sourceObj)
for (let i = 0; i < keys.length; i++) {
const item = keys[i]
if (sourceObj[item].name !== 'Time' && sourceObj[item].name !== 'Cycle number') {
channelSet.push(String(sourceObj[item].name))
}
}
}
// console.log(channelSet)
channelSet.forEach((element, index) => {
@@ -250,11 +261,20 @@ export default {
})
this.channelSelectDisableY = false
} else if (deviceInfo.library_name.indexOf('Elite') >= 0) {
const sourceObj = configTable.getChannelConfig(String(deviceInfo.library_name), deviceInfo.configuration.MODE) // [{id:0 channel:'Current'}, {id:1, channel:'Voltage'}, ]
let channelSet
if (deviceInfo.library_name.includes('EIS') && deviceInfo.configuration.MODE === 0) {
channelSet = ['Zimag_Raw', 'Zreal_Raw', 'Frequency', 'Cycle', 'Zimag', 'Zreal', 'Impedance', 'Phase', 'Current', 'Level gain']
} else {
channelSet = deviceInfo.configuration.CHANNEL_LABEL
// channelSet = deviceInfo.configuration.CHANNEL_LABEL
channelSet = []
const keys = Object.keys(sourceObj)
for (let i = 0; i < keys.length; i++) {
const item = keys[i]
if (sourceObj[item].name !== 'Time' && sourceObj[item].name !== 'Cycle number') {
channelSet.push(String(sourceObj[item].name))
}
}
}
// console.log(channelSet)
channelSet.forEach((element, index) => {
@@ -329,7 +349,6 @@ export default {
} else if (this.deviceSelectY.name.indexOf('Time') >= 0) {
deviceNameY = 'Time'
}
this.taskContentChartRegister({
chartID: this.chartID,
gridIndex: gridIndex,
@@ -13,7 +13,7 @@ const chartTable = {
min: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
defaultUnit: 's',
downloadUnit: 'ms',
},
},
@@ -43,7 +43,7 @@ const chartTable = {
min: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
defaultUnit: 's',
downloadUnit: 'ms',
},
},
@@ -57,20 +57,20 @@ const chartTable = {
mA: 1e6,
A: 1e9,
},
defaultUnit: 'mA',
defaultUnit: (Mode) => { return (Mode === 10 || Mode === 11) ? 'nA' : 'mA' },
downloadUnit: 'mA',
},
// Q = ∫ I dt
integral: {
name: 'Charge',
unit: {
nC: 1e6,
uC: 1e9,
mC: 1e12,
C: 1e15,
nAh: 3600 * 1e6,
uAh: 1600 * 1e9,
mAh: 3600 * 1e12,
Ah: 3600 * 1e15,
},
defaultUnit: 'mC',
downloadUnit: 'mC',
defaultUnit: 'mAh',
downloadUnit: 'mAh',
},
},
],
@@ -86,14 +86,14 @@ const chartTable = {
min: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
defaultUnit: 's',
downloadUnit: 'ms',
},
},
// 1
{
default: {
name: 'Resistor',
name: 'Resistance',
unit: {
: 1,
Ω: 1e3,
@@ -105,6 +105,34 @@ const chartTable = {
},
},
],
V_V: [
// 0
{
default: {
name: 'Voltage',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
// 1
{
default: {
name: 'Voltage',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
],
V_I: [
// 0
{
@@ -152,19 +180,18 @@ const chartTable = {
mA: 1e6,
A: 1e9,
},
defaultUnit: 'mA',
defaultUnit: (Mode) => { return (Mode === 10 || Mode === 11) ? 'nA' : 'mA' },
downloadUnit: 'mA',
},
// Gm = dI/dV
differential: {
name: 'Transconductance',
unit: {
'mA/V': 1,
'A/V': 1e3,
'kA/V': 1e6,
'mA/mV': 1e-3,
'A/mV': 1,
},
defaultUnit: 'A/V',
downloadUnit: 'A/V',
defaultUnit: 'mA/mV',
downloadUnit: 'A',
},
// Power = ∫ I dv
integral: {
@@ -179,6 +206,94 @@ const chartTable = {
},
},
],
V_R: [
// 0
{
default: {
name: 'Voltage',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
// 1
{
default: {
name: 'Resistance',
unit: {
: 1,
Ω: 1e3,
: 1e6,
: 1e9,
},
defaultUnit: 'Ω',
downloadUnit: 'Ω',
},
},
],
I_R: [
// 0
{
default: {
name: 'Voltage',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
// 1
{
default: {
name: 'Current',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
A: 1e9,
},
defaultUnit: (Mode) => { return (Mode === 10) ? 'nA' : 'mA' },
downloadUnit: 'mA',
},
},
],
Zreal_Zimag: [
// 0
{
default: {
name: 'Z_real',
unit: {
: 1e-3,
Ω: 1,
: 1e3,
: 1e6,
},
downloadUnit: 'Ω',
defaultUnit: 'Ω',
},
},
// 1
{
default: {
name: 'Z_imag',
unit: {
: 1e-3,
Ω: 1,
: 1e3,
: 1e6,
},
downloadUnit: 'Ω',
defaultUnit: 'Ω',
},
},
],
}
export const chartRouter = {
getChartTable: (xAxis, yAxis) => {
@@ -21,11 +21,28 @@
</va-item-section>
<va-item-section class="ml-3" caption>
<va-item-label>
{{ `[${device.memory_board}]` }} {{ device.name }}
<!-- <va-button @click="getBattery(device)"> get battery </va-button> -->
<!-- <pre> {{ device.battery }} </pre> -->
<va-item-label v-if="parseInt((device.battery - 2900) / 10) >= 75">
{{ `[${device.memory_board}]` }} {{ device.name }} <va-icon class="ml-3 fa fa-battery-full" color="#5BC236"/> {{ (parseInt((device.battery - 2900) / 10) > 100 ? 100 : parseInt((device.battery - 2900) / 10)) + '%' }}
</va-item-label>
<va-item-label v-else-if="parseInt((device.battery - 2900) / 10) >= 50">
{{ `[${device.memory_board}]` }} {{ device.name }} <va-icon class="ml-3 fa fa-battery-three-quarters" color="#5BC236"/> {{ parseInt((device.battery - 2900) / 10) + '%' }}
</va-item-label>
<va-item-label v-else-if="parseInt((device.battery - 2900) / 10) >= 25">
{{ `[${device.memory_board}]` }} {{ device.name }} <va-icon class="ml-3 fa fa-battery-half" color="#F6B431"/> {{ parseInt((device.battery - 2900) / 10) + '%' }}
</va-item-label>
<va-item-label v-else-if="parseInt((device.battery - 2900) / 10) > 10">
{{ `[${device.memory_board}]` }} {{ device.name }} <va-icon class="ml-3 fa fa-battery-quarter" color="#DA244B"/> {{ parseInt((device.battery - 2900) / 10) + '%' }}
</va-item-label>
<va-item-label v-else>
{{ `[${device.memory_board}]` }} {{ device.name }} <va-icon class="ml-3 fa fa-battery-empty" color="#DA244B"/> <span style="color: red;"> low battery </span>
</va-item-label>
<!-- <va-item-label v-else>
{{ `[${device.memory_board}]` }} {{ device.name }} <va-icon class="ml-3 fa fa-battery-empty" color="#DA244B"/> {{ '0%' }}
</va-item-label> -->
<va-item-label caption>
{{ device.mac_address }}
{{ device.mac_address.toUpperCase() }}
</va-item-label>
</va-item-section>
</va-item>
@@ -36,6 +53,7 @@
<va-button @click.stop="start(device)" v-if="device.library_name.includes('Elite') && device.status !== 1" class="px-2 py-0 mr-0" color="success" small>START</va-button>
<va-button @click.stop="stop(device)" v-if="device.library_name.includes('Elite') && device.status === 1" class="px-2 py-0 mr-0" color="danger" small>STOP</va-button>
<va-button id="detectButton" @click.stop="detect(device)" v-if="device.library_name.includes('Elite')" color="primary" class="px-2 py-0 mr-0" small>DETECT</va-button>
<va-button @click.stop="show($event, device)" v-if="developerMode" color="warning" class="px-2 py-0 mr-0" small>Show</va-button>
</va-item-label>
</va-item-section>
</va-item>
@@ -65,6 +83,7 @@ import types from '@/store/modules/task/content/types'
import { taskInfo } from '../../../../data/task/TaskInfo'
import api from '@/data/api'
// import CanvasChart from '../chart/CanvasChart'
import { mapFields } from 'vuex-map-fields'
export default {
name: 'TaskDeviceList',
@@ -88,6 +107,9 @@ export default {
}
},
computed: {
...mapFields('', [
'developerMode',
]),
},
methods: {
mqttPub: function (topic, mes) {
@@ -151,6 +173,12 @@ export default {
this.$emit('detect', device)
this.pageToast('The device ' + device.name + ' has been detect.')
},
show: function (event, device) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'show_device_data/0',
device: device.memory_board,
}))
},
recoverDetectButton () {
document.getElementById('detectButton').className += ' no-dark-style-va-button'
},
@@ -16,7 +16,7 @@
/>
</div>
<div class="flex sm2 xl2 md2 xs2 px-0 mx-0 my-0 py-0 pl-2">
<va-button class="pa-0 ma-0 mt-2 circle-button" small color="dark" @click="showModal=true">
<va-button v-if="place != 'scheduler'" class="pa-0 ma-0 mt-2 circle-button" small color="dark" @click="showModal=true">
<va-icon
name="fa fa-info"
color="white"
@@ -81,6 +81,7 @@
:parameterName="name"
:inputValue="parameter[name]"
:disable="name === 'CTRL_HIGH_Z_15' && device && device.status === 0"
:syncParameter="parameterTable[name].syncParameter"
v-bind="parameterTable[name]"
@parameterChange="parameterChange"
@getParameter="getParameter"
@@ -156,6 +157,10 @@ export default {
type: Object,
default: null,
},
place: {
type: String,
default: '',
},
},
computed: {
parameterTable () {
@@ -197,7 +202,7 @@ export default {
}
},
...mapFields('', [
'developer_mode',
'developerMode',
]),
...mapFields('taskContent', [
'deviceListNew',
@@ -221,6 +226,7 @@ export default {
parameterValue (name) {
const value = this.parameter[name]
if (this.parameterTable[name].type === 'number') {
if (this.parameterTable[name].defaultUnit === undefined) return ''
const scale = this.parameterTable[name].unit[this.parameterTable[name].defaultUnit]
return ` ( ${this.parameterTable[name].outputReadabilityData(value, scale)} ${this.parameterTable[name].defaultUnit} )`
} else if (this.parameterTable[name].type === 'array') {
@@ -248,8 +254,10 @@ export default {
this.parameterChange('MODE', this.workingModeSelect.id)
// if device is idle, then setting highz when mode switch
if (this.deviceStatus === true && this.workingModeSelect.highz !== undefined) {
this.parameterChange('CTRL_HIGH_Z_15', this.workingModeSelect.highz)
if (this.deviceStatus === true) {
if (this.workingModeSelect.highz !== undefined) {
this.parameterChange('CTRL_HIGH_Z_15', this.workingModeSelect.highz)
}
}
}
},
@@ -262,7 +270,7 @@ export default {
},
mounted () {
// dev mode
// this.developer_mode === true
// this.developerMode === true
// ? this.workingModeOptions = this.workingModeDevOptions
// : this.workingModeOptions = this.workingModeNoDevOptions
this.workingModeOptions = this.parameterTable.MODE_OPTIONS
@@ -270,6 +278,13 @@ export default {
this.workingModeSelect = (this.parameter.MODE !== undefined) ? this.workingModeOptions.find(ele => ele.id === this.parameter.MODE) : this.workingModeOptions[0]
},
watch: {
parameter: {
deep: true,
handler: function () {
// refresh real time parameter
this.workingModeSelect = (this.parameter.MODE !== undefined) ? this.workingModeOptions.find(ele => ele.id === this.parameter.MODE) : this.workingModeOptions[0]
},
},
},
destroyed () {
},
@@ -168,7 +168,7 @@ export default {
}
},
...mapFields('', [
'developer_mode',
'developerMode',
]),
...mapFields('taskContent', [
'deviceListNew',
@@ -233,7 +233,7 @@ export default {
},
mounted () {
// dev mode
// this.developer_mode === true
// this.developerMode === true
// ? this.workingModeOptions = this.workingModeDevOptions
// : this.workingModeOptions = this.workingModeNoDevOptions
this.workingModeOptions = this.parameterTable.MODE_OPTIONS
@@ -75,6 +75,10 @@ export default {
type: Boolean,
default: false,
},
syncParameter: {
type: Object,
default: () => {},
},
},
created () {
},
@@ -87,6 +91,13 @@ export default {
methods: {
buttonSelectChange (value) {
this.$emit('parameterChange', this.parameterName, value)
this.syncParameter && Object.keys(this.syncParameter).forEach(element => {
if (String(element) === String(value)) {
this.syncParameter[value].forEach(element => {
this.$emit('parameterChange', element[0], element[1])
})
}
})
},
},
async mounted () {
+12 -11
View File
@@ -75,7 +75,7 @@ function sgFilter (data, windowSize, k) {
// return list
}
function sgFilterGetDifferential (data, windowSize, polynomial) {
function sgFilterGetDifferential (data, windowSize, polynomial, sampleRate = 1) {
// self
const arr = []
const m = parseInt((windowSize - 1) / 2)
@@ -96,23 +96,24 @@ function sgFilterGetDifferential (data, windowSize, polynomial) {
// use index 1 row in matrix
const rowOneInB = row(B, 1)._data[0]
const start = []
const end = []
// const start = []
// const end = []
const list = []
// eslint-disable-next-line no-unused-vars
for (const _ of range(0, m)) {
start.push(data[0])
end.push(data[data.length - 1])
}
const _data = [...start, ...data, ...end]
// for (const _ of range(0, m)) {
// start.push(data[0])
// end.push(data[data.length - 1])
// }
// const _data = [...start, ...data, ...end]
// const _data = [...data]
// m ... data_length - m - 1
for (const i of range(m, _data.length - m)) {
for (const i of range(m, data.length - m)) {
const arra = []
// -m ... 0 ... m
for (const j of range(-m, m + 1)) {
arra.push(_data[i.value + j.value])
arra.push(data[i.value + j.value])
}
let sum = 0
@@ -120,7 +121,7 @@ function sgFilterGetDifferential (data, windowSize, polynomial) {
sum += (arra[index] * rowOneInB[index])
}
list.push(sum)
list.push(sum * sampleRate)
}
return list
}
+5 -4
View File
@@ -1,7 +1,8 @@
export default {
name: 'Cali ADC - test',
parameter: ['DAC_VOLT', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'ADC_DAC_CHANNEL_15'], // 這個mode用到的參數
showParameter: ['DAC_VOLT', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'ADC_DAC_CHANNEL_15'], // 有要秀給user看的參數
name: 'Cali Mode - test',
parameter: ['ADC_DAC_CHANNEL_15', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'DAC_LEVEL_V_OUT_15', 'DAC_VOLT_BUTTON'], // 這個mode用到的參數
showParameter: ['ADC_DAC_CHANNEL_15', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'DAC_LEVEL_V_OUT_15', 'DAC_VOLT_BUTTON'], // 有要秀給user看的參數
headerParameter: () => ['ADC_DAC_CHANNEL_15', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'DAC_LEVEL_V_OUT_15', 'DAC_VOLT_BUTTON'], // export header的參數
valScales: {
linear: {
func: (val) => {
@@ -52,7 +53,7 @@ export default {
charts: {
default: [
{
name: 'Cali ADC - test',
name: 'Cali Mode - test',
description: '',
subplot: [
{
@@ -58,6 +58,46 @@ export default {
defaultUnit: 'mV',
downloadUnit: 'mV',
},
3: {
name: 'sum_cnt',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'uV',
},
4: {
name: 'sum_adc_delta_Iin',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'uV',
},
5: {
name: 'sum_adc_delta_Voutin',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'uV',
},
6: {
name: 'resis',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'uV',
},
},
charts: {
default: [
@@ -45,7 +45,7 @@ export default {
downloadUnit: 'ms',
},
0: {
name: 'pul1_I_in',
name: 'I_in_pul1',
unit: {
nA: 1,
uA: 1e3,
@@ -55,7 +55,7 @@ export default {
downloadUnit: 'mA',
},
1: {
name: 'pul2_I_in',
name: 'I_in_pul2',
unit: {
nA: 1,
uA: 1e3,
+71 -4
View File
@@ -162,17 +162,24 @@ const EliteZM15 = {
options: [
{ value: 0, label: 'Iin' },
{ value: 1, label: 'Vin' },
{ value: 2, label: 'Vout' },
],
range: ['Iin', 'Vin'],
range: ['Iin', 'Vin', 'Vout'],
defaultValue: 0,
outputRawData: (val) => {
const caliChannelArr = ['Iin', 'Vin']
const caliChannelArr = ['Iin', 'Vin', 'Vout']
return caliChannelArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const caliChannelArr = ['Iin', 'Vin']
const caliChannelArr = ['Iin', 'Vin', 'Vout']
return caliChannelArr[parseInt(idx)]
},
syncParameter: {
0: [['ADC_LEVEL_V_IN_15', 3], ['ADC_LEVEL_I_15', 0], ['DAC_LEVEL_V_OUT_15', 2]],
1: [['ADC_LEVEL_V_IN_15', 0], ['ADC_LEVEL_I_15', 0], ['DAC_LEVEL_V_OUT_15', 2]],
2: [['ADC_LEVEL_V_IN_15', 3], ['ADC_LEVEL_I_15', 4], ['DAC_LEVEL_V_OUT_15', 0]],
},
},
VOLT_ORIGIN: {
type: 'number',
@@ -255,6 +262,26 @@ const EliteZM15 = {
},
downloadUnit: 's',
},
DAC_LEVEL_V_OUT_15: {
type: 'array',
showName: 'DAC range',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: '0' },
{ value: 1, label: '1' },
{ value: 2, label: 'Auto' },
],
range: ['0', '1', 'Auto'],
defaultValue: 2,
outputRawData: (val) => {
const caliChannelArr = ['0', '1', 'Auto']
return caliChannelArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const caliChannelArr = ['0', '1', 'Auto']
return caliChannelArr[parseInt(idx)]
},
},
DAC_VOLT: {
type: 'number',
showName: 'Volt out',
@@ -274,6 +301,46 @@ const EliteZM15 = {
return parseInt((parseFloat(val) - 25000) / 5) / scale
},
},
DAC_VOLT_SCROLL: {
type: 'number',
showName: 'DAC code',
componentType: 'input-range',
range: Object.freeze({ min: 0, max: 60000 }),
defaultValue: 25000,
defaultUnit: '',
downloadUnit: 'mV',
unit: {
mV: 1,
V: 1e3,
},
outputRawData: (val, scale = 1) => {
return parseInt(parseFloat(val))
},
outputReadabilityData: (val, scale = 0) => {
return parseInt(parseFloat(val))
},
},
DAC_VOLT_BUTTON: {
type: 'array',
showName: 'DAC code',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: '10000' },
{ value: 1, label: '25000' },
{ value: 2, label: '50000' },
{ value: 3, label: '60000' },
],
range: ['10000', '25000', '50000', '60000'],
defaultValue: 1,
outputRawData: (val) => {
const caliChannelArr = ['10000', '25000', '50000', '60000']
return caliChannelArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const caliChannelArr = ['10000', '25000', '50000', '60000']
return caliChannelArr[parseInt(idx)]
},
},
SAMPLE_RATE: {
type: 'number',
componentType: 'input-range',
@@ -981,7 +1048,7 @@ const EliteZM15 = {
},
{
id: 11,
description: 'Cali ADC - test',
description: 'Cali Mode - test',
img_src: 'CADC-Wire',
},
],
@@ -0,0 +1,97 @@
export default {
name: 'Chronoamperometry',
parameter: ['VOLT_VSCAN', 'SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 這個mode用到的參數
showParameter: ['ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'CTRL_HIGH_Z_15', 'VOLT_VSCAN', 'SAMPLE_RATE', 'TIME_DURATION'], // 有要秀給user看的參數
headerParameter: () => ['VOLT_VSCAN', 'SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'TIME_DURATION'], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'Potential',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
default: [
{
name: 'Chronoamperometric',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'chrono',
x1: {
channel: 'time',
},
y1: {
channel: 0,
},
},
],
},
],
},
],
},
}
+48 -3
View File
@@ -1,8 +1,27 @@
import PotentiostaticEIS from './PotentiostaticEIS'
import CyclicVoltammetry from './CyclicVoltammetry'
import DevMode from './DevMode'
import Chronoamperometry from './Chronoamperometry'
const EliteEIS = {
VOLT_VSCAN: {
type: 'number',
showName: 'Volt (v.s. ref)',
componentType: 'input-range',
range: Object.freeze({ min: 2500, max: 50000 }),
outputRawData: (val, scale = 1) => {
return parseInt(parseFloat(val) * scale * 12.5 + 25000)
},
outputReadabilityData: (val, scale = 1) => {
return parseInt((parseFloat(val) - 25000) / 12.5) / scale
},
defaultUnit: 'V',
downloadUnit: 'mV',
unit: {
mV: 1,
V: 1e3,
},
},
ADC_VALUE_I: {
type: 'none',
showName: 'Instruction',
@@ -49,10 +68,10 @@ const EliteEIS = {
componentType: 'multi-input-field',
range: Object.freeze({ min: 1, max: 4294967296 }),
outputRawData: (val) => {
return parseFloat(val) < 0.1 ? 1 : Math.round(parseFloat(val) / 0.0149)
return parseFloat(val) < 0.1 ? Math.round(0.1 / 0.015) : Math.round(parseFloat(val) / 0.015)
},
outputReadabilityData: (val) => {
return String(parseFloat(Math.round(parseFloat((val * 0.0149) * 100)) / 100).toFixed(1)) === '0.0' ? 0.015 : parseFloat(Math.round(parseFloat((val * 0.0149) * 100)) / 100).toFixed(1)
return (parseFloat(val) * 0.015).toFixed(1)
},
defaultUnit: 'Hz',
downloadUnit: 'Hz',
@@ -226,6 +245,27 @@ const EliteEIS = {
return voltageInRangeArr[parseInt(idx)]
},
},
TIME_DURATION: {
type: 'number',
showName: 'Time duration',
componentType: 'input-range',
range: Object.freeze({ min: 0, max: 86400 }), // UI上能輸入的最大最小值
defaultValue: 0,
defaultUnit: 's',
downloadUnit: 's',
unit: {
ms: 1e-3,
s: 1,
m: 60,
h: 3600,
},
outputRawData: (val) => {
return parseInt(parseFloat(val))
},
outputReadabilityData: (val) => {
return parseInt(parseFloat(val))
},
},
CTRL_HIGH_Z_15: {
type: 'array',
showName: 'HighZ',
@@ -361,13 +401,18 @@ const EliteEIS = {
},
{
id: 2,
description: 'Chronoamperometry',
},
{
id: 3,
description: 'Dev Tools',
},
],
MODE: {
0: PotentiostaticEIS,
1: CyclicVoltammetry,
2: DevMode,
2: Chronoamperometry,
3: DevMode,
},
}
+10 -1
View File
@@ -1,5 +1,6 @@
import EliteEDC from './EliteEDC/index'
import EliteEIS from './EliteEIS/index'
import store from '@/store/index'
// object saving library name mapping table
const libraryNameMappingTable = {
@@ -53,11 +54,19 @@ const serialNumberMappingTable = {
}
/**
* return config table by libray or serial number (type)
* return config table by library or serial number (type)
* @param {String | Object} type
* @returns {Object} : config
*/
function getConfig (type) {
if (typeof type === 'number') {
const deviceList = store.getters.getField('taskContent').deviceListNew
if (deviceList === undefined) return
const device = deviceList.find(ele => ele.memory_board === type)
if (device === undefined) return
return libraryNameMappingTable[device.library_name]
}
// library name
if (typeof type === 'string') {
return libraryNameMappingTable[type]
+28 -1
View File
@@ -1,4 +1,7 @@
/* eslint-disable no-undef */
import { v4 as uuidv4 } from 'uuid'
import localforage from 'localforage'
import { taskInfo } from '@/data/task/TaskInfo'
const TaskTotalSettingView = false
@@ -47,7 +50,8 @@ const getDefaultChartTypeByMode = (mode, lib) => {
const settings = {}
settings[0] = ['EliteEIS', 6, 'EliteEIS', 5]
settings[1] = ['Elite', 2, 'Elite', 1]
settings[2] = ['Time', 2, 'Elite', 2]
settings[2] = ['Time', 2, 'Elite', 1]
settings[3] = ['Time', 2, 'Elite', 2]
return settings[mode]
} else if (lib === 'Elite_TRI') {
// const settings = {}
@@ -141,6 +145,28 @@ const objectFilter = function (mainObject, filterFunction) {
.reduce((cur, key) => { return Object.assign(cur, { [key]: mainObject[key] }) }, {})
}
const refreshCache = async () => {
const checkRet = await checkControllerID()
const checkRet1 = await checkVersion()
if (checkRet && checkRet1) return
window.location.reload(true)
}
async function checkControllerID () {
const controllerID = await localforage.getItem('controllerID')
if (taskInfo.getTaskInfo().controllerID === undefined) return true
if (controllerID === taskInfo.getTaskInfo().controllerID) return true
localforage.setItem('controllerID', taskInfo.getTaskInfo().controllerID)
return false
}
async function checkVersion () {
const version = await localforage.getItem('version')
if (version === COMMIT) return true
localforage.setItem('version', COMMIT)
return false
}
export default
{
hasCycleMode,
@@ -155,4 +181,5 @@ export default
ChannelMaxNumber,
getUUID,
objectFilter,
refreshCache,
}
+4 -3
View File
@@ -8,7 +8,7 @@ function newChart (chartID, numOfCharts) {
chartYUnit: '',
chartXMode: 'value', // value or time
chartYMode: 'value', // value or time
cardName: 'chart' + String(numOfCharts),
cardName: 'Chart' + String(numOfCharts),
cardHeight: '500px',
cardWidth: 'auto',
mappingID: '-1',
@@ -18,8 +18,9 @@ function newChart (chartID, numOfCharts) {
legend: {
type: 'scroll',
data: [],
x: 'center',
y: '92%',
// x: 'center',
// y: '-10%',
bottom: '0%',
textStyle: {
color: '#34495e',
},
+2 -1
View File
@@ -5,7 +5,8 @@ function newDataZoom () {
// top: '0%',
height: '10px',
// realtime: false,
bottom: '8%',
bottom: '6%',
brushSelect: false,
zoomLock: false,
handleStyle: {
shadowColor: 'rgba(0, 0, 0, 0)',
+33 -85
View File
@@ -1,3 +1,5 @@
import configRouter from '@/components/analysis/replay/toolbox/configTable'
function getTime (val) {
let label = ''
const hour = Math.floor(val / 3.6e9)
@@ -23,7 +25,7 @@ function getTime (val) {
return label
}
function newTooltip (chartID) {
function newTooltip (controlPanel) {
return {
hideDelay: 5000,
trigger: 'axis',
@@ -32,92 +34,38 @@ function newTooltip (chartID) {
borderWidth: 1,
borderRadius: 0,
padding: 10,
// axisPointer: {
// type: 'cross',
// animation: false,
// label: {
// backgroundColor: '#505765',
// },
// },
formatter: function (params) {
if (params.length) {
if (params[0].seriesName.split('_')[0] === 'T' && params[0].seriesName.split('_')[1] !== 'T') {
params.unshift({ seriesName: 'Time', value: [null, getTime(parseFloat(params[0].value[0]))], color: '#5193f2' })
} else if (params[0].seriesName.split('_')[0] !== 'T' && params[0].seriesName.split('_')[1] === 'T') {
params.unshift({ seriesName: 'Time', value: [null, getTime(parseFloat(params[0].value[1]))], color: '#5193f2' })
} else {
params.unshift({ seriesName: 'Time', value: [null, getTime(parseFloat(params[0].value[2]))], color: '#5193f2' })
}
let tip = ''
for (var i = 0; i < params.length; i++) {
const param = params[i]
const style = 'color: ' + param.color
let value
// console.log(param.value)
if (param.seriesName === 'Time') {
value = param.value[1]
} else if (param.seriesName.split('_')[1] === 'T' && param.seriesName.split('_')[0] !== 'T') {
const physicalQuantity = param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1]
if (physicalQuantity === 'V') {
value = parseFloat(param.value[0]).toFixed(3) + ' μV'
} else if (physicalQuantity === 'I') {
value = parseFloat(param.value[0]).toFixed(3) + ' nA'
} else if (physicalQuantity === 'R') {
value = parseFloat(param.value[0]).toFixed(3) + ' mΩ'
} else if (physicalQuantity === 'X' || physicalQuantity === 'Y' || physicalQuantity === 'Z' || physicalQuantity === 'M') {
value = (parseFloat(param.value[0]) / 100).toFixed(3) + ' (g)'
} else if (!isNaN(physicalQuantity)) {
value = (parseFloat(param.value[0]) / 1000).toFixed(3) + ' (mV)'
} else {
value = parseFloat(param.value[0]).toFixed(3)
}
} else if (param.seriesName.split('_')[1] !== 'T' && param.seriesName.split('_')[0] === 'T') {
const physicalQuantity = param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1]
if (physicalQuantity === 'V') {
value = parseFloat(param.value[1]).toFixed(3) + ' μV'
} else if (physicalQuantity === 'I') {
value = parseFloat(param.value[1]).toFixed(3) + ' nA'
} else if (physicalQuantity === 'R') {
value = parseFloat(param.value[1]).toFixed(3) + ' mΩ'
} else if (physicalQuantity === 'X' || physicalQuantity === 'Y' || physicalQuantity === 'Z' || physicalQuantity === 'M') {
value = (parseFloat(param.value[1]) / 100).toFixed(3) + ' (g)'
} else if (!isNaN(physicalQuantity)) {
value = (parseFloat(param.value[1]) / 1000).toFixed(3) + ' (mV)'
} else {
value = parseFloat(param.value[1]).toFixed(3)
}
} else {
let value1
let value2
if (param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1] === 'V') {
value1 = parseFloat(param.value[0]).toFixed(3) + ' μV'
} else if (param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1] === 'I') {
value1 = parseFloat(param.value[0]).toFixed(3) + ' nA'
} else if (param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1] === 'R') {
value1 = parseFloat(param.value[0]).toFixed(3) + ' mΩ'
} else {
value1 = parseFloat(param.value[0]).toFixed(3)
}
if (param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1] === 'V') {
value2 = parseFloat(param.value[1]).toFixed(3) + ' μV'
} else if (param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1] === 'I') {
value2 = parseFloat(param.value[1]).toFixed(3) + ' nA'
} else if (param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1] === 'R') {
value2 = parseFloat(param.value[1]).toFixed(3) + ' mΩ'
} else {
value2 = parseFloat(param.value[1]).toFixed(3)
}
value = value1 + ', ' + value2
}
tip += '<span style="' + style + '">' +
param.seriesName +
'</span><span style="' +
style + '">' + value + '</span><br>'
}
return tip
// params is empty
if (!params.length) return params
// else return params
// params is unempty
let tip = ''
let value // value on cursor
const param = params[0]// find coressonding parameter to the channel
const style = 'color: ' + param.color
const xScale = configRouter.getUnitScale(controlPanel.x.axis.description)
const yScale = configRouter.getUnitScale(controlPanel.y.axis.description)
// (Default) Time
if (controlPanel.x.axis.description === 'Time') {
value = getTime(parseFloat(param.value[0]))
} else {
value = getTime(parseFloat(param.value[2]))
}
tip += '<span style="color: #000000">' + 'Time: ' + value + '</span><br>'
// (Manual) Voltage, Current, Resistance
tip += '<span style="' + style + '">' + param.seriesName + ':<ul style = "list-style-type: disc; list-style-position: inside">'
if (controlPanel.x.axis.description !== 'Time') {
value = parseFloat(param.value[0] / xScale[controlPanel.x.unit]).toFixed(3) + ' ' + controlPanel.x.unit
tip += '<li>' + controlPanel.x.axis.description + ' = ' + value + '</li>'
}
if (controlPanel.y.axis.description !== 'Time') {
value = parseFloat(param.value[1] / yScale[controlPanel.y.unit]).toFixed(3) + ' ' + controlPanel.y.unit
tip += '<li>' + controlPanel.y.axis.description + ' = ' + value + '</li>'
}
tip += '</ul></span>'
return tip
},
}
}
-3
View File
@@ -55,14 +55,11 @@ function newSeries (type, legendName, xAxisIndex, yAxisIndex, xAxisSource, yAxis
xAxisSource: xAxisSource,
yAxisSource: yAxisSource,
animation: false,
hoverAnimation: false,
dataXMax: null,
dataXMin: null,
dataYMax: null,
dataYMin: null,
itemStyle: {
normal: {
},
},
lineStyle: {
width: 1.5,
+4 -4
View File
@@ -50,7 +50,7 @@ function newTooltip (realTime, dataMode) {
} else {
value = getTime(parseFloat(params[0].value[timeIndex]))
}
tip += '<span style="color: #5193f2">' + 'Time: ' + value + '</span><br>'
tip += '<span style="color: #000000">' + 'Time: ' + value + '</span><br>'
// (Manual) Voltage, Current, Impedance
for (let gridIndex = 0; gridIndex < realTime.length; gridIndex++) {
for (let channelIndex = 0; channelIndex < realTime[gridIndex].length; channelIndex++) {
@@ -60,13 +60,13 @@ function newTooltip (realTime, dataMode) {
unitTable = realTime[gridIndex][channelIndex]
style = 'color: ' + param.color
tip += '<span style="' + style + '">' + param.seriesName + ':<ul style = "list-style-type: disc; list-style-position: inside">'
tip += '<span style="' + style + '">' + param.seriesName + ':<ul style = "list-style-type: disc; list-style-position: inside">'
if (unitTable.xName !== 'Time') {
value = parseFloat(param.value[0] / unitTable.xScale[unitTable.xUnit]).toFixed(3) + unitTable.xUnit
value = parseFloat(param.value[0] / unitTable.xScaleOption[unitTable.xUnit]).toFixed(3) + ' ' + unitTable.xUnit
tip += '<li>' + unitTable.xName + ' = ' + value + '</li>'
}
if (unitTable.yName !== 'Time') {
value = parseFloat(param.value[1] / unitTable.yScale[unitTable.yUnit]).toFixed(3) + unitTable.yUnit
value = parseFloat(param.value[1] / unitTable.yScaleOption[unitTable.yUnit]).toFixed(3) + ' ' + unitTable.yUnit
tip += '<li>' + unitTable.yName + ' = ' + value + '</li>'
}
tip += '</ul></span>'
+3 -1
View File
@@ -1,7 +1,9 @@
function newActionTemplate () {
return [
'start',
// 'start',
'stop',
'cycle',
'idle',
]
}
+33 -1
View File
@@ -26,7 +26,7 @@ function newConditionTemplate (action) {
select: false,
type: 'hidden',
prefix: 'When previous task done',
suffix: 'done',
suffix: '',
value: '',
},
// device: {
@@ -88,6 +88,38 @@ function newConditionTemplate (action) {
// value: '',
// },
},
cycle: {
cycle_next: {
select: false,
type: 'text',
prefix: 'Cycle next go to:',
suffix: '',
value: '',
},
cycle: {
select: false,
type: 'text',
prefix: 'Run',
suffix: 'times',
value: '0',
},
},
idle: {
after_task_run: {
select: false,
type: 'text',
prefix: 'for',
suffix: 'secs',
value: '',
},
until_button_trigger: {
select: false,
type: 'hidden',
prefix: 'until button press',
suffix: '',
value: '',
},
},
}
}
@@ -61,7 +61,7 @@ function newAction () {
},
{
id: 11,
description: 'Cali ADC - test',
description: 'Cali Mode - test',
select: false,
},
{
@@ -54,7 +54,7 @@ function newEliteZm15Parameter () {
// },
// {
// id: 11,
// description: 'Cali ADC - test',
// description: 'Cali Mode - test',
// },
// {
// id: 12,
+3
View File
@@ -12,6 +12,9 @@ function newTask (name, uuid) {
select: false,
status: -1,
cycle: -1,
cycle_count: 0,
cycle_next: '',
cycle_next_uuid: '',
uuid: uuid,
}
}
+1 -1
View File
@@ -20,7 +20,7 @@ function newState () {
},
isLoading: true,
licenseCheck: true,
developer_mode: false,
developerMode: false,
controller: null,
}
}
@@ -113,16 +113,16 @@ function getLegendName (sourceList) {
case 'Elite':
switch (source.channel) {
case 1:
legendName += '' + source.id + '-I'
legendName += '' + source.id + 'I'
break
case 2:
legendName += '' + source.id + '-V'
legendName += '' + source.id + 'V'
break
case 3:
legendName += '' + source.id + '-R'
legendName += '' + source.id + 'R'
break
case 4:
legendName += '' + source.id + '-Cycle'
legendName += '' + source.id + 'Cycle'
break
default:
legendName += '' + source.id + 'CH' + source.channel
@@ -132,28 +132,28 @@ function getLegendName (sourceList) {
case 'EliteEIS':
switch (source.channel) {
case 3:
legendName += '' + source.id + '-Frequency'
legendName += '' + source.id + 'Frequency'
break
case 4:
legendName += '' + source.id + '-Cycle'
legendName += '' + source.id + 'Cycle'
break
case 5:
legendName += '' + source.id + '-Z_imag'
legendName += '' + source.id + 'Z-imag'
break
case 6:
legendName += '' + source.id + '-Z_real'
legendName += '' + source.id + 'Z-real'
break
case 7:
legendName += '' + source.id + '-Impedance'
legendName += '' + source.id + 'Impedance'
break
case 8:
legendName += '' + source.id + '-Phase'
legendName += '' + source.id + 'Phase'
break
case 9:
legendName += '' + source.id + '-Current'
legendName += '' + source.id + 'Current'
break
case 10:
legendName += '' + source.id + '-Gain Level'
legendName += '' + source.id + 'Gain Level'
break
default:
legendName += '' + source.id + 'CH' + source.channel
@@ -210,7 +210,7 @@ const actions = {
if (payload.chartAllData[payload.chartID] == null) {
payload.chartAllData[payload.chartID] = newChart(payload.chartID)
if (payload.type !== 'overview') {
payload.chartAllData[payload.chartID].tooltip = newTooltip()
payload.chartAllData[payload.chartID].tooltip = newTooltip(state.controlPanel)
}
payload.chartAllData[payload.chartID].chartType = payload.type
payload.chartAllData[payload.chartID].chartDevice = payload.device
@@ -375,7 +375,7 @@ const actions = {
switch (sourceList[0].name) {
case 'Time':
xAxisType = 'time'
xAxisType = 'value'
xAxisSource = [-1, -1]
break
default:
@@ -1,4 +1,5 @@
import types from '@/store/modules/analysis/replay/types'
import configRouter from '@/components/analysis/replay/toolbox/configTable'
const typePath = types.chart
@@ -33,16 +34,16 @@ function getLegendName (sourceList) {
case 'Elite':
switch (source.channel) {
case 1:
legendName += '' + source.id + '-I'
legendName += '' + source.id + 'I'
break
case 2:
legendName += '' + source.id + '-V'
legendName += '' + source.id + 'V'
break
case 3:
legendName += '' + source.id + '-R'
legendName += '' + source.id + 'R'
break
case 4:
legendName += '' + source.id + '-Cycle'
legendName += '' + source.id + 'Cycle'
break
default:
legendName += '' + source.id + 'CH' + source.channel
@@ -52,28 +53,28 @@ function getLegendName (sourceList) {
case 'EliteEIS':
switch (source.channel) {
case 3:
legendName += '' + source.id + '-Frequency'
legendName += '' + source.id + 'Frequency'
break
case 4:
legendName += '' + source.id + '-Cycle'
legendName += '' + source.id + 'Cycle'
break
case 5:
legendName += '' + source.id + '-Z_imag'
legendName += '' + source.id + 'Z-imag'
break
case 6:
legendName += '' + source.id + '-Z_real'
legendName += '' + source.id + 'Z-real'
break
case 7:
legendName += '' + source.id + '-Impedance'
legendName += '' + source.id + 'Impedance'
break
case 8:
legendName += '' + source.id + '-Phase'
legendName += '' + source.id + 'Phase'
break
case 9:
legendName += '' + source.id + '-Current'
legendName += '' + source.id + 'Current'
break
case 10:
legendName += '' + source.id + '-Gain Level'
legendName += '' + source.id + 'Gain-Level'
break
default:
legendName += '' + source.id + 'CH' + source.channel
@@ -90,6 +91,30 @@ function getLegendName (sourceList) {
return legendName
}
function autoTimeFormatter (val) {
let label = ''
const hour = parseInt(val / 3.6e9)
const minute = parseInt((val % 3.6e9) / 1000000 / 60)
const second = parseInt((val % 6e7) / 1000000)
const millisecond = parseInt((val % 1e6) / 1000)
if (hour > 0) {
label += hour + ' h '
}
if (minute > 0) {
label += minute + ' m '
}
if (second > 0) {
label += second + ' s '
}
if (millisecond > 0) {
label += millisecond + ' ms '
}
if (hour === 0 && minute === 0 && second === 0 && millisecond === 0) {
label += ' 0 ms '
}
return label
}
const chartMutations = {
/**
* update label formatter
@@ -99,71 +124,86 @@ const chartMutations = {
* @param {int} axisIndex
* @param {int} channel // use for checking whether it is 3-axis
*/
// [typePath.updateAxisLabel]: (state, payload) => {
// let unit // string
// let unitScale // int
// let axisLabel
// if (payload.axis === 'x') {
// unit = state.valueFormatX.unit
// unitScale = state.valueFormatX.unitScale
// axisLabel = state.chartData[payload.chartID].xAxis[payload.axisIndex].axisLabel
// } else if (payload.axis === 'y') {
// unit = state.valueFormatY.unit
// unitScale = state.valueFormatY.unitScale
// axisLabel = state.chartData[payload.chartID].yAxis[payload.axisIndex].axisLabel
// }
// if (payload.channel < 256) {
// axisLabel.formatter = function (val) {
// let label = ''
// if (unit === 'auto') { // time
// const hour = parseInt(val / 3.6e9)
// const minute = parseInt((val % 3.6e9) / 1000000 / 60)
// const second = parseInt((val % 6e7) / 1000000)
// const millisecond = parseInt((val % 1e6) / 1000)
// if (hour > 0) {
// label += hour + ' h '
// }
// if (minute > 0) {
// label += minute + ' m '
// }
// if (second > 0) {
// label += second + ' s '
// }
// if (millisecond > 0) {
// label += millisecond + ' ms '
// }
// } else { // not time, e.g. I, V, R
// const num = String(val / unitScale)
// label = num + unit
// }
// return label
// }
// } else { // 256: x, 257: y, 258: z, 259: mag
// axisLabel.formatter = function (val) {
// let label = ''
// if (unit === 'auto') { // time
// const hour = parseInt(val / 3.6e9)
// const minute = parseInt((val % 3.6e9) / 1000000 / 60)
// const second = parseInt((val % 6e7) / 1000000)
// const millisecond = parseInt((val % 1e6) / 1000)
// if (hour > 0) {
// label += hour + ' h '
// }
// if (minute > 0) {
// label += minute + ' m '
// }
// if (second > 0) {
// label += second + ' s '
// }
// if (millisecond > 0) {
// label += millisecond + ' ms '
// }
// } else {
// label = val.toFixed(3)
// }
// return label
// }
// }
[typePath.updateAxisLabel]: (state, payload) => {
let unit // string
let unitScale // int
let axisLabel
if (payload.axis === 'x') {
unit = state.valueFormatX.unit
unitScale = state.valueFormatX.unitScale
axisLabel = state.chartData[payload.chartID].xAxis[payload.axisIndex].axisLabel
} else if (payload.axis === 'y') {
unit = state.valueFormatY.unit
unitScale = state.valueFormatY.unitScale
axisLabel = state.chartData[payload.chartID].yAxis[payload.axisIndex].axisLabel
}
if (payload.channel < 256) {
axisLabel.formatter = function (val) {
let label = ''
if (unit === 'auto') { // time
const hour = parseInt(val / 3.6e9)
const minute = parseInt((val % 3.6e9) / 1000000 / 60)
const second = parseInt((val % 6e7) / 1000000)
const millisecond = parseInt((val % 1e6) / 1000)
if (hour > 0) {
label += hour + ' h '
}
if (minute > 0) {
label += minute + ' m '
}
if (second > 0) {
label += second + ' s '
}
if (millisecond > 0) {
label += millisecond + ' ms '
}
} else { // not time, e.g. I, V, R
const num = String(val / unitScale)
label = num + unit
}
return label
}
} else { // 256: x, 257: y, 258: z, 259: mag
axisLabel.formatter = function (val) {
let label = ''
if (unit === 'auto') { // time
const hour = parseInt(val / 3.6e9)
const minute = parseInt((val % 3.6e9) / 1000000 / 60)
const second = parseInt((val % 6e7) / 1000000)
const millisecond = parseInt((val % 1e6) / 1000)
if (hour > 0) {
label += hour + ' h '
}
if (minute > 0) {
label += minute + ' m '
}
if (second > 0) {
label += second + ' s '
}
if (millisecond > 0) {
label += millisecond + ' ms '
}
} else {
label = val.toFixed(3)
}
const unit = state.controlPanel[payload.axis].unit
const unitScale = configRouter.getUnitScale(payload.type)
const axisLabel = state.chartData[payload.chartID][payload.axis + 'Axis'][payload.axisIndex].axisLabel
const _axisLabel = JSON.parse(JSON.stringify(axisLabel))
if (unit === 'auto') {
_axisLabel.formatter = autoTimeFormatter
} else {
_axisLabel.formatter = function (val) {
const label = (val / unitScale[unit]).toFixed(3) + unit
return label
}
}
state.chartData[payload.chartID][payload.axis + 'Axis'][payload.axisIndex].axisLabel = _axisLabel
},
/**
@@ -35,6 +35,19 @@ function newState () {
showWhichCycles: '1',
useSdCardData: false,
isLockDataZoom: false,
controlPanel: {
x: {
axis: null,
unit: null,
funct: null,
},
y: {
axis: null,
unit: null,
funct: null,
},
FSM: {},
},
}
}
@@ -67,7 +67,12 @@ const projectActs = {
[typePath.select]: async ({ state, getters, commit }, payload) => {
state.projectSelectIndex = payload.index
// initial default device library
state.projectLibrary = state.projectList[payload.index].device[0]?.library.value
if (typeof state.projectList[payload.index].device[0]?.library === 'object') {
state.projectLibrary = state.projectList[payload.index].device[0]?.library.value
} else {
state.projectLibrary = state.projectList[payload.index].device[0]?.library
}
// state.projectLibrary = state.projectList[payload.index].device[0]?.library.value
},
/**
@@ -80,6 +85,7 @@ const projectActs = {
await api.project.update(project.id, { deleted: true })
await api.project.del()
state.projectList.splice(index, 1)
state.projectSelectIndex = -1
return true
},
@@ -90,7 +96,15 @@ const projectActs = {
*/
[typePath.addDevice]: async ({ state, getters, commit }, payload) => {
const { device } = payload
getters.getSelectProject.device.push(device)
// console.log(getters.getSelectProject.device)
let flag = false
for (const eachDevice of getters.getSelectProject.device) {
if (device.connectDevice.mac_address === eachDevice.connectDevice.mac_address) {
flag = true
break
}
}
if (!flag) getters.getSelectProject.device.push(device)
},
/**
@@ -76,6 +76,21 @@ const taskActs = {
task.action = Object.assign({}, task.action, payload.action)
},
/**
* set task cycle
*
* @param {}
*/
[typePath.setCycle]: async ({ state, getters, commit }, payload) => {
const task = getters.getSelectTask
// task.cycle = Object.assign({}, task.cycle, payload.cycle)
// task.cycle_next = Object.assign({}, task.cycle_next, payload.cycle_next)
task.cycle = payload.cycle
task.cycle_next = payload.cycle_next
task.cycle_next_uuid = payload.cycle_next_uuid
// console.log(task, task.cycle, task.cycle_next, task.cycle_next_uuid)
},
/**
* set task paramter
*
+1
View File
@@ -28,6 +28,7 @@ const types = {
setCondition: 'setConditionTask',
setAction: 'setActionTask',
setCycle: 'setCycleTask',
setParameterSet: 'setParameterSetTask',
get: 'getTask',
@@ -10,6 +10,8 @@ import localforage from 'localforage'
import { IIRFilter } from '@/data/task/filter/IIRFilter.js'
import config from '@/data/config-table/index'
const typePath = types.chart
const chartActs = {
@@ -145,9 +147,9 @@ const chartActs = {
let legendName
if (formula == null) {
legendName = getLegendName(sourceList, formula)
legendName = getLegendName(sourceList, formula, state.deviceListNew)
} else {
legendName = getLegendName(sourceList, formula.id)
legendName = getLegendName(sourceList, formula.id, state.deviceListNew)
}
if (formula == null) {
@@ -241,7 +243,7 @@ const chartActs = {
state.chartData[chartID].xAxis[_xAxisIndex].axisLabel.formatter = function (val) {
return getTimeFormatter(val)
}
state.chartData[chartID].xAxis[_xAxisIndex].interval = 500 * 1000
// state.chartData[chartID].xAxis[_xAxisIndex].interval = 500 * 1000
} else if (sourceList[0].name === 'Elite') {
// state.chartData[chartID].series[state.chartData[chartID].series.length - 1].sampling = false
switch (sourceList[0].channel) {
@@ -338,7 +340,7 @@ const chartActs = {
return parseFloat(val).toFixed(2) + 'uV'
}
}
state.chartData[chartID].chartYUnit = 'uV' // nA * 1000
state.chartData[chartID].chartYUnit = 'uV'
} else if (sourceList[1].name === 'Elite') {
switch (sourceList[1].channel) {
case 1:
@@ -1046,7 +1048,7 @@ const chartActs = {
state.chartData[chartID].mappingID = '-1'
}
if (cardName == null) {
state.chartData[chartID].cardName = 'chart' + String(chartID)
state.chartData[chartID].cardName = 'Chart' + String(chartID)
}
state.chartData[chartID].dataZoom = null
dispatch(typePath.updateGridList, { chartID: chartID, length: 1 })
@@ -1061,10 +1063,24 @@ const chartActs = {
*/
[typePath.resetSeriesData]: ({ state, getters, commit, dispatch }, payload) => {
const { chartID, mappingID } = payload
// check chart need to reset or not
if (String(mappingID) === String(state.chartData[chartID].mappingID)) {
// reset series data
for (const i in state.chartData[chartID].series) {
state.chartData[chartID].series[i].data.length = 0
}
// reset databuffer
const databuffer = dataStreamBuffer.getByChartID(chartID)
if (databuffer) {
for (const device in databuffer) {
// console.log('device', device)
for (const channel in databuffer[device]) {
// console.log('channel', channel, databuffer[device][channel])
databuffer[device][channel].length = 0
}
}
}
}
},
/**
@@ -1157,7 +1173,7 @@ function makeXAxis (gridIndex, type, channel) {
showMaxLabel: false,
color: '#34495e',
// rotate: 45,
margin: 12,
// margin: 12,
},
splitLine: { show: true, lineStyle: { color: '#aaa' } },
// minorSplitLine: {
@@ -1212,8 +1228,8 @@ function makeYAxis (gridIndex, type, channel) {
// generate grid
function makeGrid (index, length) {
const _height = (85 / length) + '%'
const _top = index * (85 / length) + 1 + '%'
const _height = (80 / length) + '%'
const _top = index * (80 / length) + 5 + '%'
return {
index: index,
top: _top,
@@ -1225,7 +1241,7 @@ function makeGrid (index, length) {
}
// get legend name
function getLegendName (sourceList, formulaID) {
function getLegendName (sourceList, formulaID, deviceList) {
let legendName = ''
if (formulaID == null) {
// source only 2 device
@@ -1234,41 +1250,13 @@ function getLegendName (sourceList, formulaID) {
case 'Time':
legendName += 'T'
break
case 'Neulive':
// legendName += 'N' + source.id + 'CH' + source.channel
switch (source.channel) {
case 257:
legendName += 'X'
break
case 258:
legendName += 'Y'
break
case 259:
legendName += 'Z'
break
case 260:
legendName += 'M'
break
default:
legendName += 'CH' + source.channel
break
}
break
case 'Elite':
switch (source.channel) {
case 1:
legendName += 'E' + source.id + '-I'
break
case 2:
legendName += 'E' + source.id + '-V'
break
case 3:
legendName += 'E' + source.id + '-R'
break
default:
legendName += 'E' + source.id + 'CH' + source.channel
break
}
// eslint-disable-next-line no-case-declarations
const device = deviceList.find((ele) => String(ele.memory_board) === String(source.id))
if (device === undefined) break
// eslint-disable-next-line no-case-declarations
const channelName = getConfigChannel(device.library_name, device.configuration.MODE, source.channel - 1)
legendName += 'E' + source.id + '-' + channelName.name[0]
break
case 'EliteEIS':
switch (source.channel) {
@@ -1320,6 +1308,10 @@ function getLegendName (sourceList, formulaID) {
return legendName
}
function getConfigChannel (library, mode, channel) {
return config.getChannelConfig(library, mode, channel)
}
export function getTimeFormatter (val) {
const hour = parseInt(val / 3.6e9)
const minute = parseInt((val % 3.6e9) / 1000000 / 60)