Map Attributes: Apply, Clear done.
This commit is contained in:
@@ -11,7 +11,7 @@
|
|||||||
<div class="basis-1/3 bg-neutral-10 border border-neutral-300 rounded-xl px-4 pb-4 w-full h-full relative text-sm">
|
<div class="basis-1/3 bg-neutral-10 border border-neutral-300 rounded-xl px-4 pb-4 w-full h-full relative text-sm">
|
||||||
<p class="h2 my-2">Attribute Name ({{ attTotal }})</p>
|
<p class="h2 my-2">Attribute Name ({{ attTotal }})</p>
|
||||||
<div class="overflow-y-auto overflow-x-auto scrollbar -mx-2 h-[calc(100%_-_56px)]">
|
<div class="overflow-y-auto overflow-x-auto scrollbar -mx-2 h-[calc(100%_-_56px)]">
|
||||||
<DataTable v-model:selection="selectedAttName" :value="filterAttrs" dataKey="key" breakpoint="0" :tableClass="tableClass" @row-select="onRowSelect">
|
<DataTable v-model:selection="selectedAttName" :value="filterAttrs" dataKey="key" breakpoint="0" :tableClass="tableClass" @row-select="switchAttNameRadio">
|
||||||
<Column selectionMode="single" :headerClass="headerModeClass" :bodyClass="bodyModeClass"></Column>
|
<Column selectionMode="single" :headerClass="headerModeClass" :bodyClass="bodyModeClass"></Column>
|
||||||
<Column field="key" header="Attribute" :headerClass="headerClass" :bodyClass="bodyClass" sortable></Column>
|
<Column field="key" header="Attribute" :headerClass="headerClass" :bodyClass="bodyClass" sortable></Column>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- type: string -->
|
<!-- type: string -->
|
||||||
<div v-else-if="selectedAttName.type === 'string'" class="w-full">
|
<div v-else-if="selectedAttName.type === 'string'" class="w-full">
|
||||||
<DataTable v-model:selection="selectedAttRange" :value="attRangeData" dataKey="id" breakpoint="0" tableClass="w-full !border-separate !border-spacing-x-2 !table-auto text-sm" @row-select="onRowSelect">
|
<DataTable v-model:selection="selectedAttRange" :value="attRangeData" dataKey="id" breakpoint="0" tableClass="w-full !border-separate !border-spacing-x-2 !table-auto text-sm" @row-select="onRowSelect" @row-unselect="onRowUnselect" @row-select-all="onRowSelectAll($event)" @row-unselect-all="onRowUnelectAll">
|
||||||
<ColumnGroup type="header">
|
<ColumnGroup type="header">
|
||||||
<Row>
|
<Row>
|
||||||
<Column selectionMode="multiple" :headerClass="headerModeClass" ></Column>
|
<Column selectionMode="multiple" :headerClass="headerModeClass" ></Column>
|
||||||
@@ -241,11 +241,14 @@ export default {
|
|||||||
}
|
}
|
||||||
return sliderData;
|
return sliderData;
|
||||||
},
|
},
|
||||||
// user select time start and end
|
// user select value type start and end
|
||||||
attValueTypeStartEnd: function() {
|
attValueTypeStartEnd: function() {
|
||||||
let start;
|
let start;
|
||||||
let end;
|
let end;
|
||||||
switch (this.selectedAttName.type) {
|
let data;
|
||||||
|
const type = this.selectedAttName.type;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
case 'date':
|
case 'date':
|
||||||
start = getMoment(this.startTime).format('YYYY-MM-DDTHH:mm:00');
|
start = getMoment(this.startTime).format('YYYY-MM-DDTHH:mm:00');
|
||||||
end = getMoment(this.endTime).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;
|
end = this.valueEnd;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// this.selectTimeFrame = [start, end]; // 傳給後端的資料
|
data = { // 傳給後端的資料
|
||||||
// this.$emit('on-row-select', e.data);
|
type: type,
|
||||||
|
data: {
|
||||||
|
key: this.selectedAttName.key,
|
||||||
|
min: start,
|
||||||
|
max: end,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.$emit('select-attribute', data);
|
||||||
|
|
||||||
return [start, end];
|
return [start, end];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
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
|
* @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
|
if(this.valueData) { // 切換 Attribute Name
|
||||||
// 初始化雙向綁定
|
// 初始化雙向綁定
|
||||||
this.selectArea = [0, this.selectRange];
|
this.selectArea = [0, this.selectRange];
|
||||||
@@ -304,8 +366,6 @@ export default {
|
|||||||
this.attValueTypeStartEnd;
|
this.attValueTypeStartEnd;
|
||||||
// 建立圖表
|
// 建立圖表
|
||||||
this.createChart();
|
this.createChart();
|
||||||
} else { // 選取類別型 table 的選項
|
|
||||||
// this.$emit('on-row-select', e.data);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@@ -467,8 +527,8 @@ export default {
|
|||||||
this.endMinDate = new Date(start);
|
this.endMinDate = new Date(start);
|
||||||
this.startMaxDate = new Date(end);
|
this.startMaxDate = new Date(end);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this.valueStart = start;
|
this.valueStart = start;
|
||||||
this.valueEnd = end;
|
this.valueEnd = end;
|
||||||
// 重新設定 start end 日曆選取範圍
|
// 重新設定 start end 日曆選取範圍
|
||||||
this.valueEndMin = start;
|
this.valueEndMin = start;
|
||||||
@@ -513,9 +573,29 @@ export default {
|
|||||||
else return;
|
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() {
|
mounted() {
|
||||||
// Slider
|
// Slider
|
||||||
this.selectArea = [0, this.selectRange]; // 初始化滑塊
|
this.selectArea = [0, this.selectRange]; // 初始化滑塊
|
||||||
|
},
|
||||||
|
beforeUnmount() {
|
||||||
|
this.selectedAttName = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -85,7 +85,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- title: Attributes -->
|
<!-- title: Attributes -->
|
||||||
<Attributes v-if="selectValue[0] === 'Attributes'"></Attributes>
|
<Attributes v-if="selectValue[0] === 'Attributes'" @select-attribute="getSelectAttribute"></Attributes>
|
||||||
<!-- title: Trace -->
|
<!-- title: Trace -->
|
||||||
<Trace v-if="selectValue[0] === 'Trace'" ref="filterTraceView"></Trace>
|
<Trace v-if="selectValue[0] === 'Trace'" ref="filterTraceView"></Trace>
|
||||||
<!-- title: Timeframes -->
|
<!-- title: Timeframes -->
|
||||||
@@ -151,6 +151,8 @@ export default {
|
|||||||
6: 'Contained in',
|
6: 'Contained in',
|
||||||
},
|
},
|
||||||
selectFilterTask: null,
|
selectFilterTask: null,
|
||||||
|
selectAttType: '',
|
||||||
|
selectAttribute: null,
|
||||||
selectFilterStart: null,
|
selectFilterStart: null,
|
||||||
selectFilterEnd: null,
|
selectFilterEnd: null,
|
||||||
selectFilterStartToEnd: null,
|
selectFilterStartToEnd: null,
|
||||||
@@ -199,6 +201,7 @@ export default {
|
|||||||
isDisabledButton: function() {
|
isDisabledButton: function() {
|
||||||
let disabled = true;
|
let disabled = true;
|
||||||
let sele = this.selectValue;
|
let sele = this.selectValue;
|
||||||
|
const type = this.selectAttType;
|
||||||
|
|
||||||
switch(sele[0]) {
|
switch(sele[0]) {
|
||||||
case 'Sequence': // Filter Type 選 Sequence 的行為
|
case 'Sequence': // Filter Type 選 Sequence 的行為
|
||||||
@@ -224,6 +227,23 @@ export default {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
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 的行為
|
case 'Trace': // Filter Type 選 Trace 的行為
|
||||||
disabled = false;
|
disabled = false;
|
||||||
break;
|
break;
|
||||||
@@ -315,6 +335,13 @@ export default {
|
|||||||
list.sort((x, y) => y.occurrences_base - x.occurrences_base)
|
list.sort((x, y) => y.occurrences_base - x.occurrences_base)
|
||||||
return list;
|
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
|
* @param {array} select select Have activity(s) rows
|
||||||
*/
|
*/
|
||||||
@@ -396,40 +423,54 @@ export default {
|
|||||||
|
|
||||||
switch(e.type){
|
switch(e.type){
|
||||||
case "contains-task":
|
case "contains-task":
|
||||||
label = `${includeStr}, ${e.task}`
|
label = `${includeStr}, ${e.task}`;
|
||||||
type = "Sequence"
|
type = "Sequence";
|
||||||
break
|
break;
|
||||||
case "starts-with":
|
case "starts-with":
|
||||||
label = `${includeStr}, start with ${e.task} `
|
label = `${includeStr}, start with ${e.task}`;
|
||||||
type = "Sequence"
|
type = "Sequence";
|
||||||
break
|
break;
|
||||||
case "ends-with":
|
case "ends-with":
|
||||||
label = `${includeStr}, end with ${e.task} `
|
label = `${includeStr}, end with ${e.task}`;
|
||||||
type = "Sequence"
|
type = "Sequence";
|
||||||
break
|
break;
|
||||||
case "start-end":
|
case "start-end":
|
||||||
label = `${includeStr}, start with ${e.starts_with}, end with ${e.ends_with}`
|
label = `${includeStr}, start with ${e.starts_with}, end with ${e.ends_with}`;
|
||||||
type = "Sequence"
|
type = "Sequence";
|
||||||
break
|
break;
|
||||||
case "directly-follows":
|
case "directly-follows":
|
||||||
label = `${includeStr}, directly follows, ${e.task_seq.join(' -> ')}`
|
label = `${includeStr}, directly follows, ${e.task_seq.join(' -> ')}`;
|
||||||
type = "Sequence"
|
type = "Sequence";
|
||||||
break
|
break;
|
||||||
case "eventually-follows":
|
case "eventually-follows":
|
||||||
label = `${includeStr}, eventually follows, ${e.task_seq.join(' -> ')}`
|
label = `${includeStr}, eventually follows, ${e.task_seq.join(' -> ')}`;
|
||||||
type = "Sequence"
|
type = "Sequence";
|
||||||
break
|
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 "occurred-in":
|
||||||
case "started-in":
|
case "started-in":
|
||||||
case "completed-in":
|
case "completed-in":
|
||||||
case "occurred-around":
|
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")} `
|
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"
|
type = "Timeframe"
|
||||||
break
|
break;
|
||||||
case "trace-freq":
|
|
||||||
label = `${includeStr}, from #${e.lower} to #${e.upper}`
|
|
||||||
type = "Trace"
|
|
||||||
break
|
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
type,
|
type,
|
||||||
@@ -451,6 +492,10 @@ export default {
|
|||||||
this.isStartSelected = null;
|
this.isStartSelected = null;
|
||||||
this.isEndSelected = null;
|
this.isEndSelected = null;
|
||||||
this.isActAllTask = true;
|
this.isActAllTask = true;
|
||||||
|
// Attributes
|
||||||
|
this.selectAttType = '';
|
||||||
|
this.selectAttribute = null;
|
||||||
|
this.$emitter.emit('map-filter-reset', true);
|
||||||
// Timeframes
|
// Timeframes
|
||||||
this.selectTimeFrame = [];
|
this.selectTimeFrame = [];
|
||||||
// Trace
|
// Trace
|
||||||
@@ -520,6 +565,55 @@ export default {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
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 的行為
|
case 'Trace': // Filter Type 選 Trace 的行為
|
||||||
let lowerIndex = this.$refs.filterTraceView.selectArea[0];
|
let lowerIndex = this.$refs.filterTraceView.selectArea[0];
|
||||||
let upperIndex = this.$refs.filterTraceView.selectArea[1]-1;
|
let upperIndex = this.$refs.filterTraceView.selectArea[1]-1;
|
||||||
|
|||||||
@@ -97,22 +97,7 @@ export default defineStore('allMapDataStore', {
|
|||||||
},
|
},
|
||||||
filterAttrs: state => {
|
filterAttrs: state => {
|
||||||
if(state.allFilterAttrs !== null){
|
if(state.allFilterAttrs !== null){
|
||||||
state.allFilterAttrs.map(att => {
|
state.allFilterAttrㄧㄠ
|
||||||
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;
|
|
||||||
});
|
|
||||||
return state.allFilterAttrs;
|
return state.allFilterAttrs;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -143,7 +143,8 @@
|
|||||||
fileId = file.id;
|
fileId = file.id;
|
||||||
type = 'log';
|
type = 'log';
|
||||||
params = { type: type, fileId: fileId };
|
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;
|
break;
|
||||||
case 'Filter':
|
case 'Filter':
|
||||||
this.createFilterId = file.id;
|
this.createFilterId = file.id;
|
||||||
@@ -151,7 +152,8 @@
|
|||||||
fileId = file.id;
|
fileId = file.id;
|
||||||
type = 'filter';
|
type = 'filter';
|
||||||
params = { type: type, fileId: fileId };
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user