diff --git a/src/G6/index.ts b/src/G6/index.ts index 7cd5665..3f8818e 100644 --- a/src/G6/index.ts +++ b/src/G6/index.ts @@ -1,8 +1,6 @@ import G6 from "@antv/g6"; import { breakdownNode as breakdownNodeConfig, - rootNode as rootNodeConfig, - treeNode as treeNodeConfig, workflowNode as workflowNodeConfig, } from "@/G6/nodeConfig.ts"; import { @@ -13,8 +11,8 @@ import { activateNodeBehavior as activateNodeBehaviorConfig } from "@/G6/behavio export function G6Register() { // node registration - G6.registerNode("rootNode", rootNodeConfig, "rect"); - G6.registerNode("treeNode", treeNodeConfig); + // G6.registerNode("rootNode", rootNodeConfig, "rect"); + // G6.registerNode("treeNode", treeNodeConfig); G6.registerNode("breakdownNode", breakdownNodeConfig); G6.registerNode("workflowNode", workflowNodeConfig); // edge registration diff --git a/src/G6/nodeConfig.ts b/src/G6/nodeConfig.ts index 2c77245..d1dab60 100644 --- a/src/G6/nodeConfig.ts +++ b/src/G6/nodeConfig.ts @@ -110,6 +110,28 @@ export const rootNode: ShapeOptions = { }, }; export const breakdownNode: ShapeOptions = { + setState(name, value, item) { + const group = item?.getContainer(); + const rectShape = group?.get("children")[0]; + const textShape = group?.get("children")[1]; + if (name === "hover") { + if (value) { + rectShape.attr({ + stroke: "green", + }); + textShape.attr({ + fill: "green", + }); + } else { + rectShape.attr({ + stroke: "#5A77C1", + }); + textShape.attr({ + fill: "#000", + }); + } + } + }, draw(cfg, group) { const r = 10; const keyShape = group.addShape("circle", { @@ -120,9 +142,9 @@ export const breakdownNode: ShapeOptions = { stroke: "#5B8FF9", fill: "#D7DCF1", lineWidth: 2, - // cursor: "pointer", + cursor: "pointer", }, - name: "root-node-key-shape", + name: "breakdown-node-key-shape", }); group.addShape("text", { attrs: { @@ -135,7 +157,7 @@ export const breakdownNode: ShapeOptions = { textBaseline: "middle", // cursor: "pointer", }, - name: "root-text-shape", + name: "breakdown-text-shape", }); return keyShape; }, @@ -147,6 +169,28 @@ export const breakdownNode: ShapeOptions = { }, }; export const workflowNode: ShapeOptions = { + setState(name, value, item) { + const group = item?.getContainer(); + const rectShape = group?.get("children")[0]; + const textShape = group?.get("children")[2]; + if (name === "hover") { + if (value) { + rectShape.attr({ + stroke: "green", + }); + textShape.attr({ + fill: "green", + }); + } else { + rectShape.attr({ + stroke: "#5A77C1", + }); + textShape.attr({ + fill: "#000", + }); + } + } + }, draw(cfg, group) { const size = 24; const keyShape = group.addShape("rect", { diff --git a/src/api/index.ts b/src/api/index.ts index e7b6ed0..6487230 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -5,8 +5,8 @@ */ // 手动修改 Mock 接口 -export * from "./job.ts"; -// export * from "./mock.ts"; +// export * from "./job.ts"; +export * from "./mock.ts"; export * from "./qgis.ts"; // TODO: interface definition of api diff --git a/src/components/BreakdownChart.vue b/src/components/BreakdownChart.vue index 7233538..6bf42dc 100644 --- a/src/components/BreakdownChart.vue +++ b/src/components/BreakdownChart.vue @@ -2,12 +2,17 @@ import G6 from "@antv/g6"; import { onMounted } from "vue"; import { useJobStore } from "@/store/job.ts"; +import { IG6GraphEvent } from "@antv/g6-core/lib/types"; +import { useGraphStore } from "@/store/graph.ts"; +import { storeToRefs } from "pinia"; const props = defineProps<{ graphId: string; }>(); const jobStore = useJobStore(); +const graphStore = useGraphStore(); +let { tree, graph } = storeToRefs(graphStore); const getGraphNum = function () { return "mountNode-" + props.graphId; @@ -15,7 +20,7 @@ const getGraphNum = function () { onMounted(() => { console.log("breakdown"); - const tree = new G6.TreeGraph({ + tree.value = new G6.TreeGraph({ container: getGraphNum(), animate: false, layout: { @@ -37,9 +42,30 @@ onMounted(() => { }, }); - tree.data(jobStore.breakdownData); - tree.render(); - tree.fitCenter(); + tree.value.data(jobStore.breakdownData); + tree.value.render(); + tree.value.fitCenter(); + + tree.value.on("node:mouseover", (evt: IG6GraphEvent) => { + const node = evt.item; + node?.setState("hover", true); + const EqNode = graph.value!.find("node", (n) => { + return n.getModel().label === node?.getModel().label; + }); + if (EqNode) { + graph.value!.setItemState(EqNode, "hover", true); + } + }); + tree.value.on("node:mouseout", (evt: IG6GraphEvent) => { + const node = evt.item; + node?.setState("hover", false); + const EqNode = graph.value!.find("node", (n) => { + return n.getModel().label === node?.getModel().label; + }); + if (EqNode) { + graph.value!.setItemState(EqNode, "hover", false); + } + }); }); diff --git a/src/components/WorkflowChart.vue b/src/components/WorkflowChart.vue index 00a9ed6..3835e90 100644 --- a/src/components/WorkflowChart.vue +++ b/src/components/WorkflowChart.vue @@ -8,6 +8,9 @@ import { onMounted } from "vue"; import G6 from "@antv/g6"; import { useJobStore } from "@/store/job.ts"; import { useTaskStore } from "@/store/task.ts"; +import { IG6GraphEvent } from "@antv/g6-core/lib/types"; +import { useGraphStore } from "@/store/graph.ts"; +import { storeToRefs } from "pinia"; const props = defineProps<{ graphId: string; @@ -15,6 +18,8 @@ const props = defineProps<{ const jobStore = useJobStore(); const taskStore = useTaskStore(); +const graphStore = useGraphStore(); +let { graph, tree } = storeToRefs(graphStore); const getGraphNum = function () { return "mountNode-" + props.graphId; @@ -22,7 +27,7 @@ const getGraphNum = function () { onMounted(() => { console.log("workflow"); - const graph = new G6.Graph({ + graph.value = new G6.Graph({ container: getGraphNum(), fitCenter: true, layout: { @@ -40,15 +45,38 @@ onMounted(() => { }, }); - graph.data(jobStore.workflowData); - graph.render(); + graph.value.data(jobStore.workflowData); + graph.value.render(); - const group = graph.get("edgeGroup"); + const group = graph.value.get("edgeGroup"); group.toFront(); - graph.on("click", () => { + graph.value.on("click", () => { taskStore.close(); }); + + graph.value.on("node:mouseover", (evt: IG6GraphEvent) => { + const node = evt.item; + node?.setState("hover", true); + tree.value!.setItemState( + tree.value!.find("node", (node) => { + return node.getModel().label === node?.getModel().label; + })!, + "hover", + true, + ); + }); + graph.value.on("node:mouseout", (evt: IG6GraphEvent) => { + const node = evt.item; + node?.setState("hover", false); + tree.value!.setItemState( + tree.value!.find("node", (node) => { + return node.getModel().label === node?.getModel().label; + })!, + "hover", + false, + ); + }); }); diff --git a/src/pages/Home/index.vue b/src/pages/Home/index.vue index 03817d0..30b78f7 100644 --- a/src/pages/Home/index.vue +++ b/src/pages/Home/index.vue @@ -13,7 +13,7 @@ import Case from "@/components/Case.vue"; - + diff --git a/src/store/graph.ts b/src/store/graph.ts new file mode 100644 index 0000000..dd85e0d --- /dev/null +++ b/src/store/graph.ts @@ -0,0 +1,9 @@ +import { defineStore } from "pinia"; +import { ref } from "vue"; +import { Graph, TreeGraph } from "@antv/g6"; + +export const useGraphStore = defineStore("graph", () => { + let graph = ref(); + const tree = ref(); + return { graph, tree }; +}); diff --git a/src/store/job.ts b/src/store/job.ts index 0f07a0c..ed52b69 100644 --- a/src/store/job.ts +++ b/src/store/job.ts @@ -8,8 +8,8 @@ export const useJobStore = defineStore("job", () => { let _job: Task; async function updateData(question: string) { - // const res = (await fetchJob(question)).data; - const res = (await fetchJob(`{ "task": "${question}" }`)).data; + const res = (await fetchJob(question)).data; + // const res = (await fetchJob(`{ "task": "${question}" }`)).data; console.debug("res", res); _job = convertData(res.data);