From 2ac112dbbd9d87028652a776f1f8a693f724d251 Mon Sep 17 00:00:00 2001 From: chiayin Date: Tue, 31 Oct 2023 15:29:18 +0800 Subject: [PATCH] Map Attributes: Apply, Clear done. --- .../Discover/Map/Filter/Attributes.vue | 104 +++++++++++-- src/components/Discover/Map/SidebarFilter.vue | 142 +++++++++++++++--- src/stores/allMapData.js | 17 +-- src/views/Files/index.vue | 6 +- 4 files changed, 215 insertions(+), 54 deletions(-) diff --git a/src/components/Discover/Map/Filter/Attributes.vue b/src/components/Discover/Map/Filter/Attributes.vue index 4a9e8e8..258176f 100644 --- a/src/components/Discover/Map/Filter/Attributes.vue +++ b/src/components/Discover/Map/Filter/Attributes.vue @@ -11,7 +11,7 @@

Attribute Name ({{ attTotal }})

- + @@ -32,7 +32,7 @@
- + @@ -241,11 +241,14 @@ export default { } return sliderData; }, - // user select time start and end + // user select value type start and end attValueTypeStartEnd: function() { let start; let end; - switch (this.selectedAttName.type) { + let data; + const type = this.selectedAttName.type; + + switch (type) { case 'date': start = getMoment(this.startTime).format('YYYY-MM-DDTHH:mm:00'); end = getMoment(this.endTime).format('YYYY-MM-DDTHH:mm:00'); @@ -255,18 +258,77 @@ export default { end = this.valueEnd; break; } - // this.selectTimeFrame = [start, end]; // 傳給後端的資料 - // this.$emit('on-row-select', e.data); + data = { // 傳給後端的資料 + type: type, + data: { + key: this.selectedAttName.key, + min: start, + max: end, + } + } + this.$emit('select-attribute', data); return [start, end]; }, }, methods: { /** - * 切換 Attribute Name 或選取類別型 table 的選項 + * 選取類別型 table 的選項 + */ + onRowSelect() { + const type = this.selectedAttName.type; + const data = { + type: type, + data: this.selectedAttRange, + }; + this.$emit('select-attribute', data); + }, + /** + * 取消類別型 table 的選項 + */ + onRowUnselect() { + const type = this.selectedAttName.type; + const data = { + type: type, + data: this.selectedAttRange, + }; + this.$emit('select-attribute', data); + }, + /** + * 選取類別型 table 的全選項 * @param {event} e */ - onRowSelect(e) { + onRowSelectAll(e) { + this.selectedAttRange = e.data; + const type = this.selectedAttName.type; + const data = { + type: type, + data: this.selectedAttRange, + }; + this.$emit('select-attribute', data); + }, + /** + * 取消類別型 table 的全選項 + */ + onRowUnelectAll() { + this.selectedAttRange = null; + const type = this.selectedAttName.type; + const data = { + type: type, + data: this.selectedAttRange, + }; + this.$emit('select-attribute', data) + }, + /** + * 切換 Attribute Name Radio + * @param {event} e + */ + switchAttNameRadio(e) { + this.selectedAttRange = null; + this.startTime = null; + this.endTime = null; + this.valueStart = null; + this.valueEnd = null; if(this.valueData) { // 切換 Attribute Name // 初始化雙向綁定 this.selectArea = [0, this.selectRange]; @@ -304,8 +366,6 @@ export default { this.attValueTypeStartEnd; // 建立圖表 this.createChart(); - } else { // 選取類別型 table 的選項 - // this.$emit('on-row-select', e.data); } }, /** @@ -467,8 +527,8 @@ export default { this.endMinDate = new Date(start); this.startMaxDate = new Date(end); break; - default: - this.valueStart = start; + default: + this.valueStart = start; this.valueEnd = end; // 重新設定 start end 日曆選取範圍 this.valueEndMin = start; @@ -513,9 +573,29 @@ export default { else return; }, }, + created() { + this.$emitter.on('map-filter-reset', value => { + if(value) { + this.selectedAttRange = null; + if(this.valueData && this.valueTypes.includes(this.selectedAttName.type)){ + const min = this.valueData.min; + const max = this.valueData.max; + this.startTime = new Date(min); + this.endTime = new Date(max); + this.valueStart = min; + this.valueEnd = max; + this.selectArea = [0, this.selectRange]; + this.resizeMask(this.chartComplete); + } + } + }); + }, mounted() { // Slider this.selectArea = [0, this.selectRange]; // 初始化滑塊 + }, + beforeUnmount() { + this.selectedAttName = {}; } } diff --git a/src/components/Discover/Map/SidebarFilter.vue b/src/components/Discover/Map/SidebarFilter.vue index ddc9af5..68c3a93 100644 --- a/src/components/Discover/Map/SidebarFilter.vue +++ b/src/components/Discover/Map/SidebarFilter.vue @@ -85,7 +85,7 @@
- + @@ -151,6 +151,8 @@ export default { 6: 'Contained in', }, selectFilterTask: null, + selectAttType: '', + selectAttribute: null, selectFilterStart: null, selectFilterEnd: null, selectFilterStartToEnd: null, @@ -199,6 +201,7 @@ export default { isDisabledButton: function() { let disabled = true; let sele = this.selectValue; + const type = this.selectAttType; switch(sele[0]) { case 'Sequence': // Filter Type 選 Sequence 的行為 @@ -224,6 +227,23 @@ export default { break; } break; + case 'Attributes': // Activity Sequence 選 Attributes 的行為 + switch (type) { + case 'string': + if(this.selectAttribute && this.selectAttribute.length > 0) disabled = false; + break; + case 'boolean': + if(this.selectAttribute?.key && this.selectAttribute?.label) disabled = false; + break; + case 'int': + case 'float': + case 'date': + if(this.selectAttribute?.key && this.selectAttribute?.min && this.selectAttribute?.max) disabled = false; + break; + default: + break; + } + break; case 'Trace': // Filter Type 選 Trace 的行為 disabled = false; break; @@ -315,6 +335,13 @@ export default { list.sort((x, y) => y.occurrences_base - x.occurrences_base) return list; }, + /** + * @param {array} e select Attribute + */ + getSelectAttribute(e){ + this.selectAttType = e.type; + this.selectAttribute = e.data; + }, /** * @param {array} select select Have activity(s) rows */ @@ -396,40 +423,54 @@ export default { switch(e.type){ case "contains-task": - label = `${includeStr}, ${e.task}` - type = "Sequence" - break + label = `${includeStr}, ${e.task}`; + type = "Sequence"; + break; case "starts-with": - label = `${includeStr}, start with ${e.task} ` - type = "Sequence" - break + label = `${includeStr}, start with ${e.task}`; + type = "Sequence"; + break; case "ends-with": - label = `${includeStr}, end with ${e.task} ` - type = "Sequence" - break + label = `${includeStr}, end with ${e.task}`; + type = "Sequence"; + break; case "start-end": - label = `${includeStr}, start with ${e.starts_with}, end with ${e.ends_with}` - type = "Sequence" - break + label = `${includeStr}, start with ${e.starts_with}, end with ${e.ends_with}`; + type = "Sequence"; + break; case "directly-follows": - label = `${includeStr}, directly follows, ${e.task_seq.join(' -> ')}` - type = "Sequence" - break + label = `${includeStr}, directly follows, ${e.task_seq.join(' -> ')}`; + type = "Sequence"; + break; case "eventually-follows": - label = `${includeStr}, eventually follows, ${e.task_seq.join(' -> ')}` - type = "Sequence" - break + label = `${includeStr}, eventually follows, ${e.task_seq.join(' -> ')}`; + type = "Sequence"; + break; + case "trace-freq": + label = `${includeStr}, from #${e.lower} to #${e.upper}`; + type = "Trace"; + break; + case 'string-attr': + label = `${includeStr}, ${e.key}, ${e.value}`; + type = "Attributes"; + break; + case 'boolean-attr': + label = `${includeStr}, ${e.key}, ${this.selectAttribute.label}`; + type = "Attributes"; + break; + case 'int-attr': + case 'float-attr': + case 'date-attr': + label = `${includeStr}, ${e.key}, start with ${e.min}, end with ${e.max}`; + type = "Attributes"; + break; case "occurred-in": case "started-in": case "completed-in": case "occurred-around": label = `${containmentMap[e.type]}, ${includeStr}, from ${getMoment(e.start).format("YYYY-MM-DD HH:mm:ss")} to ${getMoment(e.end).format("YYYY-MM-DD HH:mm:ss")} ` type = "Timeframe" - break - case "trace-freq": - label = `${includeStr}, from #${e.lower} to #${e.upper}` - type = "Trace" - break + break; }; return { type, @@ -451,6 +492,10 @@ export default { this.isStartSelected = null; this.isEndSelected = null; this.isActAllTask = true; + // Attributes + this.selectAttType = ''; + this.selectAttribute = null; + this.$emitter.emit('map-filter-reset', true); // Timeframes this.selectTimeFrame = []; // Trace @@ -520,6 +565,55 @@ export default { break; } break; + case 'Attributes': // Activity Sequence 選 Attributes 的行為 + switch (this.selectAttType) { + case 'string': + data = this.selectAttribute.map(task => { + return { + type: 'string-attr', + key: task.key, + value: task.value, + is_exclude: isExclude, + } + }) + break; + case 'boolean': + data = { + type: 'boolean-attr', + key: this.selectAttribute.key, + value: this.selectAttribute.value, + is_exclude: isExclude, + } + break; + case 'int': + data = { + type: 'int-attr', + key: this.selectAttribute.key, + min: this.selectAttribute.min, + max: this.selectAttribute.max, + is_exclude: isExclude, + } + break + case 'float': + data = { + type: 'float-attr', + key: this.selectAttribute.key, + min: this.selectAttribute.min, + max: this.selectAttribute.max, + is_exclude: isExclude, + } + break + case 'date': + data = { + type: 'date-attr', + key: this.selectAttribute.key, + min: this.selectAttribute.min, + max: this.selectAttribute.max, + is_exclude: isExclude, + } + break + } + break; case 'Trace': // Filter Type 選 Trace 的行為 let lowerIndex = this.$refs.filterTraceView.selectArea[0]; let upperIndex = this.$refs.filterTraceView.selectArea[1]-1; diff --git a/src/stores/allMapData.js b/src/stores/allMapData.js index cdb036c..65fdee6 100644 --- a/src/stores/allMapData.js +++ b/src/stores/allMapData.js @@ -97,22 +97,7 @@ export default defineStore('allMapDataStore', { }, filterAttrs: state => { if(state.allFilterAttrs !== null){ - state.allFilterAttrs.map(att => { - switch (att.type) { - case 'date': - att.min = att.min !== null ? moment(att.min).format('YYYY/MM/DD HH:mm') : null; - att.max = att.max !== null ? moment(att.max).format('YYYY/MM/DD HH:mm') : null; - break; - case 'float': - // Decimal.ROUND_UP|0: 無條件進位; Decimal.ROUND_DOWN|1: 無條件捨去。 - att.min = att.min !== null ? Number(new Decimal(att.min).toFixed(2, 0)) : null; - att.max = att.max !== null ? Number(new Decimal(att.max).toFixed(2, 1)) : null; - break - default: - break; - } - return att; - }); + state.allFilterAttrㄧㄠ return state.allFilterAttrs; } }, diff --git a/src/views/Files/index.vue b/src/views/Files/index.vue index 2539fa3..5cd8a8f 100644 --- a/src/views/Files/index.vue +++ b/src/views/Files/index.vue @@ -143,7 +143,8 @@ fileId = file.id; type = 'log'; params = { type: type, fileId: fileId }; - this.$router.push({name: 'Map', params: params, query: params}); + this.$router.push({name: 'Map', params: params}); + // this.$router.push({name: 'Map', params: params, query: params}); break; case 'Filter': this.createFilterId = file.id; @@ -151,7 +152,8 @@ fileId = file.id; type = 'filter'; params = { type: type, fileId: fileId }; - this.$router.push({name: 'Map', params: params, query: params}); + this.$router.push({name: 'Map', params: params}); + // this.$router.push({name: 'Map', params: params, query: params}); break; default: break;