Compare commits

...

88 Commits

Author SHA1 Message Date
peterlu14 9495a17d2d [update] remove folder 2022-11-10 11:43:07 +08:00
peterlu14 120a7d45b1 [update] remove EIS device battery 2022-11-10 11:42:44 +08:00
ROY 200a8d25fa [update] EIS RT Mode 2022-10-25 13:32:37 +08:00
peterlu14 b5908f8815 [update] EIS RT Mode 2022-10-25 10:16:37 +08:00
peterlu14 abf5b0e54b [update] projectTable UI 2022-10-18 11:51:10 +08:00
peterlu14 9637a5365e [update] remove some condition & add device SelectKey in condition & project table UI 2022-10-18 11:42:20 +08:00
peterlu14 2c1e247178 [update&debug] fix rearrange problem & add copy function & auto pair device in task 2022-10-18 11:38:19 +08:00
peterlu14 dbbf30623d [update] task device setting big update & auto register connect device 2022-10-14 17:43:11 +08:00
peterlu14 eeb43694b1 [update] add order property in device 2022-10-14 16:03:42 +08:00
peterlu14 4054a113d0 [update] remove device hide modal 2022-10-14 16:01:15 +08:00
peterlu14 6bcf4b100f [update] remove add device button 2022-10-14 11:10:26 +08:00
peterlu14 a2237aeb0a [update] add detect function 2022-10-14 10:27:55 +08:00
peterlu14 2972fa365c [update] remove old auto get device 2022-10-14 10:14:12 +08:00
peterlu14 75d71099ed [update] device need to pair to run scheduler 2022-10-14 10:13:28 +08:00
peterlu14 2ab96c3bf6 [update] scheduler device big update from array to object & auto pairing 2022-10-14 10:11:17 +08:00
peterlu14 a088b940e6 [update] fix EIS DELAY range & add library EDC EIS 2022-10-14 10:06:13 +08:00
peterlu14 59ce90d348 [update] temp fix many project message error 2022-10-11 10:48:40 +08:00
peterlu14 01f1cf28d5 [update] temp fix project table element key duplicate error 2022-10-11 10:48:08 +08:00
peterlu14 b826442672 [update] fix project copy 2022-10-11 10:47:27 +08:00
ROY 0c385ee212 [update] remove LEVEL_V button and update V_RANGE label name 2022-10-06 16:54:42 +08:00
peterlu14 15eeb513a6 [debug] fix eis replay parameter & eis realtime chart fix 2022-10-05 18:09:11 +08:00
peterlu14 f5f30cbe61 [debug] eis realtime chart source and cache problem 2022-10-05 17:01:58 +08:00
peterlu14 f7dbf43e77 [update] project enable Elite_EDC & Elite_EIS 2022-10-05 12:02:28 +08:00
peterlu14 dba675254d [update] FREQ 13333333 2022-10-05 12:00:28 +08:00
peterlu14 7635f991c1 [update] vt add parameter MEASURE_VIN_RANGE 2022-10-05 11:21:49 +08:00
peterlu14 476a1699a5 [update] add VT_MODE 2022-10-05 10:59:50 +08:00
peterlu14 8131a19e97 [debug] fix copy id 2022-10-04 13:56:47 +08:00
peterlu14 c310cd4253 [update] check action target when create fake action 2022-10-04 13:56:27 +08:00
peterlu14 6c80390917 [debug] dismiss type error 2022-10-04 13:55:00 +08:00
peterlu14 ff0da52db8 [update] remove cycle & text ui & add -> + 2022-09-30 11:37:46 +08:00
peterlu14 4074af8b4f Merge remote-tracking branch 'origin/dev/debug_cp' into release/v1.3.8/cycle 2022-09-30 10:59:53 +08:00
peterlu14 562632e417 [update] replay new page & modal outside-dismiss 2022-09-30 10:42:07 +08:00
peterlu14 782efbf366 [update] project add cycle 2022-09-30 10:40:31 +08:00
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
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
unknown eca51be1f8 [update] get source from different mode (some bugs need to be fixed) 2022-08-18 18:21:44 +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
nthu1080112244 bdd9113b80 [update] real time grid setting 2022-08-17 17:58:58 +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
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
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
nthu1080112244 e3267fdb3a [update] new version control panel 2022-08-16 10:10:46 +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 e2e0b5609a [update] add -sync-parameter 2022-08-09 14:18:38 +08:00
71 changed files with 3317 additions and 1381 deletions
+5
View File
@@ -1217,6 +1217,11 @@
"@hapi/hoek": "^8.3.0"
}
},
"@hyjiacan/vue-slideout": {
"version": "2.5.9",
"resolved": "https://registry.npmjs.org/@hyjiacan/vue-slideout/-/vue-slideout-2.5.9.tgz",
"integrity": "sha512-SSf0QaENGt9B2We8lL5QF+gNK7/pHqUEA8SiwUKtMTDj2rbjhGYFpCD+grV7oAAynGdiEIhQ3b3Mphh9/+keBg=="
},
"@intervolga/optimize-cssnano-plugin": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@intervolga/optimize-cssnano-plugin/-/optimize-cssnano-plugin-1.0.6.tgz",
+1
View File
@@ -15,6 +15,7 @@
"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",
+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">
+7
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'
@@ -101,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_
@@ -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>
@@ -379,8 +379,8 @@ export default {
toolbox: ['rect', 'clear'],
// toolbox: ['rect', 'polygon', 'lineX', 'lineY', 'keep', 'clear'],
xAxisIndex: 0,
// throttleType: 'debounce',
// throttleDelay: 5,
throttleType: 'debounce',
throttleDelay: 0,
}
this.showChartLoading('detail')
const timeDur = this.endTimeCurrent - this.startTimeCurrent
@@ -394,7 +394,7 @@ export default {
})
let scale = '1'
if (this.controlPanel.x.type === '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)會不一樣
@@ -413,11 +413,11 @@ export default {
this.currentScale = scale
this.chartDetailData.series[_gridNumber].data.length = 0
let dataListX
const channelX = parseInt(this.controlPanel.x.channel)
if (this.controlPanel.x.type !== '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.controlPanel.y.channel)
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)
@@ -464,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.controlPanel.x.type !== 'Time') {
if (this.controlPanel.x.axis.description !== 'Time') {
dataX = await this.getData(parseInt(scale), this.sampleMethod, dataListX[i].id, channelX, metaInfo)
}
var deltaX = 0
@@ -566,7 +566,7 @@ export default {
}
}
if (this.controlPanel.x.type === 'Time') {
if (this.controlPanel.x.axis.description === 'Time') {
this.chartDetailData.xAxis[_gridNumber].min = _startTime
this.chartDetailData.xAxis[_gridNumber].max = _endTime
} else {
@@ -576,7 +576,7 @@ export default {
_gridNumber += 1
}
if (this.controlPanel.x.type !== 'Time') {
if (this.controlPanel.x.axis.description !== 'Time') {
this.showOverviewChart = false
this.detailchartheight = '88vh'
// this.$refs.chart_detail.updateChartHeight()
@@ -652,8 +652,8 @@ export default {
// tang
if (this.initDone) {
const libName = this.metaList[gridIndex].device.library_name
const xType = (this.controlPanel.x.type === 'Time') ? 'Time' : ((libName === 'EliteZM15' || libName.includes('Elite_EDC') ? 'Elite' : 'EliteEIS'))
const xChannel = (this.controlPanel.x.channel === -1) ? undefined : this.controlPanel.x.channel + 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,
@@ -663,10 +663,10 @@ export default {
channelX: xChannel,
deviceNameY: libName.includes('EIS') ? 'EliteEIS' : 'Elite',
deviceIDY: '',
channelY: this.controlPanel.y.channel + 1,
channelY: this.controlPanel.y.axis.channel + 1,
})
}
if (this.controlPanel.x.type === 'Time') {
if (this.controlPanel.x.axis.description === 'Time') {
this.drawOverviewData()
}
this.drawDetailData() // reDraw
@@ -107,12 +107,12 @@ 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] && params.batch[0].areas.length !== 0) {
var boundary = {
@@ -12,77 +12,34 @@
<delete-file />
</div>
</div>
<!-- <div class="flex-container mb-2" v-show='false'>
<div class="flex sm2 xl2 md2 xs2 px-0 py-0">
<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"/>
</div>
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<change-unit :ref="'change_unit_x'" axis="x" @refreshChart="refreshChart"/>
</div>
</div>
<div class="flex-container mb-2" v-show='false'>
<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"/>
</div>
</div> -->
<!-- <div class="flex-container mb-2" v-show='false'>
<div class="flex sm2 xl2 md2 xs2 px-0 py-0">
<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"/>
</div>
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<change-unit :ref="'change_unit_y'" axis="y" @refreshChart="refreshChart"/>
</div>
</div>
<div class="flex-container mb-2" v-show='false'>
<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"/>
</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> -->
<!-- tang -->
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0">
<p class="display-6"> X-Axis </p>
</div>
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<change-axis-b :ref="'axis_x'" axis="x" @changeAxis="changeAxis"/>
<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-b
<control-unit
:ref="'unit_x'"
axis="x"
@changeUnit="refreshFormatter"
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-funct-b :ref="'funct_x'" axis="x" @changeFunct="changeFunct"/>
<control-funct
:ref="'funct_x'"
coordinate="x"
@changeFunct="changeFunct"
/>
</div>
</div>
<div class="flex-container mb-2">
@@ -90,23 +47,28 @@
<p class="display-6"> Y-Axis </p>
</div>
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<change-axis-b
<control-axis
:ref="'axis_y'"
axis="y"
coordinate="y"
@changeAxis="changeAxis"
/>
</div>
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<change-unit-b
<control-unit
:ref="'unit_y'"
axis="y"
@changeUnit="refreshFormatter"/>
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-funct-b :ref="'funct_y'" axis="y" @changeFunct="changeFunct"/>
<control-funct
:ref="'funct_y'"
coordinate="y"
@changeFunct="changeFunct"/>
</div>
</div>
<specific-integral :ref="'specific_integral'" @setBrushBoundary="setBrushBoundary"/>
@@ -127,14 +89,10 @@
<script>
import ShowResampleRate from '@/components/analysis/replay/toolbox/ShowResampleRate.vue'
// import ChangeAxis from '@/components/analysis/replay/toolbox/ChangeAxis.vue'
import ChangeAxisB from '@/components/analysis/replay/toolbox/ChangeAxisB.vue'
// import ChangeUnit from '@/components/analysis/replay/toolbox/ChangeUnit.vue'
import ChangeUnitB from '@/components/analysis/replay/toolbox/ChangeUnitB.vue'
// import ChangeScale from '@/components/analysis/replay/toolbox/ChangeScale.vue'
import ChangeFunctB from '@/components/analysis/replay/toolbox/ChangeFunctB.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'
@@ -145,15 +103,16 @@ import ChangeWindowStartAndSize from '@/components/analysis/replay/toolbox/Chang
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,
ChangeAxisB,
ChangeUnitB,
ChangeFunctB,
controlAxis,
controlUnit,
controlFunct,
ChangeCycle,
SpecificIntegral,
DownloadFile,
@@ -171,76 +130,87 @@ export default {
'controlPanel',
]),
},
props: {
},
async created () {
},
data () {
return {
deviceName: '',
libraryName: '',
showCycle: false,
innerCollapse: false,
tableRouter,
configRouter,
}
},
methods: {
...mapMutations('replay', [types.chart.updateAxisLabel]),
refreshFormatter (axis) {
this.updateAxisLabelChart({
chartID: 1,
axis: axis,
axisIndex: 0,
})
},
changeFunct (axis) {
this.refreshUnit()
this.refreshFormatter(axis)
this.$emit('changeFunctional', axis, this.controlPanel[axis].funct)
this.$emit('changeAxis', 0)
},
refreshAxis () {
const xType = this.controlPanel.x.type
const yType = this.controlPanel.y.type
const xFunct = this.controlPanel.x.funct
const yFunct = this.controlPanel.y.funct
this.$refs.axis_x.refreshAxis(xType, xFunct, yType, yFunct)
this.$refs.axis_y.refreshAxis(xType, xFunct, yType, yFunct)
},
refreshUnit (axis) {
const xType = this.controlPanel.x.type
const yType = this.controlPanel.y.type
const xFunct = this.controlPanel.x.funct
const yFunct = this.controlPanel.y.funct
if (axis === 'x') {
this.$refs.unit_x.refreshUnit(xType, xFunct, yType, yFunct)
} else {
this.$refs.unit_y.refreshUnit(xType, xFunct, yType, yFunct)
}
},
// initialize control buttons
init () {
//
this.deviceName = this.metaList[0].device.library_name
// tang
this.initDefaultControlPanel()
this.$refs.axis_x.init()
this.$refs.funct_x.init()
this.$refs.unit_x.init(this.controlPanel.x.type)
this.$refs.axis_y.init()
this.$refs.funct_y.init()
this.$refs.unit_y.init(this.controlPanel.y.type)
// prev
// 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')
@@ -248,145 +218,12 @@ export default {
refreshChart (options) {
this.$emit('refreshChart', options)
},
changeFunctional (axis, functional) {
this.$emit('changeFunctional', axis, functional)
},
changeAxis (gridIndex) {
this.$refs.funct_x.init()
this.$refs.funct_y.init()
this.$refs.unit_x.init(this.controlPanel.x.type)
this.$refs.unit_y.init(this.controlPanel.y.type)
this.refreshFormatter('x')
this.refreshFormatter('y')
this.$emit('changeFunctional', 'x', 'Linear')
this.$emit('changeFunctional', 'y', 'Linear')
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()
}
},
clearCycle () {
this.$refs.change_cycle.clear()
},
setBrushBoundary (boundary) {
this.$emit('setBrushBoundary', boundary)
},
/* switchCollapse () {
this.innerCollapse = this.innerCollapse ? false : true
console.log(this.innerCollapse)
}, */
initDefaultControlPanel () {
// use state meta to decide which default unit need to be used (like check I-V mode...)
const setting = this.GLOBAL.getDefaultChartTypeByMode(this.metaList[0].parameter_set.MODE, this.deviceName)
// x-axis
let settingType = setting[0]
let settingValue = setting[1]
if (this.deviceName === 'EliteZM15' || this.deviceName.includes('Elite_EDC')) {
if (settingType === 'Elite') {
// 1: I, 2: V, 3: R, 4: cycle
if (settingValue === 1) {
this.controlPanel.x.type = 'Current'
this.controlPanel.x.channel = 0
} else if (settingValue === 2) {
this.controlPanel.x.type = 'Voltage'
this.controlPanel.x.channel = 1
} else if (settingValue === 3) {
this.controlPanel.x.type = 'Resistance'
this.controlPanel.x.channel = 2
} else if (settingValue === 4) {
this.controlPanel.x.type = 'Cycle'
this.controlPanel.x.channel = 3
}
} else if (settingType === 'Time') {
this.controlPanel.x.type = 'Time'
this.controlPanel.x.channel = undefined
}
} else if (this.deviceName.includes('EIS')) {
if (settingType.includes('EIS')) {
if (settingValue === 3) {
this.controlPanel.x.type = 'Frequency'
} else if (settingValue === 5 || settingValue === 6 || settingValue === 7) {
this.controlPanel.x.type = 'Impedance'
} else if (settingValue === 8) {
this.controlPanel.x.type = 'Phase'
} else if (settingValue === 9) {
this.controlPanel.x.type = 'Current'
} else if (settingValue === 10) {
this.controlPanel.x.type = 'Default'
}
} else if (settingType === 'Elite') {
// 1: I, 2: V, 3: R
if (settingValue === 1) {
this.controlPanel.x.type = 'Current'
} else if (settingValue === 2) {
this.dataTcontrolPanel.xype = 'Voltage'
} else if (settingValue === 3) {
this.controlPanel.x.type = 'Resistance'
}
} else if (settingType === 'Time') {
this.controlPanel.x.type = 'Time'
}
}
// y-axis
settingType = setting[2]
settingValue = setting[3]
if (this.deviceName === 'EliteZM15' || this.deviceName.includes('Elite_EDC')) {
if (settingType === 'Elite') {
// 1: I, 2: V, 3: R, 4: cycle
if (settingValue === 1) {
this.controlPanel.y.type = 'Current'
this.controlPanel.y.channel = 0
} else if (settingValue === 2) {
this.controlPanel.y.type = 'Voltage'
this.controlPanel.y.channel = 1
} else if (settingValue === 3) {
this.controlPanel.y.type = 'Resistance'
this.controlPanel.y.channel = 2
} else if (settingValue === 4) {
this.controlPanel.y.type = 'Cycle'
this.controlPanel.y.channel = 3
}
} else if (settingType === 'Time') {
this.controlPanel.y.type = 'Time'
this.controlPanel.y.channel = undefined
}
} else if (this.deviceName.includes('EIS')) {
if (settingType.includes('EIS')) {
if (settingValue === 3) {
this.controlPanel.y.type = 'Frequency'
} else if (settingValue === 5 || settingValue === 6 || settingValue === 7) {
this.controlPanel.y.type = 'Impedance'
} else if (settingValue === 8) {
this.controlPanel.y.type = 'Phase'
} else if (settingValue === 9) {
this.controlPanel.y.type = 'Current'
} else if (settingValue === 10) {
this.controlPanel.y.type = 'Default'
}
} else if (settingType === 'Elite') {
// 1: I, 2: V, 3: R
if (settingValue === 1) {
this.controlPanel.y.type = 'Current'
} else if (settingValue === 2) {
this.dataTcontrolPanel.xype = 'Voltage'
} else if (settingValue === 3) {
this.controlPanel.y.type = 'Resistance'
}
} else if (settingType === 'Time') {
this.controlPanel.y.type = 'Time'
}
}
},
},
mounted () {
},
}
</script>
@@ -1,81 +0,0 @@
<template>
<div>
<va-select
v-model="controlPanel[axis].type"
testBy="name"
class="va-select-without-margin"
:options="typeOption"
:noClear='true'
@input="changeAxis()"
/>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
import { tableRouter } from '@/components/analysis/replay/toolbox/EliteReplayTable'
export default {
name: 'change-axis-b',
props: {
axis: {
type: String, // x or y
},
},
data () {
return {
typeOption: [],
tableRouter,
}
},
computed: {
...mapFields('replay', [
'controlPanel',
]),
},
methods: {
init (type) {
if (this.axis === 'x') {
this.typeOption = [
'Time',
'Current',
'Voltage',
'Resistance',
]
} else {
this.typeOption = [
'Current',
'Voltage',
'Resistance',
]
}
// init call change Axis
if (this.axis === 'y') {
this.$emit('changeAxis', 0) // temporarily use metaIndex for gridIndex
}
},
refreshAxis (xType, xFunct, yType, yFunct) {
const [xTable, yTable] = this.tableRouter.getTable(xType, xFunct, yType, yFunct)
if (this.axis === 'x') {
this.controlPanel[this.axis].type = xTable.name
this.controlPanel[this.axis].channel = xTable.channel
} else {
this.controlPanel[this.axis].type = yTable.name
this.controlPanel[this.axis].channel = yTable.channel
}
},
changeAxis () {
this.controlPanel[this.axis].channel = tableRouter.getChannel(this.controlPanel[this.axis].type)
this.$emit('changeAxis', 0)
},
},
}
</script>
<style lang="scss">
.va-select-without-margin {
.va-select {
margin-bottom: 0;
}
}
</style>
@@ -78,6 +78,7 @@ 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
@@ -90,9 +91,6 @@ export default {
this.showPanel = false
}
},
clear () {
this.showWhichCycles = '1'
},
async setCycle () {
if (this.isThisModeHasCycle === true) {
const dataCycleList = this.recInfo[this.metaID][this.cycleDataID][this.currentScale]
@@ -108,15 +106,14 @@ export default {
const cycleDict = this.getCycleDictRec()(cycleDataList)
this.cycleNum = Object.keys(cycleDict).length
let dataXList
if (this.controlPanel.x.type !== 'Time') {
dataXList = this.recInfo[this.metaID][this.controlPanel.x.channel][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.controlPanel.y.channel][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]
@@ -133,9 +130,9 @@ export default {
}
}
for (let i = startIndex; i <= endIndex; i++) {
const dataY = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataYList[i].id, this.controlPanel.y.channel, this.metaList[this.metaIndex])
if (this.controlPanel.x.type !== 'Time') {
const dataX = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataXList[i].id, this.controlPanel.x.channel, 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) {
filteredData.push([dataX[j][1], dataY[j][1]])
@@ -155,14 +152,13 @@ export default {
seriesIndex: this.metaIndex,
data: filteredData,
})
if (this.controlPanel.x.type === '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])
}
}
}
@@ -181,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>
@@ -1,11 +1,12 @@
<template>
<div>
<div class="flex row">
<va-radio-button
v-for="(funct, index) in functOption"
v-model="controlPanel[coordinate].funct"
:key="index"
v-model="controlPanel[axis].funct"
:option="funct"
@input="changeFunct()"
/>
</div>
</template>
@@ -13,11 +14,12 @@
<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: 'change-funct-b',
name: 'controlFunct',
props: {
axis: {
coordinate: {
type: String, // x or y
},
},
@@ -26,6 +28,7 @@ export default {
funct: '',
functOption: [],
tableRouter,
configRouter,
}
},
computed: {
@@ -34,22 +37,14 @@ export default {
]),
},
methods: {
init () {
this.controlPanel[this.axis].funct = 'Linear'
this.functOption = this.tableRouter.getFunct(this.axis)
init (xAxis, yAxis) {
this.controlPanel[this.coordinate].funct = 'Linear'
this.functOption = this.configRouter.getFunctOption(xAxis, yAxis, this.coordinate)
},
changeFunct () {
this.$emit('changeFunct', this.axis)
this.$emit('changeFunct', this.coordinate)
},
},
}
</script>
<style lang="scss">
.va-select-without-margin {
.va-select {
margin-bottom: 0;
}
}
</style>
@@ -1,11 +1,11 @@
<template>
<div>
<va-select
@input="changeUnit()"
v-model="controlPanel[axis].unit"
v-model="controlPanel[coordinate].unit"
class="va-select-without-margin"
:options="unitOption"
:noClear='true'
@input="changeUnit()"
/>
</div>
</template>
@@ -13,11 +13,12 @@
<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: 'change-unit-b',
name: 'controlUnit',
props: {
axis: {
coordinate: {
type: String, // x or y
},
},
@@ -26,6 +27,7 @@ export default {
unit: '',
unitOption: [],
tableRouter,
configRouter,
}
},
computed: {
@@ -34,22 +36,12 @@ export default {
]),
},
methods: {
init (type) {
this.controlPanel[this.axis].unit = this.tableRouter.getDefaultUnit(type)
this.unitOption = Object.keys(this.tableRouter.getOption(type))
},
refreshUnit (xType, xFunct, yType, yFunct) {
const [xTable, yTable] = this.tableRouter.getTable(xType, xFunct, yType, yFunct)
if (this.axis === 'x') {
this.controlPanel[this.axis].unit = xTable.defaultUnit
this.unitOption = Object.keys(xTable.option)
} else {
this.controlPanel[this.axis].unit = yTable.defaultUnit
this.unitOption = Object.keys(yTable.option)
}
init (axis) {
this.controlPanel[this.coordinate].unit = this.configRouter.getUnit(axis)
this.unitOption = this.configRouter.getUnitOption(axis)
},
changeUnit () {
this.$emit('changeUnit', this.axis)
this.$emit('changeUnit', this.coordinate)
},
},
}
@@ -1,4 +1,20 @@
const chartTable = {
// library definition
// const libraryInfo = {
// EDC: {
// x: ['Time',
// 'Current',
// 'Voltage',
// 'Resistance',
// ],
// y: ['Current',
// 'Voltage',
// 'Resistance',
// ],
// },
// }
// axis information
const axisInfo = {
// axis type
Time: {
name: 'Time',
@@ -57,13 +73,13 @@ const chartTable = {
name: 'Charge',
channel: -1,
option: {
nC: 1e6,
uC: 1e9,
mC: 1e12,
C: 1e15,
nAh: 3600 * 1e6,
uAh: 1600 * 1e9,
mAh: 3600 * 1e12,
Ah: 3600 * 1e15,
},
defaultUnit: 'C',
downloadUnit: 'C',
defaultUnit: 'mAh',
downloadUnit: 'mAh',
},
Power: {
name: 'Power',
@@ -87,54 +103,84 @@ const chartTable = {
defaultUnit: 'A/V',
downloadUnit: 'A/V',
},
Idiot: {
Impedance: {
name: 'Impedance',
chanel: 6,
option: {
: 1e-3,
Ω: 1,
: 1e3,
: 1e6,
},
downloadUnit: 'Ω',
defaultUnit: 'Ω',
},
None: {
name: 'not support',
channel: -1,
option: {
'not support': 1,
none: 1,
},
defaultUnit: 'not support',
downloadUnit: 'not support',
defaultUnit: 'none',
downloadUnit: 'none',
},
}
export const tableRouter = {
getChannel: (axis) => {
return chartTable[axis].channel
return axisInfo[axis].channel
},
getDefaultUnit: (axis) => {
return chartTable[axis].defaultUnit
return axisInfo[axis].defaultUnit
},
getOption: (axis) => {
return chartTable[axis].option
return axisInfo[axis].option
},
getTable: (xAxis, xFunct, yAxis, yFunct) => {
var xTable = chartTable[xAxis]
var yTable = chartTable.Idiot
var xTable = axisInfo[xAxis]
var yTable = axisInfo.None
if (yFunct === 'Linear' || yFunct === 'Log') {
yTable = chartTable[yAxis]
yTable = axisInfo[yAxis]
} else if (yFunct === 'Integral') {
if (xAxis === 'Time' && yAxis === 'Current') {
yTable = chartTable.Charge
yTable = axisInfo.Charge
} else if (xAxis === 'Current' && yAxis === 'Voltage') {
yTable = chartTable.Power
yTable = axisInfo.Power
} else if (xAxis === 'Voltage' && yAxis === 'Current') {
yTable = chartTable.Power
yTable = axisInfo.Power
}
} else if (yFunct === 'Differential') {
if (xAxis === 'Current' && yAxis === 'Voltage') {
yTable = chartTable.Resistance
yTable = axisInfo.Resistance
} else if (xAxis === 'Voltage' && yAxis === 'Current') {
yTable = chartTable.Transconductance
yTable = axisInfo.Transconductance
}
}
return [xTable, yTable]
},
getFunct (axis) {
if (axis === 'x') {
return ['Linear', 'Log']
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 {
return ['Linear', 'Log', 'Integral', 'Differential']
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) {
@@ -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()
+14 -10
View File
@@ -33,6 +33,7 @@
editFile()
showModal.editFile = false
}"
:noOutsideDismiss="true"
tabindex="0"
>
<va-input
@@ -179,7 +180,7 @@
{{ props.rowData.name }}
</template>
<template slot="parameter_set" slot-scope="props">
{{ (props.rowData.type==='folder') ? '' : getWorkingMode(props.rowData, props.rowData) }}
{{ getWorkingMode(props.rowData) }}
</template>
<template slot="created_at" slot-scope="props">
{{transDate(props.rowData.created_at)}}
@@ -427,7 +428,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)
@@ -447,7 +448,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)
@@ -468,7 +469,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()
@@ -590,6 +591,7 @@ export default {
},
fillDeleteInfo: function (info) {
if (info.type === 'folder') {
this.deleteInfo.metaID = undefined
this.deleteInfo.folderID = info.id
this.deleteInfo.name = info.name
} else {
@@ -752,16 +754,17 @@ export default {
}
},
replay: function (meta) {
const href = location.href.split('/')[2]
if (meta.device.library_name.includes('Neulive') === true) {
// window.open('http://' + location.href.split('/')[2].split(':')[0] + '/#/admin/data-replay/' + meta.id)
this.$router.push({
path: '/admin/data-replay/' + meta.id,
})
} else if (meta.device.library_name.includes('Elite') === true) {
// window.open('http://' + location.href.split('/')[2].split(':')[0] + '/#/admin/data-replay/elite/' + meta.id)
this.$router.push({
path: '/admin/data-replay/elite/' + meta.id,
})
window.open('http://' + href + '/#/admin/data-replay/elite/' + meta.id)
// this.$router.push({
// path: '/admin/data-replay/elite/' + meta.id,
// })
}
},
spike: function (meta) {
@@ -771,9 +774,10 @@ export default {
})
}
},
getWorkingMode: function (library, mode) {
getWorkingMode: function (rowData) {
try {
return configTable.getModeConfig(library, mode).name
if (rowData.type === 'folder') return ''
return configTable.getModeConfig(rowData.device.library_name, rowData.parameter_set.MODE).name
} catch {
return ''
}
+51 -17
View File
@@ -4,17 +4,21 @@
<project-manager/>
</div>
<div
:class="(taskViewPanel.show || projectManagerPanel.show)
? (taskViewPanel.show && projectManagerPanel.show)
? cardStyle.small
: cardStyle.medium
:class="(projectManagerPanel.show)
? cardStyle.medium
: cardStyle.large
">
<project-view @start_project="startProject($event)" @stop_project="stopProject($event)" @save_project="saveProject($event)"/>
<project-view @start_project="startProject($event)" @stop_project="stopProject($event)" @save_project="saveProject($event)" @detect="detect"/>
</div>
<div :class="cardStyle.small" v-show="taskViewPanel.show">
<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/>
</div>
</slide-out>
</div>
</template>
@@ -22,7 +26,7 @@
import ProjectManager from '@/components/project/manager/ProjectManager'
import ProjectView from '@/components/project/view/ProjectView'
import ProjectTask from '@/components/project/task/ProjectTask'
import { mapActions } from 'vuex'
import { mapActions, mapGetters } from 'vuex'
import { mapFields } from 'vuex-map-fields'
import types from '@/store/modules/project/types'
import { taskInfo } from '@/data/task/TaskInfo'
@@ -35,6 +39,9 @@ export default {
ProjectTask,
},
computed: {
...mapGetters('project', [
types.project.getSelect,
]),
...mapFields('project', [
'projectConfigList',
'runningProjectList',
@@ -74,7 +81,7 @@ export default {
},
async '+/get_running_project/+' (data, topic) {
this.runningProjectList.length = 0
const runningProjects = JSON.parse(String.fromCharCode.apply(null, data)).data
const runningProjects = JSON.parse(new TextDecoder().decode(data)).data
this.runningProjectList.push(...runningProjects)
},
async '+/broadcast' (data, topic) {
@@ -125,16 +132,28 @@ export default {
this.mqttUnSub(id + '/get_running_project/+')
},
initPage: async function () {
await this.initProject()
await taskInfo.updateTaskInfo()
this.pageMqttSub(taskInfo.getTaskInfo().controllerID)
},
startProject: function (project) {
console.log('start_project', project)
console.log('taskInfo.getTaskInfo().controllerID', taskInfo.getTaskInfo().controllerID)
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'run_project/0',
project: project,
}))
let deviceReady = true
for (const device of Object.values(this.getSelectProject.device)) {
if (device.pairStatus !== 1) {
if (device.pair === null) {
window.alert('Device ' + device.name + ' is not connected yet.')
} else {
window.alert('Device ' + device.pair + ' is not connected yet.')
}
deviceReady = false
}
}
if (deviceReady === true) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'run_project/0',
project: project,
}))
}
},
stopProject: function (project) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
@@ -153,9 +172,24 @@ export default {
},
)
},
detect: async function (device) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: device,
instruction: 'VIS_DEVICE_DETECT',
}))
setTimeout(() => {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: device,
instruction: 'VIS_DEVICE_DONE',
}))
}, 5000)
},
...mapActions('project',
[
types.project.init,
types.project.update,
types.project.addDevice,
],
@@ -170,10 +204,10 @@ export default {
header: 'get_device_info_all/0',
}))
const project = await this.API.project.getAll()
console.log('project: ', project)
// console.log('project: ', project)
this.projectConfigList.length = 0
this.projectConfigList.push(...project.data)
console.log('projectConfigList: ', this.projectConfigList)
// console.log('projectConfigList: ', this.projectConfigList)
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'get_running_project/0',
@@ -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">
<div class="row">
<div class="flex d-flex xs5 sm5 lg5 xl5">
@@ -19,6 +19,7 @@
</va-item-label> -->
</va-item-section>
<va-item-section side>
<va-icon class="fa fa-copy mr-2" color="bloack" @click.native.stop="copyProject({ project: project, index: index, api: API })"></va-icon>
<va-icon class="fa fa-close" color="danger" @click.native.stop="deleteProject({ project: project, index: index, api: API })"></va-icon>
</va-item-section>
</va-item>
@@ -55,6 +56,7 @@ export default {
},
...mapActions('project',
[
types.project.copy,
types.project.select,
types.project.delete,
],
+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,32 +1,16 @@
<template>
<div class="flex sm12 xl12 md12 xs12">
<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>
<span>Device</span>
<div class="flex d-flex" v-if="Object.keys(registeredDevice).length > 0">
<div v-for="(device, deviceKey) in registeredDevice" :key="deviceKey">
<va-button @click="selectDevice(deviceKey)" small>{{ device.name }}</va-button>
<!-- <span>Device</span>
<div class="row flex sm12 xl12 md12 xs12" v-if="Object.keys(registeredDevice).length > 0">
<div class="flex sm12 xl6 md6 xs12" v-for="(device, key) in registeredDevice" :key="key">
<va-button @click="selectDevice(key)" small>{{ getDeviceShowNameProject(key) }}</va-button>
</div>
</div>
<div align="center" v-else>
No registered device found.
</div>
</div> -->
<div v-if="settingStep >= 1">
<span>Action</span>
<!-- <span>Action</span> -->
<div class="flex d-flex">
<div v-for="action in actionTemplate" :key="action">
<va-button color="info" @click="selectAction(action)" small>{{ action }}</va-button>
@@ -34,28 +18,13 @@
</div>
</div>
<div v-if="settingStep >= 2">
<span>Condition</span>
<!-- <span>Condition</span> -->
<div v-for="(condition, key) in conditionObj" :key="key">
<!-- <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">
<div 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"/>
<input style="width: 100px;" class="mr-1" :type="condition.type" v-model="condition.value"/>
<span>{{ condition.suffix }}</span>
</div>
</div>
@@ -94,16 +63,18 @@ export default {
types.project.getSelect,
types.project.getDevice,
types.project.getAllDevice,
types.project.getDeviceShowName,
]),
...mapFields('project', [
'taskSelectKey',
'taskViewPanel',
'deviceSelectKey',
]),
},
data () {
return {
settingStep: 0,
settingStep: 1,
registeredDevice: {},
deviceSelect: '',
@@ -119,7 +90,6 @@ export default {
project: {},
device: {},
task: {},
}
},
methods: {
@@ -166,35 +136,27 @@ export default {
}
for (const key in this.conditionObj) {
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)
if (this.conditionObj[key].select) {
// create fake condition if duplicate type & target
if (Object.values(this.getSelectTask.condition).findIndex(ele => ele.type === 'previous_task_done' && ele.target === this.deviceSelect) === -1) {
// create fake start previous done
const fakeStartActionUUID = this.GLOBAL.getUUID()
const fakeAction = this.createAction(fakeStartActionUUID, 'start', this.deviceSelect)
const fakeConditionUUID = this.GLOBAL.getUUID()
const fakeCondition = this.createCondition(fakeConditionUUID, 'previous_task_done', 'equal', '')
this.setConditionTask({ condition: fakeCondition })
fakeAction[fakeStartActionUUID].condition.push(fakeConditionUUID)
this.setActionTask({ action: fakeAction })
}
} 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) {
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)
}
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 })
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 () {
@@ -211,21 +173,23 @@ export default {
]),
},
mounted () {
// const project = this.getSelectProject
// const device = this.getAllDeviceProject
// const task = this.getSelectTask
this.project = this.getSelectProject
this.device = this.getAllDeviceProject
this.deviceSelect = this.deviceSelectKey
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', this.project)
// console.log('task', this.task)
this.registeredDevice = this.device
},
watch: {
// refresh parameter when click different task's parameter
deviceSelectKey: {
handler: function () {
this.deviceSelect = this.deviceSelectKey
},
},
},
}
</script>
@@ -1,54 +1,54 @@
<template>
<div class="flex sm12 xl12 md12 xs12">
<div class="task-config__header-separator mb-1">
<div class="task-config__header-text">
<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>
<va-list fit class="mb-2">
<va-item v-for="(device, index) in getSelectProject.device" :key="index" >
<va-item-section side>
<va-checkbox
:value="device.isSelect"
:arrayValue="(taskSelectKey != undefined)? String(taskSelectKey) : '-1'"
@input="selectDevice($event, device, index)"
ref="checkbox_ref"
/>
</va-item-section>
<va-list fit class="mb-2 pb-0">
<va-list-label>
Register
</va-list-label>
<va-item-section avatar class="ml-0">
<va-avatar style="border-radius: 0;">
<img
src='@/assets/img/elite_img.png' :alt="device.name">
</va-avatar>
</va-item-section>
<template v-for="(device, index) in deviceListInOrder">
<va-item :class="taskDevice.includes(device[0]) === true ? 'device-list-focus': ''" :key="'register' + String(index)" @click="selectDevice(device, index)" clickable>
<va-item-section avatar>
<va-avatar style="border-radius: 0;">
<img src='@/assets/img/elite_img.png' :alt="device[1].name">
</va-avatar>
</va-item-section>
<va-item-section>
<va-item-label>
{{ device.name }}
</va-item-label>
<va-item-section>
<va-item-label>
{{ getDeviceShowNameProject(device[0]) }}
</va-item-label>
</va-item-section>
</va-item>
</template>
</va-list>
<va-list fit class="mb-2 pb-0">
<va-list-label>
Connect
</va-list-label>
<va-item-label caption>
{{ device.connectDevice.device_address }}
</va-item-label>
</va-item-section>
</va-item>
<template v-for="(device, index) in getNotRegisterDeviceProject()">
<va-item :key="'connect' + index" clickable @click="registerConnectDevice(device)">
<va-item-section avatar>
<va-avatar style="border-radius: 0;">
<img src='@/assets/img/elite_img.png' :alt="device.macAddress">
</va-avatar>
</va-item-section>
<va-item-section>
<va-item-label>
{{ device.macAddress }}
</va-item-label>
</va-item-section>
</va-item>
</template>
</va-list>
</div>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
import { mapGetters } from 'vuex'
// import eliteImgUrl from '@/assets/img/elite_img.png'
// import neuliveImgUrl from '@/assets/img/neulive_img.png'
import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/types'
export default {
@@ -56,9 +56,18 @@ export default {
components: {
},
computed: {
deviceListInOrder () {
return Object.entries(this.getSelectProject.device).sort((a, b) => a[1].order - b[1].order)
},
taskDevice () {
return this.getSelectTask.device
},
...mapGetters('project', [
types.project.getSelect,
types.task.getSelect,
types.project.getDeviceShowName,
types.project.getNotRegisterDevice,
]),
...mapFields('project', [
@@ -71,38 +80,55 @@ export default {
}
},
methods: {
selectDevice: function (event, device, key) {
// 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)
selectDevice: function (device, index) {
if (this.taskDevice.includes(device[0]) === false) {
this.appendToTask(device[0])
} else {
// if select all tasks
if (event.includes('-1')) {
// check all
device.isSelect = ['-1', ...Array(this.getSelectProject.task.length).fill().map((_, index) => String(index))]
for (const task of this.getSelectProject.task) {
if (!task.device.includes(key)) {
task.device.push(key)
}
}
} else {
// uncheck all
device.isSelect = []
for (const task of this.getSelectProject.task) {
task.device = task.device.filter(item => item !== key)
}
}
this.removeFromTask(device[0])
}
},
resetDevice: function () {
},
registerConnectDevice: async function (device) {
// register device
await this.createDeviceProject({
name: device.name,
library: device.library,
pair: device.macAddress,
pairStatus: 1,
order: this.getDeviceMaxOrderProject,
})
// select device
this.selectDevice(this.deviceListInOrder[this.deviceListInOrder.length - 1])
},
appendToTask: function (key) {
// if select single task
this.getSelectTask.device.push(key)
},
removeFromTask: function (key) {
// if select single task
this.getSelectTask.device = this.getSelectTask.device.filter(item => item !== key)
},
closePanel: function () {
this.taskViewPanel.show = !(this.taskViewPanel.show)
},
...mapActions('project',
[
types.project.createDevice,
],
),
},
mounted () {
},
}
</script>
<style lang="scss">
.device-list-focus {
background: #ebedff;
border: 1px solid #dbdcf0;
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.25);
border-radius: 5px;
}
</style>
@@ -1,6 +1,6 @@
<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">
@@ -10,12 +10,13 @@
/>
</va-button>
</div>
</div>
</div> -->
<div>
<device-parameter-recording
:ref="'device_parameter_ref'"
:parameter="parameter"
:library="'Elite_EDC_1.5'"
:library="device.library"
:place="'scheduler'"
@setParameter="setParameter"
@setParameterWithDebounce="setParameterWithDebounce"
/>
@@ -110,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',
@@ -122,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"/>
+6 -20
View File
@@ -1,6 +1,7 @@
<template>
<div>
<va-card style="height: 90vh; overflow: auto; display: block;">
<!-- <pre>{{ getSelectProject }} </pre> -->
<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>
@@ -9,7 +10,7 @@
<span>please select project</span>
</div>
<div v-else>
<project-menu/>
<project-menu @detect="detect"/>
<project-table/>
<div align="right" v-if="lockMode === false">
<va-button @click="save">Save</va-button>
@@ -61,6 +62,9 @@ export default {
save: function () {
this.$emit('save_project', this.getSelectProject)
},
detect: function (device) {
this.$emit('detect', device)
},
...mapActions('project',
[
types.project.update,
@@ -69,24 +73,6 @@ export default {
),
},
watch: {
projectSelectIndex: {
handler: async function () {
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')
@@ -4,54 +4,62 @@
<div class="flex d-flex">
<switch-project/>
<add-task/>
<add-device @showDeviceModal="showDeviceModal"/>
<!-- <clear-task/>
<save-project/>
<import-project/>
<export-project/>
<delete-project/> -->
<!-- <add-device @showDeviceModal="showDeviceModal"/> -->
<va-button @click="showCycleModal" small>+ Cycle</va-button>
</div>
</div>
<project-device @showDeviceModal="showDeviceModal($event)"></project-device>
<device-modal ref="device_modal_ref"></device-modal>
<project-device @showDeviceModal="showDeviceModal"></project-device>
<new-device-modal ref="device_modal_ref" @detect="detect"></new-device-modal>
<cycle-modal ref="cycle_modal_ref" @createCycle="createCycle"></cycle-modal>
</div>
</template>
<script>
import SwitchProject from '@/components/project/view/menu/components/SwitchProject'
import AddTask from '@/components/project/view/menu/components/AddTask'
// import ClearTask from '@/components/project/view/menu/components/ClearTask'
// import ExportProject from '@/components/project/view/menu/components/ExportProject'
// import ImportProject from '@/components/project/view/menu/components/ImportProject'
// import SaveProject from '@/components/project/view/menu/components/SaveProject'
// import DeleteProject from '@/components/project/view/menu/components/DeleteProject'
import AddDevice from '@/components/project/view/menu/components/AddDevice'
// import AddDevice from '@/components/project/view/menu/components/AddDevice'
import ProjectDevice from '@/components/project/view/menu/components/ProjectDevice'
import DeviceModal from '@/components/project/view/menu/components/DeviceModal'
import NewDeviceModal from '@/components/project/view/menu/components/NewDeviceModal'
import CycleModal from '@/components/project/view/menu/components/CycleModal'
import { mapActions } from 'vuex'
import types from '@/store/modules/project/types'
export default {
name: 'project-menu',
components: {
SwitchProject,
AddTask,
AddDevice,
// ClearTask,
// ExportProject,
// ImportProject,
// SaveProject,
// DeleteProject,
// AddDevice,
ProjectDevice,
DeviceModal,
NewDeviceModal,
CycleModal,
},
data () {
return {
}
},
methods: {
showDeviceModal: function (device) {
this.$refs.device_modal_ref.show()
this.$refs.device_modal_ref.initSetting(device)
detect: function (device) {
this.$emit('detect', device)
},
showDeviceModal: function (key, device) {
this.$refs.device_modal_ref.show()
this.$refs.device_modal_ref.initSetting(key, device)
},
createCycle: function (cycleInfo) {
this.createCycleTask({ cycleInfo: cycleInfo })
},
showCycleModal: function () {
this.$refs.cycle_modal_ref.show()
this.$refs.cycle_modal_ref.reset()
},
...mapActions('project',
[
types.task.createCycle,
],
),
},
}
</script>
@@ -1,6 +1,6 @@
<template>
<div>
<va-button @click="addDevice" small>ADD DEVICE</va-button>
<va-button @click="addDevice" small>+ DEVICE</va-button>
</div>
</template>
<script>
@@ -1,6 +1,6 @@
<template>
<div>
<va-button @click="createTask" small>ADD TASK</va-button>
<va-button @click="createTask" small>+ TASK</va-button>
</div>
</template>
<script>
@@ -0,0 +1,258 @@
<template>
<div>
<va-modal
class="flex sm12 xl12 md12 xs12"
v-model="showModal"
size="small"
:noOutsideDismiss="true"
hide-default-actions
>
<template slot="header">
<div class="d-flex mb-3">
<va-icon name="fa fa-bluetooth-b mr-3" color="primary"/>
<h5 v-if="Object.keys(cycleInfo).length == 0" class="mt-0 mb-0">Create Cycle</h5>
<h5 v-else class="mt-0 mb-0">{{ cycleInfo.name }}</h5>
</div>
</template>
<div class="row">
<div class="row flex sm6 xl6 md6 xs6">
<div class="flex sm2 xl2 md2 xs2 pt-2">
<span>Start</span>
</div>
<div class="flex sm8 xl8 md8 xs8">
<va-select
:label="''"
v-model="task.start"
textBy="name"
class="va-select-without-margin"
:options="taskOptions"
:noClear='true'
/>
</div>
</div>
<div class="row flex sm6 xl6 md6 xs6">
<div class="flex sm2 xl2 md2 xs2 pt-2">
<span>End</span>
</div>
<div class="flex sm8 xl8 md8 xs8">
<va-select
:label="''"
v-model="task.end"
textBy="name"
class="va-select-without-margin"
:options="taskOptions"
:noClear='true'
/>
</div>
</div>
<div class="row flex sm12 xl12 md12 xs12">
<div class="flex sm2 xl2 md2 xs2 pt-2">
<span> Cycle No. </span>
</div>
<div class="flex sm2 xl2 md2 xs2">
<va-input v-model="task.cycle"/>
</div>
</div>
<div class="row flex sm12 xl12 md12 xs12" style="height: 40px;">
<div class="flex sm1 xl1 md1 xs1">
<va-checkbox
v-model="task.useID"
/>
</div>
<div class="flex sm4 xl4 md4 xs4">
Use ID As Header
</div>
<div v-if="task.useID" class="flex sm4 xl4 md4 xs4">
<va-input v-model="task.id"></va-input>
</div>
</div>
<!-- <div class="row flex sm12 xl12 md12 xs12">
<div class="flex sm1 xl1 md1 xs1">
<va-checkbox
v-model="task.buttonTrigger"
/>
</div>
<div class="flex sm6 xl6 md6 xs6">
Wait Until Button Press In Next Loop
</div>
</div> -->
</div>
<div class="flex-center sm12 xl12 md12 xs12">
<va-button v-if="Object.keys(cycleInfo).length > 0" @click="removeCycle" color="danger">Remove</va-button>
<va-button @click="hide">Cancel</va-button>
<va-button @click="createCycle" @keyup.native="keyFunction($event,item)">OK</va-button>
</div>
</va-modal>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/types'
export default {
name: 'cycle-modal',
components: {
},
computed: {
...mapGetters('project', [
types.project.getSelect,
]),
...mapFields('project', [
'deviceConnectList',
'projectLibrary',
]),
},
data () {
return {
showModal: false,
taskOptions: [],
task: {
id: '',
name: '',
start: -1,
end: -1,
cycle: '1',
useID: false,
buttonTrigger: false,
uuid: '',
},
cycleInfo: {},
}
},
methods: {
show: function () {
this.showModal = true
// window.addEventListener('keydown', (e) => {
// console.log('e', e)
// if (e.keyCode === 13) {
// this.createCycle()
// }
// }, { once: true })
},
hide: function () {
this.showModal = false
},
createCycle: async function () {
this.showModal = false
const project = this.getSelectProject
if (Object.keys(this.cycleInfo).length === 0) {
this.$emit('createCycle', this.task)
}
if (Object.keys(this.cycleInfo).length !== 0) {
this.cycleInfo.max = this.task.cycle
this.cycleInfo.name = this.task.name
this.cycleInfo.useID = this.task.useID
this.cycleInfo.id = this.task.id
const originStartIndex = await this.getIndexTask({ project: project, uuid: this.cycleInfo.range[0] })
const newStartIndex = await this.getIndexTask({ project: project, uuid: this.task.start.value })
if (this.task.useID === true) {
const condition = project.task[originStartIndex].condition
const action = project.task[originStartIndex].action
delete condition[(Object.keys(condition).find(key => condition[key].type === 'after_task_run'))]
const conditionUUID = this.GLOBAL.getUUID()
const newCond = await this.createConditionTask({ uuid: conditionUUID, condition: 'until_button_trigger', compOp: 'equal', value: '' })
project.task[originStartIndex].condition = Object.assign({}, condition, newCond)
action[Object.keys(action).find(key => action[key].type === 'cycle')].condition.push(conditionUUID)
project.task[originStartIndex].name = this.task.name
} else {
const condition = project.task[originStartIndex].condition
const action = project.task[originStartIndex].action
delete condition[(Object.keys(condition).find(key => condition[key].type === 'until_button_trigger'))]
const conditionUUID = this.GLOBAL.getUUID()
const newCond = await this.createConditionTask({ uuid: conditionUUID, condition: 'after_task_run', compOp: 'equal', value: '0' })
project.task[originStartIndex].condition = Object.assign({}, condition, newCond)
action[Object.keys(action).find(key => action[key].type === 'cycle')].condition.push(conditionUUID)
}
if (Number(originStartIndex) + 1 !== Number(newStartIndex)) {
await this.swapTask({ project: project, originIndex: originStartIndex, newIndex: newStartIndex })
}
const originEndIndex = await this.getIndexTask({ project: project, uuid: this.cycleInfo.range[1] })
const newEndIndex = await this.getIndexTask({ project: project, uuid: this.task.end.value })
project.task[originEndIndex].name = this.task.name
if (Number(originEndIndex) - 1 !== Number(newEndIndex)) {
await this.swapTask({ project: project, originIndex: originEndIndex, newIndex: newEndIndex + 1 })
}
}
return true
},
removeCycle: async function () {
const project = this.getSelectProject
// remove project cycle
project.cycle.splice(project.cycle.findIndex(ele => ele.name === this.cycleInfo.name), 1)
// remove left cycle task
const originStartIndex = await this.getIndexTask({ project: project, uuid: this.cycleInfo.range[0] })
await this.deleteTask({ project: project, index: originStartIndex })
// remove right cycle task
const originEndIndex = await this.getIndexTask({ project: project, uuid: this.cycleInfo.range[1] })
await this.deleteTask({ project: project, index: originEndIndex })
this.showModal = false
return true
},
updateTaskOptions: function () {
const taskOptions = []
const project = this.getSelectProject
for (var idx = 0; idx < project.task.length; idx++) {
if (Object.keys(this.cycleInfo).length !== 0) {
if (this.cycleInfo.range.findIndex(ele => ele === project.task[idx].uuid) !== -1) continue
}
taskOptions.push({
id: idx,
name: project.task[idx].name,
value: project.task[idx].uuid,
})
}
this.taskOptions = taskOptions
},
reset: function () {
this.updateTaskOptions()
this.task.start = this.taskOptions[0]
this.task.end = this.taskOptions[this.taskOptions.length - 1]
},
setCycleInfo: async function (project, uuid) {
this.cycleInfo = project.cycle.find(ele => ele.range.find(ele => ele === uuid))
const startIndex = await this.getIndexTask({ project: project, uuid: this.cycleInfo.range[0] }) + 1
const endIndex = await this.getIndexTask({ project: project, uuid: this.cycleInfo.range[1] }) - 1
this.updateTaskOptions()
this.task.start = this.taskOptions[this.taskOptions.findIndex(ele => ele.value === project.task[startIndex].uuid)]
this.task.end = this.taskOptions[this.taskOptions.findIndex(ele => ele.value === project.task[endIndex].uuid)]
this.task.name = this.cycleInfo.name
this.task.cycle = this.cycleInfo.max
this.task.useID = this.cycleInfo.useID
this.task.id = this.cycleInfo.id
},
...mapActions('project',
[
types.project.addDevice,
types.project.findDevice,
types.project.setDevice,
types.task.init,
types.task.create,
types.task.save,
types.task.delete,
types.task.select,
types.task.getIndex,
types.task.swap,
types.task.createCondition,
],
),
},
mounted () {
},
}
</script>
@@ -0,0 +1,153 @@
<template>
<div>
<va-modal
class="flex sm12 xl12 md12 xs12"
v-model="showModal"
size="small"
:noOutsideDismiss="true"
hide-default-actions
>
<template slot="header">
<div class="d-flex mb-3">
<va-icon name="fa fa-bluetooth-b mr-3" color="primary"/>
<h5 class="mt-0 mb-0">Choose Device</h5>
</div>
</template>
<va-list fit class="mb-2 pb-0">
<va-list-label>
Connect
</va-list-label>
<va-item v-if="deviceList.length === 0">
<va-item-section>
There is no connected device.
</va-item-section>
</va-item>
<template v-else v-for="(device, index) in deviceList">
<va-item :class="deviceSelect === index ? 'device-list-focus': ''" :key="'connect-' + index" @click="selectDevice(device, index)" clickable>
<va-item-section avatar>
<va-avatar style="border-radius: 0;">
<img src='@/assets/img/elite_img.png' :alt="device.macAddress">
</va-avatar>
</va-item-section>
<va-item-section>
{{ device.macAddress }}
</va-item-section>
<va-item-section side>
<va-icon name="fa fa-map-marker" color="gray" @click.native="detect(device.macAddress)"/>
</va-item-section>
</va-item>
<!-- <va-list-separator v-if="index < deviceList.length - 1" :key="'separator-' + index" /> -->
</template>
</va-list>
<div class="flex-center sm12 xl12 md12 xs12">
<va-button color='danger' @click="removeDevice">Remove</va-button>
<va-button @click="hide">Cancel</va-button>
<va-button @click="changeDevice">OK</va-button>
</div>
</va-modal>
</div>
</template>
<script>
// import { mapFields } from 'vuex-map-fields'
import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/types'
export default {
name: 'add-device-modal',
components: {
},
computed: {
optionDeviceVersion () {
return (this.optionDeviceVersionObj[this.device.product.value] !== undefined)
? this.optionDeviceVersionObj[this.device.product.value]
: undefined
},
...mapGetters('project', [
types.project.getSelect,
types.project.getDeviceShowName,
]),
// ...mapFields('project', [
// 'deviceConnectList',
// ]),
},
data () {
return {
showModal: false,
showDisplayDevice: false,
key: '',
device: {},
deviceList: [],
deviceSelect: -1,
}
},
methods: {
show: function () {
this.showModal = true
},
hide: function () {
this.showModal = false
},
detect: function (device) {
if (device) this.$emit('detect', device)
},
selectDevice: function (device, index) {
this.deviceSelect = index
},
changeDevice: function () {
if (this.deviceList[this.deviceSelect]) {
this.device.pair = this.deviceList[this.deviceSelect].macAddress
}
this.hide()
},
removeDevice: function () {
this.deleteDeviceProject({ deviceKey: this.key })
this.hide()
},
getDeviceList: async function (device) {
const deviceList = await this.checkNotRegisterDeviceProject({ library: device.library })
const _device = { macAddress: device.pair, library: device.library }
if (device.pair !== null) {
this.deviceList = [_device, ...deviceList]
} else {
this.deviceList = [...deviceList]
}
},
initSetting: function (key, device) {
this.key = key
this.device = device
this.deviceList = []
this.deviceSelect = 0
this.getDeviceList(device)
},
...mapActions('project',
[
types.project.addDevice,
types.project.findDevice,
types.project.setDevice,
types.project.deleteDevice,
types.project.checkNotRegisterDevice,
types.task.init,
types.task.create,
types.task.save,
types.task.delete,
types.task.select,
],
),
},
mounted () {
},
}
</script>
<style lang="scss">
.device-list-focus {
background: #ebedff;
border: 1px solid #dbdcf0;
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.25);
border-radius: 5px;
}
</style>
@@ -1,11 +1,20 @@
<template>
<div class="row">
<div class="flex d-flex">
<div v-for="(device, index) in getSelectProject.device" :key="index">
<va-button color="info" @click="showDeviceModal(device)" small>
<va-icon name="fa fa-close" @click.native.stop="deleteDevice(index)"></va-icon>
{{ device.name }} {{ device.connectDevice && device.connectDevice.device_address }}
</va-button>
<div class="flex d-flex" v-if="showLibrary === true">
<va-button small @click="clickShowDevice('EDC')">EDC</va-button>
<va-button small @click="clickShowDevice('EIS')">EIS</va-button>
<va-button small @click="cancelSelectDevice()">X</va-button>
</div>
<div class="flex d-flex" v-if="showDevice === false && showLibrary === false">
<draggable class="flex row" :list="deviceListInOrder" :move="handleMove" @end="handleDragEnd">
<div class="mr-2" v-for="(device, index) in deviceListInOrder" :key="index">
<button :class="device[1].pairStatus === 1 ? 'pair-button mr-2' : 'not-pair-button mr-2'" @click="showDeviceModal(device[0], device[1])">
<span class="pair-button-text">{{ getDeviceShowNameProject(device[0]) }}</span>
</button>
</div>
</draggable>
<div>
<button class="add-button" icon="fa fa-plus" @click="clickShowLibrary"><span class="add-button-text">+</span></button>
</div>
</div>
</div>
@@ -15,46 +24,154 @@
import { mapFields } from 'vuex-map-fields'
import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/types'
import draggable from 'vuedraggable'
export default {
name: 'project-device',
components: {
draggable,
},
computed: {
deviceListInOrder () {
return Object.entries(this.getSelectProject.device).sort((a, b) => a[1].order - b[1].order)
},
...mapGetters('project', [
types.project.getSelect,
types.project.getDeviceShowName,
types.project.getDeviceMaxOrder,
]),
...mapFields('project', [
'projectLibrary',
'projectSelectIndex',
]),
},
data () {
return {
showDevice: false,
showLibrary: false,
notRegisterDevice: [],
index: -1,
futureIndex: -1,
}
},
methods: {
showDeviceModal: function (device) {
this.$emit('showDeviceModal', device)
clickShowLibrary: async function () {
this.notRegisterDevice = await this.checkNotRegisterDeviceProject({})
if (this.notRegisterDevice.length === 0) {
this.showLibrary = true
return true
}
await this.createDeviceProject({
name: this.notRegisterDevice[0].name,
library: this.notRegisterDevice[0].library,
pair: this.notRegisterDevice[0].macAddress,
pairStatus: 1,
order: this.getDeviceMaxOrderProject,
})
return true
},
clickShowDevice: async function (library) {
this.showLibrary = false
await this.createDeviceProject({
name: library + '-' + String(Object.keys(this.getSelectProject.device).length + 1),
library: library,
pair: null,
pairStatus: 0,
order: this.getDeviceMaxOrderProject,
})
return false
},
cancelSelectDevice: function () {
this.showLibrary = false
},
showDeviceModal: function (key, device) {
this.$emit('showDeviceModal', key, device)
},
deleteDevice: function (deviceIndex) {
this.deleteDeviceProject({ index: deviceIndex })
},
handleMove (e) {
const { index, futureIndex } = e.draggedContext
this.index = index
this.futureIndex = futureIndex
return false // disable sort
},
handleDragEnd () {
const changeList = ['name', 'library', 'pair', 'pairStatus']
const deviceListTemp = JSON.parse(JSON.stringify(this.deviceListInOrder))
const keyOld = deviceListTemp[this.index][0]
const keyNew = deviceListTemp[this.futureIndex][0]
const deviceList = this.getSelectProject.device
for (const key of changeList) {
deviceList[keyOld][key] = deviceListTemp[this.futureIndex][1][key]
deviceList[keyNew][key] = deviceListTemp[this.index][1][key]
}
},
...mapActions('project',
[
types.project.createDevice,
types.project.deleteDevice,
types.project.checkNotRegisterDevice,
types.project.checkPairDeviceExist,
],
),
},
mounted () {
for (const device in this.getSelectProject.device) {
if (this.projectLibrary === null) {
this.projectLibrary = this.getSelectProject.device[device].library.value
}
}
},
watch: {
projectSelectIndex: {
immediate: true,
handler: async function (val) {
console.log('projectSelectIndex', val)
this.checkPairDeviceExistProject()
},
},
},
}
</script>
<style lang="scss">
.add-button {
width: 38px;
height: 36px;
background: #e0e0e0;
border: 2px dashed #b7b7b7;
border-radius: 20px;
}
.add-button-text {
color: white;
font-size: 20px;
font-weight: bold;
}
.pair-button {
width: 100%;
height: 36px;
background: #858dd6;
border: 0;
border-radius: 20px;
}
.not-pair-button {
width: 100%;
height: 36px;
background: #858dd6;
border: 1px #ffffff dashed;
border-radius: 20px;
}
.pair-button-text {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-size: 18px;
line-height: 24px;
text-align: center;
color: #ffffff;
}
</style>
@@ -1,6 +1,6 @@
<template>
<div class="markup-tables project-table flex d-flex sm12 xl12 md12 xs12" id="scro" style="height: 66vh; overflow: auto;">
<div class="table-wrapper">
<div class="markup-tables project-table flex d-flex sm12 xl12 md12 xs12 px-0 mx-0" id="scro" style="width: 100%; height: 55vh; overflow: auto;">
<div class="table-wrapper" style="width: 100%;">
<table class="va-table">
<thead>
<tr>
@@ -21,9 +21,57 @@
</tr>
</thead>
<!-- <tbody> -->
<vuedraggable class="draggable" v-model="getSelectProject.task" @start="() => {}" @end="() => {}" tag="tbody" animation="500">
<vuedraggable :disabled="lockMode === true" class="draggable" :list="getSelectProject.task" @end="rearrangeTask({ project: getSelectProject })" tag="tbody" animation="500">
<template class="item" v-for="(task, taskIndex) in getSelectProject.task">
<tr v-if="task.device && task.device.length === 0" :key="taskIndex" height="80px">
<tr v-if="task.type === 'cycle'" :key="'empty' + taskIndex" height="80px" @click="showCycleModal(task.uuid)">
<td v-if="lockMode === false">
<va-checkbox
v-model="tableColumn.checked"
:array-value="String(taskIndex)"
/>
</td>
<td align="center">
{{ taskIndex + 1 }}
</td>
<td align="center" @dblclick="switchInput('name', taskIndex)">
<div v-if="tableColumn.name == taskIndex && getCycleInfo(task.uuid, 'useID') === true && lockMode === true">
<va-input
v-model="inputSaved"
style="width: 100px;"
@blur="switchCycle('name', -1, getSelectProject, task)"
@keyup.enter="switchCycle('name', -1, getSelectProject, task)"
/>
</div>
<div v-else>
<div v-if="getCycleInfo(task.uuid, 'useID') === true">
{{ getCycleInfo(task.uuid, 'id') }}
</div>
<div v-if="getCycleInfo(task.uuid, 'useID') === false">
{{ getCycleInfo(task.uuid, 'name') }}
</div>
</div>
</td>
<td align="center" v-if="getCycleLocation(task.uuid) === 'start'">
{{ getCycleInfo(task.uuid, 'max') }} Rounds
</td>
<td v-if="lockMode === true && getCycleLocation(task.uuid) === 'start'">
{{ getCycleInfo(task.uuid, 'count') }} / {{ getCycleInfo(task.uuid, 'max') }}
</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
v-if="task.status === 1"
:animation-duration="3000"
:color="'#6c7fee'"
:size="16"
></fulfilling-bouncing-circle-spinner>
<!-- <va-icon v-if="task.status === 2" class="fa fa-check"></va-icon> -->
</td>
</tr>
<tr v-else-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"
@@ -37,19 +85,19 @@
{{ task.name }}
</td>
<td align="center">
<va-button :flat="true" @click="openConfig(1, taskIndex)" small>Add Device</va-button>
<va-button :flat="true" @click="openConfig(1, taskIndex)" small>+ Device</va-button>
</td>
<td align="center">
<va-button :flat="true" @click="openConfig(3, taskIndex)" small>+ New Action/Condition</va-button>
<va-button :flat="true" @click="openConfig(3, taskIndex)" :disabled="true" small>-</va-button>
</td>
<td align="center">
<va-button :flat="true" @click="openConfig(4, taskIndex)" small>Add Parameter</va-button>
<va-button :flat="true" @click="openConfig(4, taskIndex)" :disabled="true" small>-</va-button>
</td>
<td align="center">
<va-icon class="fa fa-close" @click.native="() => deleteTask({ index: taskIndex})"></va-icon>
<va-icon class="fa fa-close" @click.native="() => deleteTask({ project: getSelectProject, index: taskIndex})"></va-icon>
</td>
</tr>
<tr v-else 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="String(taskIndex) + ' ' + String(deviceUUID)" height="80px" @click="() => { focus = taskIndex }">
<td v-if="lockMode === false">
<va-checkbox
v-model="tableColumn.checked"
@@ -69,9 +117,6 @@
/>
</div>
<div v-else>
<!-- <vuedraggable class="draggable">
{{ task.name }}
</vuedraggable> -->
{{ task.name }}
</div>
</td>
@@ -79,12 +124,12 @@
<td align="center">
<div v-if="task.device && task.device.length === 0">
<va-button :flat="true" @click="openConfig(1, taskIndex, deviceUUID)" small>
Add device
+ Device
</va-button>
</div>
<div v-else>
<va-button :flat="true" @click="openConfig(1, taskIndex, deviceUUID)" small>
<span>{{ getDeviceProject(deviceUUID) && getDeviceProject(deviceUUID).name }}</span>
<span>{{ getDeviceShowNameProject(deviceUUID)}}</span>
</va-button>
</div>
</td>
@@ -93,18 +138,18 @@
<td align="center">
<div v-if="Object.keys(task.action).length === 0">
<va-button :flat="true" @click="openConfig(3, taskIndex, deviceUUID)" small>
Add event
+ 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">
<div small v-if="action.type !== 'cycle'">
<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="task.condition[conditionKey].type === 'previous_task_done'">
<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>
@@ -112,7 +157,7 @@
</div>
</div>
<va-button :flat="true" @click="openConfig(3, taskIndex, deviceUUID)" small>
+ New Action/Condition
+ Event
</va-button>
</div>
</td>
@@ -120,7 +165,7 @@
<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
+ Parameter
</va-button>
</div>
<va-button :flat="true" @click="openConfig(4, taskIndex, deviceUUID)" v-else class="flex d-flex">
@@ -129,7 +174,7 @@
<div v-for="(parameter, parameterKey) in parameterSet" :key="parameterKey">
<span v-if="parameterKey !== 'target'">
<div small>
{{ parameterName(parameterKey) }} : {{ parameterValue(parameterKey, parameter) }}
{{ parameterName(parameterKey, deviceUUID) }} : {{ parameterValue(parameterKey, parameter, deviceUUID) }}
</div>
</span>
</div>
@@ -140,7 +185,8 @@
<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>
<va-icon class="fa fa-copy ml-1" @click.native="() => copyTask({ project: getSelectProject, index: taskIndex})"></va-icon>
<va-icon class="fa fa-close ml-1" @click.native="() => deleteTask({ project: getSelectProject, 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">
@@ -150,6 +196,9 @@
{{ 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
@@ -166,6 +215,9 @@
<!-- </tbody> -->
</table>
</div>
<div>
<cycle-modal ref="cycle_modal_ref"></cycle-modal>
</div>
</div>
</template>
<script>
@@ -175,12 +227,15 @@ 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'
import CycleModal from '@/components/project/view/menu/components/CycleModal'
export default {
name: 'project-table',
components: {
FulfillingBouncingCircleSpinner,
vuedraggable,
CycleModal,
},
computed: {
config () {
@@ -190,6 +245,9 @@ export default {
...mapGetters('project', [
types.project.getSelect,
types.project.getDevice,
types.project.getCycle,
types.project.getDeviceLibrary,
types.project.getDeviceShowName,
types.task.get,
types.task.getCondition,
types.task.getParameterSet,
@@ -209,29 +267,24 @@ export default {
name: -1,
checked: [],
},
inputSaved: '',
focus: -1,
index: -1,
futureIndex: -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
this.rearrangeTask({ project: this.getSelectProject })
},
swapTask: function (taskIndex, upDown) {
taskIndex = parseInt(taskIndex)
@@ -244,41 +297,48 @@ export default {
this.getSelectProject.task.splice(taskIndex, 1, this.getSelectProject.task[taskIndex + 1])
this.getSelectProject.task.splice(taskIndex + 1, 1, a)
}
this.rearrangeTask({ project: this.getSelectProject })
},
delSelected: function () {
for (const indexSelected of this.tableColumn.checked) {
this.deleteTask({ index: indexSelected })
this.deleteTask({ project: this.getSelectProject, 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
: this.tableColumn[tag] = index
},
switchCycle: function (tag, index, projectID, task) {
this.switchInput(tag, index)
const cycleInfo = this.getCycleProject(task.uuid) // 0: index, 1: location, 2: info
if (this.inputSaved === cycleInfo[2].id) return
cycleInfo[2].id = this.inputSaved
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'set_project_cycle/0',
project: projectID.uuid,
index: cycleInfo[0],
content: { id: this.inputSaved },
}))
},
selectAll: function (selectedArray) {
const totalRange = [...Array(this.getSelectProject.task.length).keys()].map(idx => String(idx))
selectedArray.includes('-1')
@@ -304,30 +364,62 @@ export default {
}
}
},
parameterName (name) {
if (name === 'MODE') {
return 'Mode'
parameterName (name, deviceKey) {
const config = configTable.getConfig(this.getDeviceLibraryProject(deviceKey))
if (config !== undefined && Object.keys(config) !== 0) {
if (name === 'MODE') {
return 'Mode'
}
if (typeof config[name].showName === 'function') {
return config[name].showName()
}
return 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
parameterValue (name, value, deviceKey) {
const config = configTable.getConfig(this.getDeviceLibraryProject(deviceKey))
if (config !== undefined && Object.keys(config) !== 0) {
if (name === 'MODE') {
return config.MODE[value].name
}
if (config[name].type === 'number') {
const scale = config[name].unit[config[name].defaultUnit]
return `${config[name].outputReadabilityData(value, scale)} ${config[name].defaultUnit}`
} else if (config[name].type === 'array') {
return `${config[name].outputReadabilityData(value)}`
} else if (config[name].type === 'none') {
return ''
}
}
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 ''
},
showCycleModal: function (uuid) {
if (!this.lockMode) {
this.$refs.cycle_modal_ref.show()
this.$refs.cycle_modal_ref.setCycleInfo(this.getSelectProject, uuid)
}
},
getCycleInfo: function (uuid, attribute) {
const cycleInfo = this.getCycleProject(uuid) // 0: index, 1: location, 2: info
if (cycleInfo.length === 0) return ''
return cycleInfo[2][attribute]
},
getCycleLocation: function (uuid) {
const cycleInfo = this.getCycleProject(uuid) // 0: index, 1: location, 2: info
return cycleInfo[1]
},
handleMove (e) {
const { index, futureIndex } = e.draggedContext
this.index = index
this.futureIndex = futureIndex
return false // disable sort
},
...mapActions('project', [
types.task.copy,
types.task.delete,
types.task.rearrange,
]),
},
mounted () {
@@ -341,15 +433,12 @@ export default {
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%;
@@ -143,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)
@@ -311,6 +327,12 @@ export default {
},
},
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)
},
@@ -328,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) {
@@ -340,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) {
@@ -623,6 +647,7 @@ export default {
}
await taskInfo.updateTaskInfo(this.$route.params.taskID)
this.GLOBAL.refreshCache()
this.pageMqttSub(taskInfo.getTaskInfo().controllerID)
await this.pageInit()
@@ -647,6 +672,10 @@ export default {
}
clearInterval(this.dataRefreshTimer)
this.pageMqttUnSub(taskInfo.getTaskInfo().controllerID)
for (var interval in this.batteryInterval) {
clearInterval(this.batteryInterval[interval])
}
},
}
@@ -30,14 +30,17 @@
<div v-if="tabValue == 0" >
<div v-if="chartData[chartID].legend.data.length != 0">
<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 xl1 lg1 sm0 xs0 ma-0 pa-0"> -->
<div class="flex ma-0 pa-0">
</div>
<div class="flex xl7 lg7 sm7 xs7 my-0 py-0">
<!-- <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 sm5 xs5 my-0 py-0 mt-2">
<!-- <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>
@@ -102,7 +105,7 @@
</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>
@@ -114,55 +117,6 @@
INVERSE SELECT
</va-button>
</div> -->
<div class="row flex align--left ma-0 pa-0 mt-2">
<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="developerMode === true">
<canvas-chart-filter :chartID="chartID" :filterIndex="0" />
<canvas-chart-filter :chartID="chartID" :filterIndex="1" />
@@ -260,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)
@@ -278,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') {
@@ -293,6 +249,7 @@ export default {
}
})
}
await this.taskContentChartSaveToCache({ controllerID: taskInfo.getTaskInfo().controllerID })
},
xIntervalChange: async function (val) {
if (!isNaN(parseInt(val))) {
@@ -320,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
@@ -337,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
}
})
}
@@ -445,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,6 +1,6 @@
<template>
<div>
<div class="xs12 sm12 lg12 xl12 mr-4" style="text-align: end;">
<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 -->
@@ -60,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'
@@ -88,7 +88,6 @@ export default {
data () {
return {
info: null,
paramTable: paramTable,
rawData: null,
mode_name: '',
xName: '',
@@ -241,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++) {
@@ -417,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>
<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">
<!-- 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="ma-1" style="width: 75px;"
v-show="data !== null && data.cycle > 0"
>
<div class="mt-1" style="width: 75px;" v-show="data !== null && data.cycle > 0">
<va-input
label="cycle no."
v-model="data.cycle"
:options="grid.xUnitOption"
noClear
disabled
/>
</div>
<!-- value (x-axis) -->
<div class="ma-1" style="width: 100px;">
<va-input
label="x-value"
disable="disable"
v-model="grid.xValue"
/>
<!-- 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>
<!-- unit (x-axis) -->
<div class="ma-1" style="width: 75px;">
<va-select
label="x-unit"
v-model="grid.xUnit"
:options="grid.xUnitOption"
noClear
/>
<!-- 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>
<!-- value (y-axis) -->
<div class="ma-1" style="width: 100px;">
<va-input
label="y-value"
disable="disable"
v-model="grid.yValue"
/>
</div>
<!-- unit (y-axis) -->
<div class="ma-1" style="width: 75px;">
<va-select
label="y-unit"
v-model="grid.yUnit"
:options="grid.yUnitOption"
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,110 +121,121 @@ 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)
// add device mode condition
const device = this.deviceListNew.find(ele => String(ele.memory_board) === String(this.chartData[this.chartID].mappingID))
let mode = -1
if (device !== undefined) mode = device.configuration.MODE
_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 = (typeof _xAxis.default.defaultUnit === 'function') ? _xAxis.default.defaultUnit(mode) : _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 = (typeof _yAxis.default.defaultUnit === 'function') ? _yAxis.default.defaultUnit(mode) : _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) {
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) {
this.data.yAxis[plotIndex].axisLabel.formatter = function (val) {
return parseFloat(val / _yScale).toFixed(3) + _yUnit
}
}
@@ -194,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 = ''
@@ -249,17 +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.updateValue()
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,
@@ -57,20 +57,20 @@ const chartTable = {
mA: 1e6,
A: 1e9,
},
defaultUnit: (Mode) => { return (Mode === 10) ? 'nA' : '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',
},
},
],
@@ -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: (Mode) => { return (Mode === 10) ? 'nA' : '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) => {
@@ -19,11 +19,30 @@
<img :src="device.picture" :alt="device.name">
</va-avatar>
</va-item-section>
<va-item-section class="ml-3" caption>
<va-item-label>
<!-- <va-button @click="getBattery(device)"> get battery </va-button> -->
<!-- <pre> {{ device.battery }} </pre> -->
<va-item-label v-if="device.library_name.includes('EIS')">
{{ `[${device.memory_board}]` }} {{ device.name }}
</va-item-label>
<va-item-label v-else-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.toUpperCase() }}
</va-item-label>
@@ -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 () {
@@ -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,11 +254,18 @@ 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)
}
}
}
},
resetWorkingMode () {
this.workingModeOptions = this.parameterTable.MODE_OPTIONS
this.workingModeSelect = (this.parameter.MODE !== undefined) ? this.workingModeOptions.find(ele => ele.id === this.parameter.MODE) : this.workingModeOptions[0]
console.log(this.workingModeOptions, this.workingModeSelect)
},
getParameter: function (name) {
this.$emit('getParameter', name)
},
@@ -270,6 +283,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 () {
},
@@ -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',
},
],
@@ -2,8 +2,8 @@ export default {
name: 'Potentiostatic Electrochemical Impedance Spectroscopy',
parameter: ['DC_BIAS', 'AC_AMP', 'FREQ', 'PPD', 'SCALE', 'DELAY', 'AVERAGE_NUM', 'RTIA'],
// parameter: ['DC_BIAS', 'AC_AMP', 'FREQ_START', 'FREQ_STOP', 'PPD', 'SCALE', 'DELAY', 'AVERAGE_NUM', 'RTIA'], // 這個mode用到的參數
showParameter: ['DC_BIAS', 'AC_AMP', 'FREQ_START', 'FREQ_STOP', 'PPD', 'SCALE', 'DELAY', 'AVERAGE_NUM', 'RTIA'], // 有要秀給user看的參數
headerParameter: () => ['DC_BIAS', 'AC_AMP', 'FREQ_START', 'FREQ_STOP', 'PPD', 'SCALE', 'DELAY', 'AVERAGE_NUM', 'RTIA'], // 有要秀給user看的參數
showParameter: ['DC_BIAS', 'AC_AMP', 'FREQ', 'PPD', 'SCALE', 'DELAY', 'AVERAGE_NUM', 'RTIA'], // 有要秀給user看的參數
headerParameter: () => ['DC_BIAS', 'AC_AMP', 'FREQ', 'PPD', 'SCALE', 'DELAY', 'AVERAGE_NUM', 'RTIA'], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
@@ -31,7 +31,7 @@ export default {
downloadUnit: 'ms',
},
0: {
name: 'Z_imag_Raw',
name: 'Z_Imag_Raw',
unit: {
ohm: 1,
},
@@ -65,7 +65,7 @@ export default {
// downloadUnit: null,
// },
4: {
name: 'Z_imag',
name: 'Z_Imag',
unit: {
mohm: 1e-3,
: 1e-3,
@@ -80,7 +80,7 @@ export default {
defaultUnit: 'Ω',
},
5: {
name: 'Z_real',
name: 'Z_Real',
unit: {
mohm: 1e-3,
: 1e-3,
+102
View File
@@ -0,0 +1,102 @@
export default {
name: 'R-T Graph',
parameter: ['DAC_VOLT', 'SAMPLE_RATE', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 這個mode用到的參數
showParameter: ['DAC_VOLT', 'SAMPLE_RATE', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 有要秀給user看的參數
headerParameter: () => ['DAC_VOLT', 'SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'TIME_DURATION'], // export header的參數
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: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'Resistor',
unit: {
: 1,
mohm: 1,
Ω: 1e3,
ohm: 1e3,
: 1e6,
kohm: 1e6,
: 1e9,
Mohm: 1e9,
},
defaultUnit: 'Ω',
downloadUnit: 'ohm',
},
},
charts: {
default: [
{
name: 'R-T Graph',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'RT',
x1: {
channel: 'time',
},
y1: {
channel: 2,
},
},
],
},
],
},
],
},
}
+87
View File
@@ -0,0 +1,87 @@
export default {
name: 'V-T Graph',
parameter: ['SAMPLE_RATE', 'MEASURE_VIN_RANGE', 'ADC_LEVEL_I_15', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 這個mode用到的參數
showParameter: ['SAMPLE_RATE', 'MEASURE_VIN_RANGE', 'ADC_LEVEL_I_15', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 有要秀給user看的參數
headerParameter: () => ['SAMPLE_RATE', 'MEASURE_VIN_RANGE', 'ADC_LEVEL_I_15', 'TIME_DURATION'], // export header的參數
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: 'V_in',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
default: [
{
name: 'V-T Graph',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'VT',
x1: {
channel: 'time',
},
y1: {
channel: 1,
},
},
],
},
],
},
],
},
}
+113 -36
View File
@@ -2,8 +2,48 @@ import PotentiostaticEIS from './PotentiostaticEIS'
import CyclicVoltammetry from './CyclicVoltammetry'
import DevMode from './DevMode'
import Chronoamperometry from './Chronoamperometry'
import VT from './VT'
import RT from './RT'
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
},
defaultValue: 25000,
defaultUnit: 'V',
downloadUnit: 'mV',
unit: {
mV: 1,
V: 1e3,
},
},
DAC_VOLT: {
type: 'number',
showName: 'Volt out',
componentType: 'input-range',
range: Object.freeze({ min: 2500, max: 50000 }),
defaultValue: 37500,
defaultUnit: 'V',
downloadUnit: 'mV',
unit: {
mV: 1,
V: 1e3,
},
outputRawData: (val, scale = 1) => {
return parseInt(parseFloat(val) * scale * 12.5 + 25000)
},
outputReadabilityData: (val, scale = 1) => {
return parseInt((parseFloat(val) - 25000) / 12.5) / scale
},
},
ADC_VALUE_I: {
type: 'none',
showName: 'Instruction',
@@ -20,6 +60,7 @@ const EliteEIS = {
outputReadabilityData: (val, scale = 1) => {
return Math.round(parseInt(val - 25000) / 12.5) / scale
},
defaultValue: 25000,
defaultUnit: 'mV',
downloadUnit: 'mV',
unit: {
@@ -38,6 +79,7 @@ const EliteEIS = {
outputReadabilityData: (val, scale = 1) => {
return Math.round(parseInt(val) / 2047 * 800) / scale
},
defaultValue: 25,
defaultUnit: 'mV',
downloadUnit: 'mV',
unit: {
@@ -50,43 +92,12 @@ 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)
},
defaultUnit: 'Hz',
downloadUnit: 'Hz',
unit: {
Hz: 1,
},
},
FREQ_START: {
type: 'number',
showName: 'Freq max',
range: Object.freeze({ min: 0.015, max: 200000 }),
outputRawData: (val) => {
return parseFloat(val) < 0.1 ? 1 : Math.round(parseFloat(val) / 0.0149)
},
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)
},
defaultUnit: 'Hz',
downloadUnit: 'Hz',
unit: {
Hz: 1,
},
},
FREQ_STOP: {
type: 'number',
showName: 'Freq min',
range: Object.freeze({ min: 0.015, max: 200000 }),
outputRawData: (val) => {
return parseFloat(val) < 0.1 ? 1 : Math.round(parseFloat(val) / 0.0149)
},
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)
},
defaultValue: [13333333, 7],
defaultUnit: 'Hz',
downloadUnit: 'Hz',
unit: {
@@ -104,6 +115,7 @@ const EliteEIS = {
outputReadabilityData: (val) => {
return parseInt(val)
},
defaultValue: 10,
defaultUnit: 'points',
downloadUnit: null,
unit: {
@@ -119,6 +131,7 @@ const EliteEIS = {
{ value: 1, label: 'Linear' },
],
range: ['Logarithm', 'Linear'],
defaultValue: 0,
outputRawData: (val) => {
const scaleArr = ['Logarithm', 'Linear']
return scaleArr.indexOf(val.toString())
@@ -132,13 +145,14 @@ const EliteEIS = {
type: 'number',
showName: 'DELAY',
componentType: 'input-field',
range: Object.freeze({ min: 1, max: 100 }),
range: Object.freeze({ min: 0, max: 100 }),
outputRawData: (val) => {
return parseInt(parseFloat(val) * 10)
},
outputReadabilityData: (val) => {
return parseFloat((val / 10)).toFixed(1)
},
defaultValue: 0,
defaultUnit: 'points',
downloadUnit: null,
unit: {
@@ -156,6 +170,7 @@ const EliteEIS = {
{ value: 3, label: '8' },
],
range: ['2', '4', '6', '8'],
defaultValue: 3,
outputRawData: (val) => {
const numArr = ['2', '4', '6', '8']
return numArr.indexOf(val.toString())
@@ -177,6 +192,7 @@ const EliteEIS = {
{ value: 4, label: 'Auto' },
],
range: ['1', '2', '3', '4', 'Auto'],
defaultValue: 4,
outputRawData: (val) => {
const numArr = ['1', '2', '3', '4', 'Auto']
return numArr.indexOf(val.toString())
@@ -198,6 +214,7 @@ const EliteEIS = {
{ value: 4, label: 'Auto' },
],
range: ['<1.5 uA', '1-60 uA', '40-175 uA', '>120 uA', 'Auto'],
defaultValue: 4,
outputRawData: (val) => {
const currentRangeArr = ['<1.5 uA', '1-60 uA', '40-175 uA', '>120 uA', 'Auto']
return currentRangeArr.indexOf(val.toString())
@@ -218,6 +235,7 @@ const EliteEIS = {
{ value: 3, label: 'Auto' },
],
range: ['1', '2', '3', 'Auto'],
defaultValue: 3,
outputRawData: (val) => {
const voltageInRangeArr = ['1', '2', '3', 'Auto']
return voltageInRangeArr.indexOf(val.toString())
@@ -227,6 +245,48 @@ const EliteEIS = {
return voltageInRangeArr[parseInt(idx)]
},
},
MEASURE_VIN_RANGE: {
type: 'array',
showName: 'Vin Range',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: '0~2V' },
{ value: 1, label: '-1~1V' },
{ value: 2, label: '-2~0V' },
{ value: 3, label: 'Auto' },
],
range: ['1', '2', '3', 'Auto'],
defaultValue: 0,
outputRawData: (val) => {
const voltageInRangeArr = ['1', '2', '3', 'Auto']
return voltageInRangeArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const voltageInRangeArr = ['1', '2', '3', 'Auto']
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',
@@ -236,6 +296,7 @@ const EliteEIS = {
{ value: 1, label: 'Off' },
],
range: ['On', 'Off'],
defaultValue: 1,
outputRawData: (val) => {
const highzArr = ['On', 'Off']
return highzArr.indexOf(val.toString())
@@ -256,6 +317,7 @@ const EliteEIS = {
outputReadabilityData: (val, scale = 1) => {
return parseInt((parseFloat(val) - 25000) / 12.5) / scale
},
defaultValue: 25000,
defaultUnit: 'V',
downloadUnit: 'mV',
unit: {
@@ -274,6 +336,7 @@ const EliteEIS = {
outputReadabilityData: (val, scale = 1) => {
return parseInt((parseFloat(val) - 25000) / 12.5) / scale
},
defaultValue: 25000,
defaultUnit: 'V',
downloadUnit: 'mV',
unit: {
@@ -292,6 +355,7 @@ const EliteEIS = {
outputReadabilityData: (val, scale = 1) => {
return parseInt((parseFloat(val) - 25000) / 12.5) / scale
},
defaultValue: 25000,
defaultUnit: 'V',
downloadUnit: 'mV',
unit: {
@@ -310,6 +374,7 @@ const EliteEIS = {
outputReadabilityData: (val) => {
return parseFloat(val) / 100
},
defaultValue: 10000,
defaultUnit: 'mV/s',
downloadUnit: 'mV/s',
unit: {
@@ -327,6 +392,7 @@ const EliteEIS = {
outputReadabilityData: (val, scale = 1) => {
return parseFloat(val) / 10
},
defaultValue: 1000,
defaultUnit: 'sps',
downloadUnit: 'sps',
unit: {
@@ -344,6 +410,7 @@ const EliteEIS = {
outputReadabilityData: (val) => {
return parseInt(val)
},
defaultValue: 1,
defaultUnit: 'cycle',
downloadUnit: null,
unit: {
@@ -366,6 +433,14 @@ const EliteEIS = {
},
{
id: 3,
description: 'VT',
},
{
id: 4,
description: 'RT',
},
{
id: 5,
description: 'Dev Tools',
},
],
@@ -373,7 +448,9 @@ const EliteEIS = {
0: PotentiostaticEIS,
1: CyclicVoltammetry,
2: Chronoamperometry,
3: DevMode,
3: VT,
4: RT,
5: DevMode,
},
}
+12 -1
View File
@@ -1,14 +1,17 @@
import EliteEDC from './EliteEDC/index'
import EliteEIS from './EliteEIS/index'
import store from '@/store/index'
// object saving library name mapping table
const libraryNameMappingTable = {
EDC: EliteEDC,
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,
EIS: EliteEIS,
'Elite_EIS_1.0': EliteEIS,
'Elite_EIS_1.1': EliteEIS,
'Elite_EIS_MINI_1.0': EliteEIS,
@@ -53,11 +56,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]
+29 -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,9 @@ 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]
settings[4] = ['Time', 2, 'Elite', 3]
return settings[mode]
} else if (lib === 'Elite_TRI') {
// const settings = {}
@@ -141,6 +146,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 +182,5 @@ export default
ChannelMaxNumber,
getUUID,
objectFilter,
refreshCache,
}
+10 -9
View File
@@ -1,4 +1,4 @@
import { tableRouter } from '@/components/analysis/replay/toolbox/EliteReplayTable'
import configRouter from '@/components/analysis/replay/toolbox/configTable'
function getTime (val) {
let label = ''
@@ -44,9 +44,10 @@ function newTooltip (controlPanel) {
let value // value on cursor
const param = params[0]// find coressonding parameter to the channel
const style = 'color: ' + param.color
const [xTable, yTable] = tableRouter.getTable(controlPanel.x.type, controlPanel.x.funct, controlPanel.y.type, controlPanel.y.funct) // unit is store in this object
const xScale = configRouter.getUnitScale(controlPanel.x.axis.description)
const yScale = configRouter.getUnitScale(controlPanel.y.axis.description)
// (Default) Time
if (controlPanel.x.type === 'Time') {
if (controlPanel.x.axis.description === 'Time') {
value = getTime(parseFloat(param.value[0]))
} else {
value = getTime(parseFloat(param.value[2]))
@@ -54,13 +55,13 @@ function newTooltip (controlPanel) {
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.type !== 'Time') {
value = parseFloat(param.value[0] / xTable.option[controlPanel.x.unit]).toFixed(3) + ' ' + controlPanel.x.unit
tip += '<li>' + xTable.name + ' = ' + value + '</li>'
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.type !== 'Time') {
value = parseFloat(param.value[1] / yTable.option[controlPanel.y.unit]).toFixed(3) + ' ' + controlPanel.y.unit
tip += '<li>' + yTable.name + ' = ' + 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>'
+2 -2
View File
@@ -62,11 +62,11 @@ function newTooltip (realTime, dataMode) {
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 -2
View File
@@ -1,8 +1,9 @@
function newActionTemplate () {
return [
'start',
// 'start',
'stop',
'cycle',
// 'cycle',
'idle',
]
}
+42 -26
View File
@@ -45,25 +45,25 @@ function newConditionTemplate (action) {
// },
},
stop: {
absolute_time: {
select: false,
type: 'datetime-local',
prefix: 'At',
suffix: '',
value: '',
},
after_project_run: {
select: false,
type: 'text',
prefix: 'After project run',
suffix: 'secs',
value: '',
},
// absolute_time: {
// select: false,
// type: 'datetime-local',
// prefix: 'At',
// suffix: '',
// value: '',
// },
// after_project_run: {
// select: false,
// type: 'text',
// prefix: 'After project run',
// suffix: 'secs',
// value: '',
// },
after_task_run: {
select: false,
select: true,
type: 'text',
prefix: 'After task run',
suffix: 'secs',
prefix: 'when task run for',
suffix: 'seconds',
value: '',
},
// task: {
@@ -88,20 +88,36 @@ function newConditionTemplate (action) {
// value: '',
// },
},
cycle: {
cycle_next: {
// 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: 'Cycle next go to:',
suffix: '',
prefix: 'for',
suffix: 'secs',
value: '',
},
cycle: {
until_button_trigger: {
select: false,
type: 'text',
prefix: 'Run',
suffix: 'times',
value: '0',
type: 'hidden',
prefix: 'until button press',
suffix: '',
value: '',
},
},
}
+5 -4
View File
@@ -1,10 +1,11 @@
function newDevice (uuid = '', name = '', product = 0, library = 0, connectDevice = {}) {
function newDevice (order = -1, name = '', library = '', device = null) {
return {
order: order,
name: name,
product: product,
library: library,
uuid: uuid,
connectDevice: connectDevice,
pair: device,
pairStatus: -1,
locked: false,
isSelect: [],
}
}
@@ -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,
+2 -1
View File
@@ -3,10 +3,11 @@ function newProject (name, uuid) {
name: name,
desc: '',
task: [],
device: [],
device: {},
uuid: uuid,
select: false,
status: -1,
cycle: [],
}
}
+2 -2
View File
@@ -1,9 +1,9 @@
function newTask (name, uuid) {
function newTask (name, uuid, type = '') {
return {
id: -1,
name: name,
next: [],
type: '',
type: type,
desc: '',
device: [],
action: {},
@@ -1,5 +1,5 @@
import types from '@/store/modules/analysis/replay/types'
import { tableRouter } from '@/components/analysis/replay/toolbox/EliteReplayTable'
import configRouter from '@/components/analysis/replay/toolbox/configTable'
const typePath = types.chart
@@ -91,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
@@ -166,33 +190,20 @@ const chartMutations = {
// return label
// }
// }
// tang: try here
[typePath.updateAxisLabel]: (state, payload) => {
let axisLabel
let unitScale
const unit = state.controlPanel[payload.axis].unit
const [xTable, yTable] = tableRouter.getTable(state.controlPanel.x.type, state.controlPanel.x.funct, state.controlPanel.y.type, state.controlPanel.y.funct)
if (payload.axis === 'x') {
axisLabel = state.chartData[payload.chartID].xAxis[payload.axisIndex].axisLabel
unitScale = xTable.option[unit]
} else {
axisLabel = state.chartData[payload.chartID].yAxis[payload.axisIndex].axisLabel
unitScale = yTable.option[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 = tableRouter.autoTimeFormatter
_axisLabel.formatter = autoTimeFormatter
} else {
_axisLabel.formatter = function (val) {
const label = (val / unitScale).toFixed(3) + unit
const label = (val / unitScale[unit]).toFixed(3) + unit
return label
}
}
if (payload.axis === 'x') {
state.chartData[payload.chartID].xAxis[payload.axisIndex].axisLabel = _axisLabel
} else {
state.chartData[payload.chartID].yAxis[payload.axisIndex].axisLabel = _axisLabel
}
state.chartData[payload.chartID][payload.axis + 'Axis'][payload.axisIndex].axisLabel = _axisLabel
},
/**
+3 -4
View File
@@ -37,17 +37,16 @@ function newState () {
isLockDataZoom: false,
controlPanel: {
x: {
type: null,
channel: null,
axis: null,
unit: null,
funct: null,
},
y: {
type: null,
channel: null,
axis: null,
unit: null,
funct: null,
},
FSM: {},
},
}
}
+131 -17
View File
@@ -1,6 +1,8 @@
import types from '@/store/modules/project/types'
import newProject from '@/factories/project/projectFactory'
import newDevice from '@/factories/project/deviceFactory'
import { v4 as uuidv4 } from 'uuid'
import Vue from 'vue'
const typePath = types.project
@@ -26,6 +28,14 @@ const projectActs = {
* @param {}
*/
[typePath.init]: async ({ state, getters, commit }, payload) => {
state.projectSelectIndex = -1
state.taskSelectKey = ''
state.deviceSelectKey = ''
state.lockMode = false
state.taskViewPanel = {
show: false,
type: '',
}
},
/**
* create project
@@ -72,7 +82,6 @@ const projectActs = {
} else {
state.projectLibrary = state.projectList[payload.index].device[0]?.library
}
// state.projectLibrary = state.projectList[payload.index].device[0]?.library.value
},
/**
@@ -89,22 +98,52 @@ const projectActs = {
return true
},
/**
* delete device
*
* @param {number} deviceIndex
*/
[typePath.copy]: async ({ state, getters, commit }, payload) => {
const { project, api } = payload
const copyProject = JSON.parse(JSON.stringify(project))
copyProject.name += ' copy'
copyProject.uuid = uuidv4()
// create project need to remove
delete copyProject.id
const response = await api.project.create(copyProject)
copyProject.id = response.data.id
state.projectList.push(copyProject)
},
/**
* register device
*
* @param {object} device
*/
[typePath.addDevice]: async ({ state, getters, commit }, payload) => {
const { device } = payload
// 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)
[typePath.appendDevice]: async ({ state, getters, commit }, payload) => {
const { key, device } = payload
Vue.set(getters.getSelectProject.device, key, device)
return true
},
/**
* create device
*
* @param {object} device
*/
[typePath.createDevice]: async ({ state, getters, commit, dispatch }, payload) => {
const { name, library, pair, pairStatus, order } = payload
const uuid = uuidv4()
const device = newDevice()
device.name = name
device.library = library
device.pair = pair
device.order = order
if (pairStatus) device.pairStatus = pairStatus
await dispatch(typePath.appendDevice, { key: uuid, device: device })
return true
},
/**
@@ -127,20 +166,95 @@ const projectActs = {
[typePath.setDevice]: async ({ state, getters, commit }, payload) => {
const { device, index } = payload
const deviceList = getters.getSelectProject.device
deviceList[index] = device
if (index) {
deviceList[index] = device
return true
}
deviceList.push(device)
return true
},
/**
* delete device
*
* @param {number} deviceIndex
* @param {string} deviceKey
* @param {string} macAddress
*/
[typePath.deleteDevice]: async ({ state, getters, commit }, payload) => {
const { deviceIndex } = payload
getters.getSelectProject.device.splice(deviceIndex, 1)
[typePath.deleteDevice]: async ({ state, getters, commit, dispatch }, payload) => {
const { deviceKey } = payload
// delete project register device
if (deviceKey) {
Vue.delete(getters.getSelectProject.device, deviceKey)
}
// delete task device
await dispatch('deleteDeviceTask', { deviceKey: deviceKey })
return true
},
/**
* find devices that is connected but not register in project
*
* @param {string} library
*/
[typePath.checkNotRegisterDevice]: async ({ state, getters, commit }, payload) => {
const library = payload.library
const deviceList = []
const connectedDevices = state.deviceConnectList
const registeredDevices = getters.getSelectProject?.device
// if there is not connect device then return
if (connectedDevices.length === 0) return deviceList
// if there is registered device, need to remove cause duplicate device
if (registeredDevices) {
for (const device of connectedDevices) {
if (Object.values(registeredDevices).findIndex(ele => {
return ele.pair === device.mac_address
}) === -1) {
// if no metion which library
if (library === undefined) {
deviceList.push({ macAddress: device.mac_address, library: device.library_name })
}
// if library is assign then need to be same library
if (library && device.library_name.includes(library)) {
deviceList.push({ macAddress: device.mac_address, library: device.library_name })
}
}
}
}
return deviceList
},
/**
* find devices that is register in project but not connected
*
* @param {number} deviceIndex
*/
[typePath.checkPairDeviceExist]: async ({ state, getters, commit, dispatch }, payload) => {
const deviceList = getters.getSelectProject.device
// check project each device is connected(exist) or not
for (const device in deviceList) {
const _device = deviceList[device]
_device.pairStatus = 0
let deviceExist = false
for (const connectDevice of state.deviceConnectList) {
if (deviceList[device].pair === connectDevice.mac_address) {
_device.pairStatus = 1
deviceExist = true
}
}
// if not exist then check if there is connected device is idle and not register in project
if (deviceExist === false) {
const passDevice = await dispatch(typePath.checkNotRegisterDevice, { library: deviceList[device].library })
if (passDevice.length > 0) {
_device.pairStatus = 1
deviceList[device].pair = passDevice[0].macAddress
}
if (passDevice.length === 0) {
_device.pairStatus = 0
}
}
}
},
}
export default projectActs
+185 -22
View File
@@ -1,6 +1,8 @@
import types from '@/store/modules/project/types'
import newTask from '@/factories/project/taskFactory'
import { v4 as uuidv4 } from 'uuid'
import global from '@/data/global/global.js'
import Vue from 'vue'
const typePath = types.task
@@ -17,33 +19,147 @@ const taskActs = {
*
* @param {}
*/
[typePath.create]: async ({ state, getters, commit }, payload) => {
[typePath.create]: async ({ state, getters, commit, dispatch }, payload) => {
const selectProject = getters.getSelectProject
const name = `task${(selectProject.task.length + 1)}`
const uuid = uuidv4()
const task = newTask(name, uuid)
const prevTask = getters.getTask(selectProject.task.length - 1)
prevTask && prevTask.next.push(uuid)
// check device needs to add auto
if (Object.keys(getters.getSelectProject.device).length === 1) {
task.device.push(Object.keys(getters.getSelectProject.device)[0])
}
selectProject.task.push(task)
dispatch(typePath.insert, { project: selectProject, task: task, index: selectProject.task.length })
},
/**
* select task
*
* @param {}
*/
[typePath.select]: async ({ state, getters, commit }, payload) => {
[typePath.createCycle]: async ({ state, getters, commit, dispatch }, payload) => {
const { cycleInfo } = payload
const selectProject = getters.getSelectProject
const start = cycleInfo.start.id
const end = cycleInfo.end.id + 1
const max = cycleInfo.cycle
const useID = cycleInfo.useID
const id = cycleInfo.id
const count = 1
const cycleLength = selectProject.cycle.length + 1
const name = 'Loop' + cycleLength
// create start & end task
const taskStartUUID = global.getUUID()
const taskEndUUID = global.getUUID()
const taskStart = newTask(name, taskStartUUID, 'cycle')
const taskEnd = newTask(name, taskEndUUID, 'cycle')
// create action
const fakeStartActionUUID = global.getUUID()
const fakeAction = await dispatch(typePath.createAction, { uuid: fakeStartActionUUID, action: 'cycle', target: null })
// create start condition
const conditionUUID = global.getUUID()
const newCondition = await dispatch(typePath.createCondition, { uuid: conditionUUID, condition: 'previous_task_done', compOp: 'equal', value: '' })
taskStart.condition = Object.assign({}, taskStart.condition, newCondition)
taskEnd.condition = Object.assign({}, taskEnd.condition, newCondition)
// create stop condition
const conditionUUID1 = global.getUUID()
let newCondition1
if (!useID) {
newCondition1 = await dispatch(typePath.createCondition, { uuid: conditionUUID1, condition: 'after_task_run', compOp: 'equal', value: '0' })
} else {
newCondition1 = await dispatch(typePath.createCondition, { uuid: conditionUUID1, condition: 'until_button_trigger', compOp: 'equal', value: '' })
}
taskStart.condition = Object.assign({}, taskStart.condition, newCondition1)
const conditionUUID2 = global.getUUID()
const newCondition2 = await dispatch(typePath.createCondition, { uuid: conditionUUID2, condition: 'after_task_run', compOp: 'equal', value: '0' })
taskEnd.condition = Object.assign({}, taskEnd.condition, newCondition2)
// assign action & condition
fakeAction[fakeStartActionUUID].condition.push(conditionUUID)
fakeAction[fakeStartActionUUID].condition.push(conditionUUID1)
fakeAction[fakeStartActionUUID].condition.push(conditionUUID2)
taskStart.action = Object.assign({}, taskStart.action, fakeAction)
taskEnd.action = Object.assign({}, taskEnd.action, fakeAction)
taskStart.next.push(await dispatch(typePath.get, { project: selectProject, index: start, attribute: 'uuid' }))
await dispatch(typePath.insert, { project: selectProject, task: taskEnd, index: end })
await dispatch(typePath.insert, { project: selectProject, task: taskStart, index: start })
await dispatch(typePath.rearrange, { project: selectProject })
selectProject.cycle.push({
id: id,
name: name,
range: [taskStartUUID, taskEndUUID],
max: max,
count: count,
useID: useID,
})
},
/**
* save task
*
* @param {}
*/
[typePath.save]: async ({ state, getters, commit }, payload) => {
[typePath.insert]: async ({ state, getters, commit }, payload) => {
const { project, task, index } = payload
project.task.splice(index, 0, task)
if (index !== 0) {
project.task[index - 1].next.length = 0
project.task[index - 1].next.push(task.uuid)
}
if (index !== project.task.length - 1) {
task.next.length = 0
task.next.push(project.task[index + 1].uuid)
}
},
[typePath.copy]: async ({ state, getters, commit, dispatch }, payload) => {
const { project, index } = payload
const copyTask = JSON.parse(JSON.stringify(project.task[index]))
copyTask.name += '-copy'
copyTask.uuid = uuidv4()
project.task.push(copyTask)
await dispatch(typePath.rearrange, { project: project })
},
[typePath.get]: async ({ state, getters, commit }, payload) => {
const { project, index, attribute } = payload
if (attribute) return project.task[index][attribute]
return project.task[index]
},
[typePath.getIndex]: ({ state, getters, commit }, payload) => {
const { project, uuid } = payload
return project.task.findIndex(ele => ele.uuid === uuid)
},
[typePath.swap]: async ({ state, getters, commit, dispatch }, payload) => {
const { project, originIndex, newIndex } = payload
// if swap to higher index insert first then delete
if (originIndex < newIndex) {
const task = project.task[originIndex]
project.task.splice(newIndex, 0, task)
await dispatch(typePath.delete, { project: project, index: originIndex })
}
// if swap to lower index delete first then insert
if (originIndex > newIndex) {
const task = project.task[originIndex]
await dispatch(typePath.delete, { project: project, index: originIndex })
project.task.splice(newIndex, 0, task)
}
await dispatch(typePath.rearrange, { project: project })
return true
},
[typePath.rearrange]: async ({ state, getters, commit, dispatch }, payload) => {
const { project } = payload
project.task = project.task.filter(ele => ele !== undefined)
for (const idx in project.task) {
project.task[idx].next.length = 0
if (Number(idx) === Number(project.task.length - 1)) return
project.task[idx].next.push(project.task[Number(idx) + 1].uuid)
}
},
/**
@@ -51,9 +167,38 @@ const taskActs = {
*
* @param {}
*/
[typePath.delete]: async ({ state, getters, commit }, payload) => {
const selectProject = getters.getSelectProject
selectProject.task.splice(payload.index, 1)
[typePath.delete]: async ({ state, getters, commit, dispatch }, payload) => {
const { project, index } = payload
project.task.splice(index, 1)
await dispatch(typePath.rearrange, { project: project })
},
/**
* delete task
*
* @param {}
*/
[typePath.deleteDevice]: async ({ state, getters, commit, dispatch }, payload) => {
const { deviceKey } = payload
for (const task of getters.getSelectProject.task) {
// delete task device
task.device = task.device.filter(ele => ele !== deviceKey)
// delete task action & condition
for (const [key, value] of Object.entries(task.action)) {
if (value.target === deviceKey) {
for (const condition of value.condition) {
Vue.delete(task.action, condition)
}
Vue.delete(task.action, key)
}
}
// delete task parameter
for (const [key, value] of Object.entries(task.parameter_set)) {
if (value.target === deviceKey) {
Vue.delete(task.parameter_set, key)
}
}
}
},
/**
@@ -83,12 +228,9 @@ const taskActs = {
*/
[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)
},
/**
@@ -113,6 +255,27 @@ const taskActs = {
}
task.parameter_set = Object.assign({}, task.parameter_set)
},
[typePath.createCondition]: async ({ state, getters, commit }, payload) => {
const { uuid, condition, compOp, value } = payload
return {
[uuid]: {
type: condition,
comparsion: compOp,
value: value,
},
}
},
[typePath.createAction]: async ({ state, getters, commit }, payload) => {
const { uuid, action, target } = payload
return {
[uuid]: {
type: action,
target: target,
condition: [],
},
}
},
}
export default taskActs
@@ -16,13 +16,87 @@ const projectGets = {
return state.projectList[state.projectSelectIndex]
},
[typePath.getDevice]: (state) => (deviceKey) => {
return state.projectList[state.projectSelectIndex].device[deviceKey]
[typePath.getDevice]: (state, getters) => (deviceKey) => {
return getters[typePath.getSelect].device[deviceKey]
},
[typePath.getDeviceNum]: (state, getters) => {
return Object.keys(getters[typePath.getSelect].device).length
},
[typePath.getDeviceLibrary]: (state, getters) => (key) => {
return getters[typePath.getSelect].device[key].library
},
[typePath.getDeviceMaxOrder]: (state, getters) => {
const deviceList = getters[typePath.getSelect].device
if (deviceList.length === 0) return 0
let order = 0
for (const device in deviceList) {
order = Math.max(deviceList[device].order, order)
}
order += 1
return order
},
[typePath.getDeviceShowName]: (state, getters) => (key) => {
if (getters[typePath.getSelect].device[key].pair === null) {
return getters[typePath.getSelect].device[key].name
}
return getters[typePath.getSelect].device[key].pair
},
[typePath.getAllDevice]: (state) => {
return state.projectList[state.projectSelectIndex].device
},
[typePath.getCycle]: (state) => (uuid) => {
// 0: index, 1: location, 2: info
let location
const project = state.projectList[state.projectSelectIndex]
// if no input then reject
if (uuid === undefined) return []
const cycleIndex = project.cycle.findIndex(ele => ele.range.find(ele => ele === uuid))
// if find no index then reject
if (cycleIndex === -1) return []
if (project.cycle[cycleIndex].range[0] === uuid) location = 'start'
if (project.cycle[cycleIndex].range[1] === uuid) location = 'end'
return [cycleIndex, location, project.cycle[cycleIndex]]
},
/**
* find devices that is connected but not register in project
*
* @param {string} library
*/
[typePath.getNotRegisterDevice]: (state, getters) => (library) => {
const deviceList = []
const connectedDevices = state.deviceConnectList
const registeredDevices = getters.getSelectProject.device
// if there is not connect device then return
if (connectedDevices.length === 0) return deviceList
// if there is registered device, need to remove cause duplicate device
if (registeredDevices) {
for (const device of connectedDevices) {
if (Object.values(registeredDevices).findIndex(ele => {
return ele.pair === device.mac_address
}) === -1) {
// if no metion which library
if (library === undefined) {
deviceList.push({ name: device.name, macAddress: device.mac_address, library: device.library_name })
}
// if library is assign then need to be same library
if (library && device.library_name.includes(library)) {
deviceList.push({ name: device.name, macAddress: device.mac_address, library: device.library_name })
}
}
}
}
return deviceList
},
}
export default projectGets
+20 -2
View File
@@ -7,24 +7,41 @@ const types = {
delete: 'deleteProject',
save: 'saveProject',
select: 'selectProject',
copy: 'copyProject',
get: 'getProject',
getSelect: 'getSelectProject',
getDevice: 'getDeviceProject',
getCycle: 'getCycleProject',
getAllDevice: 'getAllDeviceProject',
getDeviceNum: 'getDeviceNumProject',
getDeviceShowName: 'getDeviceShowNameProject',
getDeviceLibrary: 'getDeviceLibraryProject',
getDeviceMaxOrder: 'getDeviceMaxOrderProject',
getNotRegisterDevice: 'getNotRegisterDeviceProject',
addDevice: 'addDeviceProject',
appendDevice: 'appendDeviceProject',
createDevice: 'createDeviceProject',
findDevice: 'findDeviceProject',
setDevice: 'setDeviceProject',
checkNotRegisterDevice: 'checkNotRegisterDeviceProject',
checkPairDeviceExist: 'checkPairDeviceExistProject',
deleteDevice: 'deleteDeviceProject',
},
task: {
init: 'initTask',
create: 'createTask',
createCycle: 'createCycleTask',
createAction: 'createActionTask',
createCondition: 'createConditionTask',
insert: 'insertTask',
swap: 'swapTask',
delete: 'deleteTask',
deleteDevice: 'deleteDeviceTask',
rearrange: 'rearrangeTask',
save: 'saveTask',
select: 'selectTask',
copy: 'copyTask',
setCondition: 'setConditionTask',
setAction: 'setActionTask',
@@ -32,6 +49,7 @@ const types = {
setParameterSet: 'setParameterSetTask',
get: 'getTask',
getIndex: 'getIndexTask',
getSelect: 'getSelectTask',
getCondition: 'getConditionTask',
getParameterSet: 'getParameterSetTask',
@@ -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) {
@@ -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:
@@ -432,44 +434,20 @@ const chartActs = {
}
break
case 'EliteEIS':
if (state.chartData[chartID].chartMode === 0) {
// eslint-disable-next-line no-case-declarations
const device = state.deviceListNew.find((ele) => String(ele.memory_board) === String(source.id))
if (device === undefined) break
if (Number(device.configuration.MODE) === 0) {
state.chartData[chartID].series[state.chartData[chartID].series.length - 1].showSymbol = true
state.chartData[chartID].series[state.chartData[chartID].series.length - 1].showAllSymbol = true
}
dataStreamBuffer.register(chartID, source.id, source.channel)
switch (source.channel) {
case 1:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' ZIMAG_RAW')
break
case 2:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' ZREAL_RAW')
break
case 3:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' FREQ')
break
case 4:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' CYCLE')
break
case 5:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' ZIMAG')
break
case 6:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' ZREAL')
break
case 7:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' IMPEDANCE')
break
case 8:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' PHASE')
break
case 9:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' CURRENT')
break
case 10:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' LEVEL_GAIN')
_axisList.push(_axis + ' AXIS = ELITEEIS ' + source.id + ' CHANNEL ' + source.channel)
break
default:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' CHANNEL ' + source.channel)
_axisList.push(_axis + ' AXIS = ELITEEIS ' + source.id + ' CHANNEL ' + source.channel)
break
}
break
@@ -1133,6 +1111,8 @@ function parseGridSourceAxis (gridSourceAxis) {
break
case 'ELITEEIS':
deviceInfo.deviceName = 'EliteEIS'
deviceInfo.deviceID = parseResult[1]
deviceInfo.channel = Number(parseResult[3])
break
default:
break
@@ -1239,87 +1219,38 @@ 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
sourceList.forEach(source => {
let device = ''
let channelName = ''
switch (source.name) {
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
device = deviceList.find((ele) => String(ele.memory_board) === String(source.id))
if (device === undefined) break
// eslint-disable-next-line no-case-declarations
channelName = getConfigChannel(device.library_name, device.configuration.MODE, source.channel - 1)
if (!channelName) break
legendName += 'E' + source.id + '-' + channelName.name[0]
break
case 'EliteEIS':
switch (source.channel) {
case 1:
legendName += 'E' + source.id + '-Zimag_raw'
break
case 2:
legendName += 'E' + source.id + '-Zreal_raw'
break
case 3:
legendName += 'E' + source.id + '-Freq'
break
case 4:
legendName += 'E' + source.id + '-Cycle'
break
case 5:
legendName += 'E' + source.id + '-Zimag'
break
case 6:
legendName += 'E' + source.id + '-Zreal'
break
case 7:
legendName += 'E' + source.id + '-Imped'
break
case 8:
legendName += 'E' + source.id + '-Phase'
break
case 9:
legendName += 'E' + source.id + '-Current'
break
case 10:
legendName += 'E' + source.id + '-Level_gain'
break
default:
legendName += 'E' + source.id + 'CH' + source.channel
break
// eslint-disable-next-line no-case-declarations
device = deviceList.find((ele) => String(ele.memory_board) === String(source.id))
if (device === undefined) break
// eslint-disable-next-line no-case-declarations
channelName = getConfigChannel(device.library_name, device.configuration.MODE, source.channel - 1)
if (!channelName) break
if (device.configuration.MODE === 0) {
legendName += 'E' + source.id + '-' + channelName.name.split('_').join('')
break
}
legendName += 'E' + source.id + '-' + channelName.name[0]
break
default:
legendName += 'D' + source.id + 'CH' + source.channel
@@ -1334,6 +1265,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)