dash14 / v-network-graph

An interactive network graph visualization component for Vue 3
https://dash14.github.io/v-network-graph/
MIT License
504 stars 44 forks source link

Get default coordinate for node #117

Closed Krusty84 closed 1 year ago

Krusty84 commented 1 year ago

Konnichiwa Dear dash 14! It will be good to have ability for getting nodes coordinate in case there are not using Layouts with predefined coordinates Thanks!

dash14 commented 1 year ago

Hi @Krusty84,

You can get the positions of nodes whether you specify coordinates to layouts or not.

<script setup lang="ts">
import * as vNG from "@v-network-graph";
import { VNetworkGraph } from "@v-network-graph";
import { computed, ref, watch } from "vue";
import data from "./data"

const nodes: vNG.Nodes = {
  node1: { name: "Node 1", active: false },
  node2: { name: "Node 2", active: false },
  node3: { name: "Node 3", active: true },
  node4: { name: "Node 4", active: false },
}

const edges: vNG.Edges = {
  edge1: { source: "node1", target: "node2" },
  edge2: { source: "node2", target: "node3" },
  edge3: { source: "node3", target: "node4" },
}

const layouts = ref<vNG.Layouts>({ nodes: {} /* empty */ });

const layoutsText = computed(() => {
  /* The default coordinates are contained. */
  return JSON.stringify(layouts.value, null, 2)
})
</script>

<template>
  <div>
    <v-network-graph
      :nodes="data.nodes"
      :edges="data.edges"
      v-model:layouts="layouts"
    />
    <pre>{{ layoutsText }}</pre>
  </div>
</template>

<style lang="scss" scoped>
.v-network-graph {
  width: 600px;
  height: 600px;
  border: 1px solid #aaa;
}
</style>

Is this what you need? If not, it would be helpful if you could be more concrete about what you want to do. Thank you!

jaderinoo commented 1 year ago

Hi, I'm running into potentially a similar issue as the op. Using your example above, I was able to figure how to get the generated layouts, but I'm having trouble using the data. I'm making an api call that returns the nodes and edges which are then inputted into the v-network-graph. I'm using d3-force to build out the structure here but I'd like to pan to a specified node on view:load. But since the layout ins't set on load, I have a watch on layouts:

layouts: function (val) {
    this.vNGComp.panTo({
        x: val.nodes[this.currentNodeID].x,
        y: val.nodes[this.currentNodeID].y,
    })
},

But it seems to only watch for the initial push to layouts, so it seems that the location info might be outdated during the call. Is there a better way of handling this?

Thanks for the help in advance, and thank you for making such an awesome component!

Edit: Swapping for to watch deep fixed my issue.

layouts: {
    deep: true,
    handler: function(newValue) {
        const sizes = this.vNGComp.getSizes()
        this.vNGComp.panTo({
            x: sizes.width / 2 - newValue.nodes[this.currentNodeID].x,
            y: sizes.height / 2 - newValue.nodes[this.currentNodeID].y,
        })
    }
},
dash14 commented 1 year ago

I close this issue for now. If you have any other question, please reopen this issue.