dash14 / v-network-graph

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

Exporting/Serializing as JSON #59

Closed jacklinke closed 2 years ago

jacklinke commented 2 years ago

I want to be able to save the state of a graph to my database, ideally by grabbing the state as JSON, and then passing that to my Django backend.

In #48 you show how v-network-graph can utilize JSON content as an input, but is there a recommended way to get the graph contents as a JSON output? That way if I enable editing for user-generated graphs, I can persist those changes for my users.

For instance, I see getAsSvg(): string mentioned in the docs. Would it be helpful to have an equivalent getAsJSON(): string method? I'm not very JS/Vue savvy, so there's probably already an obvious way to accomplish this that I just don't see. Either way, I'd love your input.

Thanks for building a really cool project and for any help you can provide with my question.

dash14 commented 2 years ago

Hi @jacklinke,

Thanks for the question. v-network-graph basically displays objects given as attributes. The information that is updated by user manipulation is also mostly available from the attributes. Please refer to the following for a list of attributes and whether they are updated from the library. https://dash14.github.io/v-network-graph/reference.html#attributes

Unfortunately, since it is application-dependent as to which items are needed (or not), there are currently no plans to provide serialization capabilities in the library.

I think it can be achieved by assembling as JSON the variables to be passed to these attributes, and then disassembling them and passing them to the library when displaying them. Easier still, it is possible to enclose a single JSON object in reactive and pass it to the library with each attribute. An example is shown below.

<!-- App.vue -->
<script setup lang="ts">
import { defineConfigs, Edges, Layouts, Nodes } from "v-network-graph";
import { reactive } from "vue";

// Define what you want to serialize/deserialize
interface TopologyModel {
  nodes: Nodes;
  edges: Edges;
  layouts: Layouts;
  selectedNodes: string[];
}

const model = reactive<TopologyModel>({
  nodes: {
    node0: { name: "Node 0" },
    node1: { name: "Node 1" },
    node2: { name: "Node 2" },
    node3: { name: "Node 3" },
  },
  edges: {
    edge1: { source: "node0", target: "node1" },
    edge2: { source: "node1", target: "node2" },
    edge3: { source: "node2", target: "node3" },
  },
  layouts: {
    nodes: {
      node0: { x: 0, y: 0 },
      node1: { x: 50, y: 80 },
      node2: { x: 100, y: 0 },
      node3: { x: 150, y: 80 },
    },
  },
  selectedNodes: [],
});

const configs = defineConfigs({
  node: {
    selectable: true,
  },
});

function exportModel() {
  // Just save this object as is.
  console.log(model);
}
</script>

<template>
  <div class="graph">
    <v-network-graph
      :nodes="model.nodes"
      :edges="model.edges"
      v-model:layouts="model.layouts"
      v-model:selected-nodes="model.selectedNodes"
      :configs="configs"
    />
    <button @click="exportModel">Export</button>
  </div>
</template>

<style>
.graph {
  border: 1px solid #888;
  width: 600px;
  height: 400px;
  margin: 0 auto;
}
</style>

I hope this will be helpful to you. Best Regards,

dash14 commented 2 years ago

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