dualonNodeClickHighlightEdges and onEdgeClickHighlightNodes

This commit is contained in:
Cindy Chang
2024-08-21 15:10:50 +08:00
parent c3c2861a8f
commit 85b8536f3a
2 changed files with 47 additions and 15 deletions

View File

@@ -3,11 +3,13 @@ import spread from 'cytoscape-spread';
import dagre from 'cytoscape-dagre'; import dagre from 'cytoscape-dagre';
import tippy from 'tippy.js'; import tippy from 'tippy.js';
import 'tippy.js/dist/tippy.css'; import 'tippy.js/dist/tippy.css';
import MapPathStore from '@/stores/mapPathStore';
import Gradient from 'javascript-color-gradient'; // 多個色階產生器 import Gradient from 'javascript-color-gradient'; // 多個色階產生器
import { getTimeLabel } from '@/module/timeLabel.js'; // 時間格式轉換器 import { getTimeLabel } from '@/module/timeLabel.js'; // 時間格式轉換器
import CytoscapeStore from '@/stores/cytoscapeStore'; import CytoscapeStore from '@/stores/cytoscapeStore';
import { SAVE_KEY_NAME } from '@/constants/constants.js'; import { SAVE_KEY_NAME } from '@/constants/constants.js';
const mapPathStore = MapPathStore();
const composeFreqTypeText = (baseText, dataLayerOption, optionValue) => { //sonar-qube const composeFreqTypeText = (baseText, dataLayerOption, optionValue) => { //sonar-qube
let text = baseText; let text = baseText;
const textInt = dataLayerOption === 'rel_freq' ? baseText + optionValue * 100 + "%" : baseText + optionValue; const textInt = dataLayerOption === 'rel_freq' ? baseText + optionValue * 100 + "%" : baseText + optionValue;
@@ -241,6 +243,13 @@ export default function cytoscapeMap(mapData, dataLayerType, dataLayerOption, cu
'overlay-opacity': 0.2, 'overlay-opacity': 0.2,
'overlay-padding': '5px', 'overlay-padding': '5px',
}, },
},{
selector: '.highlight-node',
style: {
'overlay-color': '#0099FF',
'overlay-opacity': 0.01,
'overlay-padding': '5px',
},
} }
], ],
}); });
@@ -257,6 +266,17 @@ export default function cytoscapeMap(mapData, dataLayerType, dataLayerOption, cu
event.target.addClass('highlight-edge'); event.target.addClass('highlight-edge');
}); });
// 按下節點光暈效果與鄰邊光暈效果
cy.on('tap, mousedown', 'node', function(event) {
mapPathStore.onNodeClickHighlightEdges(event.target);
});
// 按下線段光暈效果與兩端點光暈效果
cy.on('tap, mousedown', 'edge', function(event) {
mapPathStore.onEdgeClickHighlightNodes(event.target);
});
// creat tippy.js // creat tippy.js
let tip; let tip;
cy.on('mouseover', 'node', function(event) { cy.on('mouseover', 'node', function(event) {

View File

@@ -14,20 +14,8 @@ import ImgCapsule4 from '@/assets/capsule4.svg';
const ImgCapsulesGlow = [ImgCapsuleGlow1, ImgCapsuleGlow2, ImgCapsuleGlow3, ImgCapsuleGlow4]; const ImgCapsulesGlow = [ImgCapsuleGlow1, ImgCapsuleGlow2, ImgCapsuleGlow3, ImgCapsuleGlow4];
const ImgCapsules = [ImgCapsule1, ImgCapsule2, ImgCapsule3, ImgCapsule4]; const ImgCapsules = [ImgCapsule1, ImgCapsule2, ImgCapsule3, ImgCapsule4];
interface MapPathStoreState {
clickedPath: string[];
insights: Record<string, any[]>; // Replace `any` with the correct type if available
cytoscape: cytoscape.Core | null;
allPaths: NodeSingular[][];
allPathsByEdge: EdgeSingular[][];
startNode: NodeSingular | null;
mapGraphPathToInsight: Record<string, { [key: string]: number; pathByNode: NodeSingular[]; pathByEdge: EdgeSingular[] }>;
activeTrace: number;
activeListIndex: number;
}
export default defineStore('useMapPathStore', { export default defineStore('useMapPathStore', {
state: (): MapPathStoreState => ({ state: () => ({
clickedPath: [], clickedPath: [],
insights: {}, insights: {},
cytoscape: null, cytoscape: null,
@@ -37,6 +25,7 @@ export default defineStore('useMapPathStore', {
mapGraphPathToInsight: {}, mapGraphPathToInsight: {},
activeTrace: 0, activeTrace: 0,
activeListIndex: 0, activeListIndex: 0,
lastClickedNode: null,
}), }),
actions: { actions: {
setCytoscape(cytoscape) { setCytoscape(cytoscape) {
@@ -165,10 +154,33 @@ export default defineStore('useMapPathStore', {
}) })
}, },
clearAllHighlight() { clearAllHighlight() {
this.cytoscape.edges().removeClass('highlight-edge'); this.cytoscape?.edges().removeClass('highlight-edge');
this.cytoscape.nodes().forEach(nodeToReset => { this.cytoscape?.nodes().removeClass('highlight-node');
this.cytoscape?.nodes().forEach(nodeToReset => {
nodeToReset.data('nodeImageUrl', ImgCapsules[nodeToReset.data('level')]) nodeToReset.data('nodeImageUrl', ImgCapsules[nodeToReset.data('level')])
}) })
}, },
onNodeClickHighlightEdges(clickedNode) {
this.clearAllHighlight();
clickedNode.addClass('highlight-node');
clickedNode.data('nodeImageUrl', ImgCapsulesGlow[clickedNode.data('level')]);
clickedNode.outgoers('edge').forEach(edgeToHighlight => edgeToHighlight.addClass('highlight-edge'));
clickedNode.incomers('edge').forEach(edgeToHighlight => edgeToHighlight.addClass('highlight-edge'));
this.lastClickedNode = clickedNode;
},
onEdgeClickHighlightNodes(clickedEdge) {
this.clearAllHighlight();
const sourceNode = clickedEdge.source();
const targetNode = clickedEdge.target();
sourceNode.addClass('highlight-node');
targetNode.addClass('highlight-node');
sourceNode.data('nodeImageUrl', ImgCapsulesGlow[sourceNode.data('level')]);
targetNode.data('nodeImageUrl', ImgCapsulesGlow[targetNode.data('level')]);
clickedEdge.addClass('highlight-edge');
},
}, },
}); });