Compare commits

...

17 Commits

Author SHA1 Message Date
nthu1080112244 302b40bcef [debug] fix cycleIV.js and chartAct.js 2022-07-25 10:12:26 +08:00
nthu1080112244 e89150507c [debug] fix missing mapActions in CanvasChart.vue 2022-07-22 14:59:01 +08:00
nthu1080112244 0bd84d865f [update] integrate axis unit, tooltip information 2022-07-22 09:41:40 +08:00
nthu1080112244 5fe321828a Merge remote-tracking branch 'origin/release/v1.2.5/task_configuration' into dev/real_time_value 2022-07-19 11:30:21 +08:00
peterlu14 ca823d174b [update] reset series data type error fix 2022-07-19 11:26:46 +08:00
nthu1080112244 2e573e2c72 [update] add coment 2022-07-19 11:22:55 +08:00
nthu1080112244 84d136d4cf [update] real time display modularization 2022-07-18 18:28:23 +08:00
nthu1080112244 9b296c45bd [update] complete real time value display 2022-07-18 15:13:16 +08:00
nthu1080112244 ef9db8bee2 Merge commit 'bcf7b51dc6f0c241ab2f8bd3fdffb4173a5e7693' into dev/real_time_value 2022-07-18 14:15:23 +08:00
nthu1080112244 7c4515521d [update] unit correction, real time value bar 2022-07-15 19:40:34 +08:00
peterlu14 bcf7b51dc6 [update] mapping unify format string 2022-07-15 10:05:24 +08:00
peterlu14 ba660ac952 [update] fix girdsource not clear problem 2022-07-14 10:21:39 +08:00
nthu1080112244 7b6948d027 Merge remote-tracking branch 'origin/release/v1.2.5/task_configuration' into dev/real_time_value 2022-07-12 15:15:12 +08:00
nthu1080112244 28f1aef82c [update] default real time representation 2022-07-12 15:14:31 +08:00
peterlu14 d171d8b572 [update] only refresh chart which device running 2022-07-12 10:41:43 +08:00
peterlu14 1e57bde1df [update] chartID uuid && fix mappingID -1 && reset series data && chart created manual or default 2022-07-12 10:38:04 +08:00
peterlu14 0946b01a41 [update] prop chartID add new type 2022-07-12 10:30:36 +08:00
27 changed files with 471 additions and 244 deletions
+44 -13
View File
@@ -108,6 +108,7 @@ import { mapFields } from 'vuex-map-fields'
import { mapActions } from 'vuex'
import taskTypes from '@/store/modules/task/content/types'
import TaskFormula from './formula/TaskFormula'
import { v4 as uuid } from 'uuid'
// TODO change chart data tag format
@@ -207,7 +208,6 @@ export default {
const topicSplit = topic.split('/')
const deviceID = parseInt(topicSplit[3])
const channel = parseInt(topicSplit[4])
dataStreamBuffer.into(String.fromCharCode.apply(null, data), deviceID, (channel + 1))
},
'+/device_save_path/+' (data, topic) {
@@ -261,12 +261,22 @@ export default {
this.showShutdownModal = true
break
case 'start':
// register default chart again
await this.taskContentChartDefaultChartGenerator({
_deviceList: this.deviceListNew,
_itemID: parseInt(mes[1]),
_chartID: null,
_type: 'device',
})
// remove mapping ID chart series data
for (const chart in this.chartData) {
this.taskContentChartResetSeriesData({
chartID: chart,
mappingID: mes[1],
})
}
device = this.deviceListNew.find((ele) => ele.memory_board === parseInt(mes[1]))
device.status = 1
break
@@ -347,12 +357,20 @@ export default {
)
},
refreshData: function () {
// TODO don't need to refresh chart with stop status
for (const chart in this.chartData) {
this.taskContentChartRefreshData({
chartID: parseInt(chart),
deviceList: this.deviceListNew,
})
// find each chart mappingID with device memory_board
const device = this.deviceListNew.find(ele => String(ele.memory_board) === String(this.chartData[chart].mappingID))
// device not found continue
if (device === undefined) {
continue
}
// device is running refresh chart
if (device.status === 1) {
this.taskContentChartRefreshData({
chartID: chart,
deviceList: this.deviceListNew,
})
}
}
},
refreshDevicesWindow: function () {
@@ -362,25 +380,35 @@ export default {
}
},
addChart: async function (isDefault) {
this.taskContentChartAdd({
chartID: this.taskContentChartNumber,
maxDots: 4000,
// create chartID with uuid instead of length of chart list
const newChart = await this.taskContentChartAdd({
chartID: uuid(),
maxDots: 5000,
gridLength: 1,
})
// createby default
if (isDefault === true) {
newChart.createdBy = 'default'
}
// createby manaul
if (isDefault === false) {
newChart.createdBy = 'manual'
}
if (this.$refs.chart_ref != null) {
this.$refs.chart_ref.forEach(ref => {
ref.refreshMappingSelect()
})
}
this.taskContentChartRefreshPanel()
this.taskContentChartNumber++
// save chart config to web storage
if (!isDefault) {
await this.taskContentChartSaveToCache()
}
this.pageToast('The chart has been added.')
return this.taskContentChartNumber - 1
return newChart.chartID
},
refreshChartSetting: async function () {
if (this.$refs.chart_ref != null) {
@@ -462,9 +490,11 @@ export default {
return chart
},
addDevice: async function (deviceID, memoryBoardID) {
// subscribe datastream when add device
this.mqttSub(`${taskInfo.getTaskInfo().controllerID}/data_server/device_data_stream/${deviceID}/+`)
// add mapping chart
await this.addMappingChart(deviceID)
// register default chart
await this.taskContentChartDefaultChartGenerator({
_deviceList: this.deviceListNew,
_itemID: deviceID,
@@ -567,6 +597,7 @@ export default {
taskTypes.chart.add,
taskTypes.chart.defaultChartGenerator,
taskTypes.chart.reset,
taskTypes.chart.resetSeriesData,
taskTypes.chart.refreshData,
taskTypes.chart.refreshChart,
taskTypes.chart.refreshPanel,
@@ -26,6 +26,10 @@
</va-tabs>
<div v-if="tabValue == 0" >
<div v-if="chartData[chartID].legend.data.length != 0">
<canvas-chart-real-time-display
:chartID="chartID"
/>
<!-- chart -->
<chart :key="taskContentChartKey" :ref="'chart_ref'" :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" :options="data" :auto-resize="true"></chart>
</div>
</div>
@@ -108,6 +112,7 @@ import CanvasChartFilterPopup from './CanvasChartFilterPopup.vue'
import CanvasChartSource from './CanvasChartSource'
import { taskInfo } from '../../../../data/task/TaskInfo'
import { mapFields } from 'vuex-map-fields'
import CanvasChartRealTimeDisplay from '@/components/task/content/chart/CanvasChartRealTimeDisplay'
import { mapActions } from 'vuex'
import taskTypes from '@/store/modules/task/content/types'
@@ -118,10 +123,11 @@ export default {
CanvasChartSource,
CanvasChartFilter,
CanvasChartFilterPopup,
CanvasChartRealTimeDisplay,
},
props: {
chartID: {
type: Number,
type: [Number, String],
required: true,
},
cardclass: {
@@ -146,6 +152,7 @@ export default {
...mapFields('taskContent', [
'chartData',
'taskContentChartKey',
'deviceListNew',
]),
},
data () {
@@ -275,7 +282,7 @@ export default {
},
refreshMappingSelect: async function () {
this.setMappingSelect(this.chartData[this.chartID].mappingID)
if (this.chartData[this.chartID].mappingID !== -1 && this.chartData[this.chartID].mappingID != null) {
if (this.chartData[this.chartID].mappingID !== '-1' && this.chartData[this.chartID].mappingID != null) {
taskInfo.getMappingList().forEach(item => {
if (item.id === this.chartData[this.chartID].mappingID) {
this.setChartName(item.name)
@@ -322,7 +329,6 @@ export default {
type: 'legendInverseSelect',
})
},
...mapActions('taskContent', [
taskTypes.chart.saveToCache,
]),
@@ -65,7 +65,7 @@ export default {
name: 'canvas-chart-filter',
props: {
chartID: {
type: Number,
type: [Number, String],
required: true,
},
filterIndex: {
@@ -29,7 +29,7 @@ export default {
},
props: {
chartID: {
type: Number,
type: [Number, String],
required: true,
},
chartRef: {
@@ -66,7 +66,7 @@ export default {
name: 'canvas-chart-filter-individual-filter',
props: {
chartID: {
type: Number,
type: [Number, String],
required: true,
},
seriesIndex: {
@@ -0,0 +1,218 @@
<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">
<div class="col flex xs0 sm0 lg0 md0 xl0 xxl1"/>
<div class="col flex xs2 sm2 lg2 md2 xl2 xxl1" pa-0 ma-0>
<p color="primary" style="text-align: right;">{{ grid.name }}</p>
</div>
<!-- value (y-axis) -->
<div class="col flex sm2 xl2 md2 xs2">
<va-input
label="y-value"
disable="disable"
v-model="grid.yValue"
/>
</div>
<!-- unit (y-axis) -->
<div class="col flex sm2 xl2 md2 xs2">
<va-select
label="y-unit"
v-model="grid.yUnit"
:options="grid.yUnitOption"
noClear
/>
</div>
<div class="col flex sm1 xl1 md1 xs1"></div>
<!-- value (x-axis) -->
<div class="col flex sm2 xl2 md2 xs2">
<va-input
label="x-value"
disable="disable"
v-model="grid.xValue"
/>
</div>
<!-- unit (x-axis) -->
<div class="col flex sm2 xl2 md2 xs2">
<va-select
label="x-unit"
v-model="grid.xUnit"
:options="grid.xUnitOption"
noClear
/>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
import paramTable from '@/data/param-table/index.js'
import newTooltip from '@/factories/chart/tooltipFactory'
export default {
name: 'CanvasChartRealTimeDisplay',
props: {
chartID: {
type: [Number, String],
required: true,
},
},
computed: {
...mapFields('taskContent', [
'chartData',
'deviceListNew',
]),
},
data () {
return {
data: null,
paramTable: paramTable,
realTime: [[]],
}
},
methods: {
// 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++) {
// 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)
}
// 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].xValueScale[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].yValueScale[this.realTime[gridIndex][channelIndex].yUnit]).toFixed(3)
}
}
}
},
// change the axis unit of charts
updateUnit: 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].xValueScale[this.realTime[gridIndex][channelIndex].xUnit]
const _yScale = this.realTime[gridIndex][channelIndex].yValueScale[this.realTime[gridIndex][channelIndex].yUnit]
this.data.xAxis[gridIndex].axisLabel.formatter = function (val) {
return parseFloat(val / _xScale).toFixed(2) + _xUnit
}
this.data.yAxis[gridIndex].axisLabel.formatter = function (val) {
return parseFloat(val / _yScale).toFixed(2) + _yUnit
}
// update tooltip
this.data.tooltip.formatter = newTooltip(this.realTime).formatter
}
}
}
},
// for user to choose wanted unit
setUnit: function (gridIndex, channelIndex) {
// find coressponding device for current chart
const device = this.deviceListNew.find(chart => {
return chart.memory_board === parseInt(this.chartData[this.chartID].mappingID)
})
if (!device) {
return
}
// construct realTime object, i.e., record the coressponding value and unit
// the formate imitates the data.gridSource
const modeTable = this.paramTable[device.library_name].MODE[device.configuration.MODE]
const _realTime = JSON.parse(JSON.stringify(this.realTime))
const _newChannel = {}
let xAxis = null
let yAxis = null
// find the the data of each axis coming from which channel
if (this.data.series.length > 0) {
_newChannel.name = this.data.gridSource[gridIndex][channelIndex].name
_newChannel.seriesSource = this.data.series.findIndex((ele) => ele.name === _newChannel.name)
xAxis = this.data.series[_newChannel.seriesSource].xAxisSource[1] - 1
yAxis = this.data.series[_newChannel.seriesSource].yAxisSource[1] - 1
xAxis = (xAxis === -2) ? 'time' : xAxis
yAxis = (yAxis === -2) ? 'time' : yAxis
}
// check if xAxis unit has been defined in modeTable
if (Object.prototype.hasOwnProperty.call(modeTable.channels, xAxis)) {
_newChannel.xUnit = modeTable.channels[xAxis].defaultUnit
_newChannel.xValueScale = modeTable.channels[xAxis].unit
_newChannel.xUnitOption = Object.keys(modeTable.channels[xAxis].unit)
} else {
_newChannel.xUnit = 'unvalid'
_newChannel.xValueScale = { unvalid: NaN }
_newChannel.xUnitOption = ['']
}
// check if yAxis unit has been defined in modeTable
if (Object.prototype.hasOwnProperty.call(modeTable.channels, yAxis)) {
_newChannel.yUnit = modeTable.channels[yAxis].defaultUnit
_newChannel.yValueScale = modeTable.channels[yAxis].unit
_newChannel.yUnitOption = Object.keys(modeTable.channels[yAxis].unit)
} else {
_newChannel.yUnit = 'unvalid'
_newChannel.yValueScale = { unvalid: NaN }
_newChannel.yUnitOption = ['']
}
// set real time value = 0 as default
_newChannel.xValue = 0
_newChannel.yValue = 0
// padding
while (gridIndex >= _realTime.length) {
_realTime.push([])
}
while (channelIndex >= _realTime[gridIndex].length) {
_realTime[gridIndex].push({})
}
// merge the additional part into original part
_realTime[gridIndex][channelIndex] = _newChannel
this.realTime = _realTime
},
// for each lines on the charts should have its own real time display
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)
}
}
}
}
},
},
mounted () {
this.data = this.chartData[this.chartID]
},
watch: {
data: {
handler: function () {
this.updateValue()
this.matchChart()
},
deep: true,
},
realTime: {
handler: function () {
this.updateUnit()
},
deep: true,
},
},
}
</script>
@@ -30,7 +30,7 @@ export default {
name: 'canvas-chart-setting',
props: {
chartID: {
type: Number,
type: [Number, String],
required: true,
},
},
@@ -95,7 +95,7 @@ export default {
name: 'canvas-chart-source',
props: {
chartID: {
type: Number,
type: [Number, String],
required: true,
},
},
@@ -22,11 +22,10 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
@@ -36,7 +35,7 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
@@ -22,11 +22,10 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
@@ -36,7 +35,7 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
@@ -22,11 +22,10 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
@@ -36,7 +35,7 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
+4 -5
View File
@@ -22,11 +22,10 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
@@ -36,7 +35,7 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
@@ -24,9 +24,8 @@ export default {
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
@@ -36,7 +35,7 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
+4 -5
View File
@@ -27,11 +27,10 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
@@ -41,7 +40,7 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
@@ -22,11 +22,10 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
@@ -36,7 +35,7 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
+4 -5
View File
@@ -22,11 +22,10 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
@@ -36,7 +35,7 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
+4 -5
View File
@@ -22,11 +22,10 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
@@ -36,7 +35,7 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
@@ -22,11 +22,10 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
@@ -36,7 +35,7 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
+4 -5
View File
@@ -22,11 +22,10 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
@@ -36,7 +35,7 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
@@ -38,11 +38,10 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
@@ -52,7 +51,7 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
@@ -62,7 +61,7 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
},
+5 -6
View File
@@ -22,11 +22,10 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
@@ -36,7 +35,7 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
@@ -50,7 +49,7 @@ export default {
downloadUnit: 'mV',
},
2: {
name: 'Resister',
name: 'Resistor',
unit: {
: 1,
mohm: 1,
+4 -5
View File
@@ -22,11 +22,10 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
@@ -36,7 +35,7 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
+2 -2
View File
@@ -58,7 +58,7 @@ export const dataStreamBuffer = {
into: (currentDataByChannel, currentDeviceID, currentChannel) => {
// currentData = [ timeStart, d1, d2..... , timeEnd ]
// const currentData = JSON.parse(currentDataByChannel).binary.split(' ')
// const currentData = JSON.parse(currentDataByChannel).binary.split(' '))
const currentData = currentDataByChannel.split(' ')
// console.log(currentData)
const timeStart = parseInt(currentData[0])
@@ -109,7 +109,7 @@ export const dataStreamBuffer = {
// pop the first batch data from datastream buffer
pop: (chartID, deviceID, channel) => {
if (_dataStreamBuffer[chartID] != null && _dataStreamBuffer[chartID][deviceID] != null &&
_dataStreamBuffer[chartID][deviceID][channel] != null && _dataStreamBuffer[chartID][deviceID][channel].length > 0) {
_dataStreamBuffer[chartID][deviceID][channel] != null && _dataStreamBuffer[chartID][deviceID][channel].length > 0) {
return _dataStreamBuffer[chartID][deviceID][channel].shift()
}
return []
+5 -4
View File
@@ -1,6 +1,6 @@
function newChart (chartID) {
function newChart (chartID, numOfCharts) {
return {
chartID: parseInt(chartID),
chartID: chartID,
chartType: 'detail',
chartDevice: 'elite', // elite or neulive
chartMode: 0,
@@ -8,10 +8,11 @@ function newChart (chartID) {
chartYUnit: '',
chartXMode: 'value', // value or time
chartYMode: 'value', // value or time
cardName: 'chart' + String(chartID),
cardName: 'chart' + String(numOfCharts),
cardHeight: '500px',
cardWidth: 'auto',
mappingID: -1,
mappingID: '-1',
createdBy: '', // manual ror default
run: false,
timer: 0,
legend: {
+58 -85
View File
@@ -23,7 +23,24 @@ function getTime (val) {
return label
}
function newTooltip (chartID) {
function getPhysicsQunatity (name) {
const label = []
name = name.split('_')
for (let i = 0; i < name.length; i++) {
if (name[i].includes('T')) {
label.push('Time')
} else if (name[i].includes('V')) {
label.push('Voltage')
} else if (name[i].includes('I')) {
label.push('Current')
} else if (name[i].includes('R')) {
label.push('Impedance')
}
}
return label
}
function newTooltip (realTime) {
return {
hideDelay: 5000,
trigger: 'axis',
@@ -32,92 +49,48 @@ function newTooltip (chartID) {
borderWidth: 1,
borderRadius: 0,
padding: 10,
// axisPointer: {
// type: 'cross',
// animation: false,
// label: {
// backgroundColor: '#505765',
// },
// },
formatter: function (params) {
if (params.length) {
if (params[0].seriesName.split('_')[0] === 'T' && params[0].seriesName.split('_')[1] !== 'T') {
params.unshift({ seriesName: 'Time', value: [null, getTime(parseFloat(params[0].value[0]))], color: '#5193f2' })
} else if (params[0].seriesName.split('_')[0] !== 'T' && params[0].seriesName.split('_')[1] === 'T') {
params.unshift({ seriesName: 'Time', value: [null, getTime(parseFloat(params[0].value[1]))], color: '#5193f2' })
} else {
params.unshift({ seriesName: 'Time', value: [null, getTime(parseFloat(params[0].value[2]))], color: '#5193f2' })
}
let tip = ''
for (var i = 0; i < params.length; i++) {
const param = params[i]
const style = 'color: ' + param.color
let value
// console.log(param.value)
if (param.seriesName === 'Time') {
value = param.value[1]
} else if (param.seriesName.split('_')[1] === 'T' && param.seriesName.split('_')[0] !== 'T') {
const physicalQuantity = param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1]
if (physicalQuantity === 'V') {
value = parseFloat(param.value[0]).toFixed(3) + ' μV'
} else if (physicalQuantity === 'I') {
value = parseFloat(param.value[0]).toFixed(3) + ' nA'
} else if (physicalQuantity === 'R') {
value = parseFloat(param.value[0]).toFixed(3) + ' mΩ'
} else if (physicalQuantity === 'X' || physicalQuantity === 'Y' || physicalQuantity === 'Z' || physicalQuantity === 'M') {
value = (parseFloat(param.value[0]) / 100).toFixed(3) + ' (g)'
} else if (!isNaN(physicalQuantity)) {
value = (parseFloat(param.value[0]) / 1000).toFixed(3) + ' (mV)'
} else {
value = parseFloat(param.value[0]).toFixed(3)
}
} else if (param.seriesName.split('_')[1] !== 'T' && param.seriesName.split('_')[0] === 'T') {
const physicalQuantity = param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1]
if (physicalQuantity === 'V') {
value = parseFloat(param.value[1]).toFixed(3) + ' μV'
} else if (physicalQuantity === 'I') {
value = parseFloat(param.value[1]).toFixed(3) + ' nA'
} else if (physicalQuantity === 'R') {
value = parseFloat(param.value[1]).toFixed(3) + ' mΩ'
} else if (physicalQuantity === 'X' || physicalQuantity === 'Y' || physicalQuantity === 'Z' || physicalQuantity === 'M') {
value = (parseFloat(param.value[1]) / 100).toFixed(3) + ' (g)'
} else if (!isNaN(physicalQuantity)) {
value = (parseFloat(param.value[1]) / 1000).toFixed(3) + ' (mV)'
} else {
value = parseFloat(param.value[1]).toFixed(3)
}
} else {
let value1
let value2
if (param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1] === 'V') {
value1 = parseFloat(param.value[0]).toFixed(3) + ' μV'
} else if (param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1] === 'I') {
value1 = parseFloat(param.value[0]).toFixed(3) + ' nA'
} else if (param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1] === 'R') {
value1 = parseFloat(param.value[0]).toFixed(3) + ' mΩ'
} else {
value1 = parseFloat(param.value[0]).toFixed(3)
}
if (param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1] === 'V') {
value2 = parseFloat(param.value[1]).toFixed(3) + ' μV'
} else if (param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1] === 'I') {
value2 = parseFloat(param.value[1]).toFixed(3) + ' nA'
} else if (param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1] === 'R') {
value2 = parseFloat(param.value[1]).toFixed(3) + ' mΩ'
} else {
value2 = parseFloat(param.value[1]).toFixed(3)
}
value = value1 + ', ' + value2
}
tip += '<span style="' + style + '">' +
param.seriesName +
'</span><span style="' +
style + '">' + value + '</span><br>'
}
return tip
// params is empty
if (!params.length && realTime.length) return params
// params is unempty
let tip = ''
let param // find coressonding parameter to the channel
let unitTable // unit is store in this object
let physicsQunatity // type is store here
let style // color
let value // value on cursor
const timeIndex = params[0].seriesName.split('_').findIndex(title => title === 'T')
// (Default) Time
if (timeIndex === -1) {
value = getTime(parseFloat(params[0].value[2]))
} else {
value = getTime(parseFloat(params[0].value[timeIndex]))
}
tip += '<span style="color: #5193f2">' + 'Time: ' + value + '</span><br>'
// (Manual) Voltage, Current, Impedance
for (let gridIndex = 0; gridIndex < realTime.length; gridIndex++) {
for (let channelIndex = 0; channelIndex < realTime[gridIndex].length; channelIndex++) {
param = params.find(x => x.seriesName === realTime[gridIndex][channelIndex].name)
if (param === undefined) continue
unitTable = realTime[gridIndex][channelIndex]
style = 'color: ' + param.color
physicsQunatity = getPhysicsQunatity(param.seriesName)
tip += '<span style="' + style + '">' + param.seriesName + ':<ul style = "list-style-type: disc; list-style-position: inside">'
if (physicsQunatity[0] !== 'Time') {
value = parseFloat(param.value[0] / unitTable.xValueScale[unitTable.xUnit]).toFixed(3) + unitTable.xUnit
tip += '<li>' + physicsQunatity[0] + ' = ' + value + '</li>'
}
if (physicsQunatity[1] !== 'Time') {
value = parseFloat(param.value[1] / unitTable.yValueScale[unitTable.yUnit]).toFixed(3) + unitTable.yUnit
tip += '<li>' + physicsQunatity[1] + ' = ' + value + '</li>'
}
tip += '</ul></span>'
}
}
return tip
},
}
}
@@ -20,27 +20,25 @@ const chartActs = {
[typePath.initCustomizedFromCache]: async ({ state, getters, commit, dispatch }, payload) => {
const cacheData = await localforage.getItem('chart_data')
if (cacheData !== null) {
// use ID to create new chart by cache
for (const _chart of Object.values(cacheData)) {
if (_chart.mappingID === -1) { // not default chart
const newChartID = state.taskContentChartNumber
dispatch(typePath.add, {
chartID: newChartID,
maxDots: _chart.maxDots,
gridLength: _chart.grid.length,
})
for (let gridIndex = 0; gridIndex < _chart.grid.length; gridIndex++) {
if (gridIndex in _chart.gridSource) {
dispatch(typePath.registerFromCache, {
chartID: newChartID,
gridIndex: gridIndex,
gridSource: _chart.gridSource[gridIndex],
})
}
dispatch(typePath.add, {
chartID: _chart.chartID,
maxDots: _chart.maxDots,
gridLength: _chart.grid.length,
})
for (let gridIndex = 0; gridIndex < _chart.grid.length; gridIndex++) {
if (gridIndex in _chart.gridSource) {
dispatch(typePath.registerFromCache, {
chartID: _chart.chartID,
gridIndex: gridIndex,
gridSource: _chart.gridSource[gridIndex],
})
}
state.taskContentChartNumber++
dispatch(typePath.refreshPanel)
}
state.chartData[_chart.chartID].createdBy = 'manual'
}
dispatch(typePath.refreshPanel)
}
},
/**
@@ -50,12 +48,10 @@ const chartActs = {
[typePath.saveToCache]: async ({ state, getters, commit, dispatch }, payload) => {
const _chartData = {}
for (const [_id, _chart] of Object.entries(state.chartData)) {
if (_chart.mappingID === -1) { // not default chart
// manual chart clear series data
if (_chart.createdBy === 'manual') {
_chartData[_id] = JSON.parse(JSON.stringify(_chart))
if (_chartData[_id].series.data != null) {
_chartData[_id].series.data.length = 0
}
_chartData[_id].series.length = 0
_chartData[_id].series.map((ele) => { ele.data.length = 0 })
}
}
await localforage.setItem('chart_data', _chartData)
@@ -70,8 +66,8 @@ const chartActs = {
*/
[typePath.add]: ({ state, getters, commit, dispatch }, payload) => {
const { chartID, maxDots, gridLength } = payload
if (state.chartData[parseInt(chartID)] == null) {
state.chartData[parseInt(chartID)] = newChart(chartID)
if (state.chartData[chartID] == null) {
state.chartData[chartID] = newChart(chartID, Object.keys(state.chartData).length)
state.chartData[chartID].maxDots = maxDots
state.chartData[chartID].tooltip = newTooltip()
dispatch(typePath.updateGridList, { chartID: chartID, length: gridLength })
@@ -80,6 +76,7 @@ const chartActs = {
return state.chartData[chartID]
}
},
/**
* register source channel setting from cache
*
@@ -362,7 +359,6 @@ const chartActs = {
return parseFloat(val / 1000).toFixed(2) + 'uA'
}
state.chartData[chartID].chartYUnit = 'uA' // nA * 1000
console.log(state.chartData[chartID])
break
case 2:
state.chartData[chartID].yAxis[_yAxisIndex].axisLabel.formatter = function (val) {
@@ -515,7 +511,14 @@ const chartActs = {
if (!state.chartData[chartID].gridSource[gridIndex].some(el => el.name === _gridSeries.name)) {
state.chartData[chartID].gridSource[gridIndex].push(_gridSeries)
}
// console.log(state.chartData[chartID])
// assign mappingID with device ID
if (deviceIDX >= 0) {
state.chartData[chartID].mappingID = deviceIDX
}
if (deviceIDY >= 0) {
state.chartData[chartID].mappingID = deviceIDY
}
return state.chartData[chartID]
},
/**
@@ -537,7 +540,7 @@ const chartActs = {
* @param {String} chartID
*/
[typePath.refreshData]: ({ state, getters, commit, dispatch }, payload) => {
const { chartID, deviceList } = payload
const { chartID } = payload
if (state.chartData[chartID] == null) {
return false
}
@@ -710,24 +713,12 @@ const chartActs = {
// series data list shift by time
if (series.data.length > 0) {
if (series.xAxisSource[0] === -1) {
if (deviceList.find(ele => ele.memory_board === series.yAxisSource[0]).library_name.includes('Elite')) {
if (series.data.length > state.chartData[chartID].maxDots) {
series.data.splice(0, series.data.length - state.chartData[chartID].maxDots)
}
} else {
if (series.data[series.data.length - 1][0] - series.data[0][0] > 3000000) {
series.data.splice(0, popData.length)
}
if (series.data.length > state.chartData[chartID].maxDots) {
series.data.splice(0, series.data.length - state.chartData[chartID].maxDots)
}
} else if (series.yAxisSource[0] === -1) {
if (deviceList.find(ele => ele.memory_board === series.xAxisSource[0]).library_name.includes('Elite')) {
if (series.data.length > state.chartData[chartID].maxDots) {
series.data.splice(0, series.data.length - state.chartData[chartID].maxDots)
}
} else {
if (series.data[series.data.length - 1][1] - series.data[0][1] > 3000000) {
series.data.splice(0, popData.length)
}
if (series.data.length > state.chartData[chartID].maxDots) {
series.data.splice(0, series.data.length - state.chartData[chartID].maxDots)
}
}
}
@@ -1002,7 +993,7 @@ const chartActs = {
mappingID: state.chartData[_chartID].mappingID,
cardName: state.chartData[_chartID].cardName,
})
state.chartData[_chartID].mappingID = parseInt(item.id)
state.chartData[_chartID].mappingID = item.id
switch (_type) {
case 'device':
_chartRegisterDevice(_chartID, item)
@@ -1016,21 +1007,23 @@ const chartActs = {
let isSetting = false
for (const chartID in state.chartData) {
if (parseInt(state.chartData[chartID].mappingID) === parseInt(item.id)) {
isSetting = true
dispatch(typePath.reset, {
chartID: chartID,
mappingID: state.chartData[chartID].mappingID,
cardName: state.chartData[chartID].cardName,
})
state.chartData[chartID].mappingID = parseInt(item.id)
switch (_type) {
case 'device':
_chartRegisterDevice(chartID, item)
break
case 'formula':
_chartRegisterFormula(chartID, item)
break
if (state.chartData[chartID].mappingID === item.id) {
if (state.chartData[chartID].createdBy === 'default') {
isSetting = true
dispatch(typePath.reset, {
chartID: chartID,
mappingID: state.chartData[chartID].mappingID,
cardName: state.chartData[chartID].cardName,
})
state.chartData[chartID].mappingID = item.id
switch (_type) {
case 'device':
_chartRegisterDevice(chartID, item)
break
case 'formula':
_chartRegisterFormula(chartID, item)
break
}
}
}
}
@@ -1053,12 +1046,13 @@ const chartActs = {
state.chartData[chartID].legend.data.length = 0
state.chartData[chartID].xAxis.length = 0
state.chartData[chartID].yAxis.length = 0
state.chartData[chartID].gridSource.length = 0
if (state.chartData[chartID].series.data != null) {
state.chartData[chartID].series.data.length = 0
}
state.chartData[chartID].series.length = 0
if (mappingID == null) {
state.chartData[chartID].mappingID = -1
state.chartData[chartID].mappingID = '-1'
}
if (cardName == null) {
state.chartData[chartID].cardName = 'chart' + String(chartID)
@@ -1066,6 +1060,22 @@ const chartActs = {
state.chartData[chartID].dataZoom = null
dispatch(typePath.updateGridList, { chartID: chartID, length: 1 })
},
/**
* reset chart option
*
* @param {String} chartID
* @param {String} mappingID
* @param {String} cardName
*/
[typePath.resetSeriesData]: ({ state, getters, commit, dispatch }, payload) => {
const { chartID, mappingID } = payload
if (String(mappingID) === String(state.chartData[chartID].mappingID)) {
for (const i in state.chartData[chartID].series) {
state.chartData[chartID].series[i].data.length = 0
}
}
},
/**
* refresh (key++) EChart
*
@@ -1184,6 +1194,7 @@ function makeYAxis (gridIndex, type, channel) {
// // // verticalAlign: 'bottom',
// // },
gridIndex: gridIndex,
boundarygap: ['0%', '50%'],
axisTick: { show: false },
axisLine: { show: false }, // color: '#ccc' } },
axisLabel: {
@@ -1199,8 +1210,8 @@ function makeYAxis (gridIndex, type, channel) {
// // },
animation: false,
scale: true,
min: 'dataMin',
max: 'dataMax',
// min: 'dataMin',
// max: 'dataMax',
splitNumber: 3,
// minInterval: 1,
interval: null,
+1
View File
@@ -9,6 +9,7 @@ const types = {
updateGridList: 'taskContentChartUpdateGridList',
defaultChartGenerator: 'taskContentChartDefaultChartGenerator',
reset: 'taskContentChartReset',
resetSeriesData: 'taskContentChartResetSeriesData',
refreshData: 'taskContentChartRefreshData',
refreshChart: 'taskContentChartRefreshChart',
refreshPanel: 'taskContentChartRefreshPanel',