From f3b9f7cd410c9c2e78434679f0daaca870087caa Mon Sep 17 00:00:00 2001 From: Cindy Chang Date: Wed, 28 Aug 2024 11:46:54 +0800 Subject: [PATCH] refactor create paths method and highlight path method --- src/i18n/en.json | 1 + src/module/cytoscapeMap.js | 6 ++-- src/stores/mapPathStore.ts | 61 +++++++++++++++++++++++++++++++++- src/views/Discover/Map/Map.vue | 2 +- 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/src/i18n/en.json b/src/i18n/en.json index ea9a824..68cb6f6 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -34,6 +34,7 @@ "AccountInformation": "Account Information", "Password": "Password", "ConfirmPassword": "Confirm Password", + "UserInfo": "User Information", "PwdNotMatch": "Confirm Password does not match.", "SetAsAdmin": "Set as admin.", "ActivateNow": "Activate now.", diff --git a/src/module/cytoscapeMap.js b/src/module/cytoscapeMap.js index d5d3154..b65bbcd 100644 --- a/src/module/cytoscapeMap.js +++ b/src/module/cytoscapeMap.js @@ -174,7 +174,7 @@ export default function cytoscapeMap(mapData, dataLayerType, dataLayerOption, cu return node.data('type') === 'activity' ? -5 : 0; }, 'text-margin-y': function(node) { - return node.data('type') === 'activity' ? 0 : 0; + return node.data('type') === 'activity' ? 2 : 0; }, 'padding': function(node) { return node.data('type') === 'activity' ? 0 : 0; @@ -185,10 +185,10 @@ export default function cytoscapeMap(mapData, dataLayerType, dataLayerOption, cu 'height': 'data(height)', 'width': 'data(width)', 'color': 'data(textColor)', - 'line-height': '0.8rem', + 'line-height': '0.7rem', 'font-size': function(node) { - return node.data('type') === 'activity' ? 16 : 14; + return node.data('type') === 'activity' ? 14 : 14; }, }, }, diff --git a/src/stores/mapPathStore.ts b/src/stores/mapPathStore.ts index 45dbe45..1298f0e 100644 --- a/src/stores/mapPathStore.ts +++ b/src/stores/mapPathStore.ts @@ -17,6 +17,7 @@ export default defineStore('useMapPathStore', { state: () => ({ clickedPath: [], insights: {}, + insightWithPath: {}, cytoscape: null, allPaths: [], allPathsByEdge: [], @@ -31,6 +32,48 @@ export default defineStore('useMapPathStore', { setCytoscape(cytoscape) { this.cytoscape = cytoscape; }, + async createInsightWithPath() { + const { insights } = AllMapData(); + this.insights = {...insights}; + this.startNode = this.cytoscape?.nodes().filter(function(elem) { + return elem.data('label').toLocaleLowerCase() === 'start'; + }); + for(let i = 0; i < INSIGHTS_FIELDS_AND_LABELS.length; i++) { + const curButton = this.insights[INSIGHTS_FIELDS_AND_LABELS[i][0]]; + this.insightWithPath[INSIGHTS_FIELDS_AND_LABELS[i][0]] = {}; // first layer index + + for(let listIndex = 0; listIndex < curButton.length; listIndex++) { + this.insightWithPath[INSIGHTS_FIELDS_AND_LABELS[i][0]][listIndex] = { + edges: [], + nodes: [], + }; // second layer index + + let curGraphNode, prevGraphNode, curEdge; // 配對 curGraphNode 與 nodeIndex 指向的 node + for(let nodeIndex = 0; nodeIndex < curButton[listIndex].length; nodeIndex++){ + if(nodeIndex === 0) { // special case, initialize curGraphNode + curGraphNode = this.startNode.outgoers('node').filter(neighborOfStart => + neighborOfStart.data('label') === curButton[listIndex][nodeIndex] + ); + curEdge = this.startNode.edgesTo(curGraphNode); + } else { + if(prevGraphNode){ + curGraphNode = prevGraphNode.outgoers('node').filter(neighbor => + neighbor.data('label') === curButton[listIndex][nodeIndex] + ); + if(!curGraphNode) { + // curGraphNode = prevGraphNode.outgoers('node').filter(node => + // node.data('label').toLocaleLowerCase() === 'end'); + } + curEdge = prevGraphNode.edgesWith(curGraphNode); + } + } + this.insightWithPath[INSIGHTS_FIELDS_AND_LABELS[i][0]][listIndex].nodes.push(curGraphNode); + this.insightWithPath[INSIGHTS_FIELDS_AND_LABELS[i][0]][listIndex].edges.push(curEdge); + prevGraphNode = curGraphNode; + } + } + } + }, async createPaths() { this.startNode = this.cytoscape?.nodes().filter(function(elem) { return elem.data('label').toLocaleLowerCase() === 'start'; @@ -134,7 +177,15 @@ export default defineStore('useMapPathStore', { } return false; // 當前節點不匹配時返回 false }, - highlightClickedPath(clickedActiveTraceIndex: number, clickedPathListIndex: number) { + highlightClickedPath(clickedActiveTraceIndex: number, clickedPathListIndex: number){ + this.insightWithPath[INSIGHTS_FIELDS_AND_LABELS[clickedActiveTraceIndex][0]][clickedPathListIndex].edges.forEach(edgeToHighlight => { + edgeToHighlight.addClass('highlight-edge'); + }); + this.insightWithPath[INSIGHTS_FIELDS_AND_LABELS[clickedActiveTraceIndex][0]][clickedPathListIndex].nodes.forEach(nodeToHighlight => { + nodeToHighlight.data('nodeImageUrl', ImgCapsulesGlow[nodeToHighlight.data('level')]); + }); + }, + highlightClickedPathUnused(clickedActiveTraceIndex: number, clickedPathListIndex: number) { this.activeTrace = clickedActiveTraceIndex; this.activeListIndex = clickedPathListIndex; this.mapGraphPathToInsight[clickedActiveTraceIndex][clickedPathListIndex].pathByEdge @@ -176,6 +227,14 @@ export default defineStore('useMapPathStore', { clickedEdge.addClass('highlight-edge'); }, async highlightMostFrequentPath() { + const LIST_INDEX = 0; + this.insightWithPath['most_freq_traces'][LIST_INDEX].nodes.map(nodeToHighlight => { + nodeToHighlight.data('nodeImageUrl', ImgCapsulesGlow[nodeToHighlight.data('level')]); + }); + this.insightWithPath['most_freq_traces'][LIST_INDEX].edges.map(edgeToHighlight => + edgeToHighlight.addClass('highlight-edge')); + }, + async highlightMostFrequentPathUnused() { for(let buttonIter = 0; buttonIter < INSIGHTS_FIELDS_AND_LABELS.length; buttonIter++) { // 有可能遇到兩個以上的most frequent paths,然而我們只取一個path點亮 if (this.mapGraphPathToInsight[buttonIter]) { diff --git a/src/views/Discover/Map/Map.vue b/src/views/Discover/Map/Map.vue index 33d3e02..775557e 100644 --- a/src/views/Discover/Map/Map.vue +++ b/src/views/Discover/Map/Map.vue @@ -486,7 +486,7 @@ export default { this.baseTraceId = await this.baseTraces[0]?.id; await this.createCy(this.mapType); await mapPathStore.setCytoscape(this.cytoscapeGraph); - await mapPathStore.createPaths(); + await mapPathStore.createInsightWithPath(); await mapPathStore.highlightMostFrequentPath(); await this.allMapDataStore.getFilterParams(); await this.allMapDataStore.getTraceDetail();