1

I am using vue.js and v-tree + vue2vis network, I have a tree with all my items like this one :

items: [
          {
            id: 1,
            name: 'root',
            children: [
              {
                id: 2,
                name: 'child1',
                children: [
                  {
                    id: 3,
                    name: 'child3',
                  },
                  {
                    id: 4,
                    name: 'child34',
                  },
                ],
              },
              {
                id: 5,
                name: 'subroot',
                children: [
                  {
                    id: 6,
                    name: 'Mike',
                    children:[
                      {
                        id: 7,
                        name: 'Mini Mike',
                      }
                    ]
                  },
                  {
                    id: 8,
                    name: 'Hunt',
                  },
                ],
              },
              {
                id: 9,
                name: 'test',
                children: [
                  {
                    id: 10,
                    name: 'Brandon',
                  },
                  {
                    id: 11,
                    name: 'Sean',
                  },
                ],
              },
            ],
          },
        ],

And what i want to do is when i click on a item in the tree it will generate data for the network like this:

nodes: [{'id':1 , label: 'root'},{'id':2 , label: 'child1'},{'id':3 , label: 'child3'}]
and so on for all the children and parents
same goes for the edage i want to create conection between parent and child
edage: [{'from': 1, 'to':2},{'from': 2, 'to':3}]

I try this function for this idea but its not working

      makeNetConnection(items , itemKey) {
//items -> all the tree data
//itemKey-> its the item i click on the tree that i want to create the view
          for (let item of items) {
              if (item.name == itemKey) {
                this.nodes.push({'id':item.id , 'label':item.name});
                return item;
              }
              if (item.children) {
                  let i = this.makeNetConnection(item.children ,itemKey)
                  if (i) { 
                    this.nodes.push({'id':item.id , 'label':item.name});
                    this.edges.push({'from': item.id , 'to': i.id});
                    return i;
                  }
              }
          }

its duplicate the data in the arrays and not make connect with the parent i expect to have [{'from': 1, 'to':2},{'from': 2, 'to':3},{'from': 2, 'to':4}] and os on for all the items

but i have [{'from': 1, 'to':2},{'from': 1, 'to':3} , {'from': 1, 'to':2},{'from': 1, 'to':3}, {'from': 1, 'to':4}, {'from': 1, 'to':4}]

i dont get the middel connection any idea how to make its work?

2
  • I'd suggest that you read How do I create a runnable stack snippet?. It would make it easier for us to work on your problem. Commented Jul 8, 2021 at 12:56
  • Ohhh, So that how people do thoes example , nice one i will use it from now on Commented Jul 8, 2021 at 13:19

2 Answers 2

2

Maybe overkill, but use traverse

const traverse = require('traverse');
const returnData=[];

traverse.forEach(function(item){
   returnData.push({id:item.id,label:item.value});
});
Sign up to request clarification or add additional context in comments.

5 Comments

Hey, I am not using node.js for that because its on the client side , I need to pass this dat a between component. Thanks anyway
You don't have to use "pure" node.js. Just import the library in your view-file (vuex would be better of course) with require in your code (created,mounted,...) and call traverse. created() { const obj = { a: [1, 2, 3], b: 4, c: [5, 6], d: { e: [7, 8], f: 9 } }; const traverse = require('traverse'); traverse(obj).forEach(function(x) { console.log(x); });
Hey, its not working the vue dont recognize const traverse = require('traverse'); Do you have aby other way without uding traverse ?
I don't know that library, but I know that snippet is wrong. It doesn't mention the input data at all! Should it be something like traverse.forEach(items, function(item) {/* ... */}) or perhaps traverse(items).forEach(function(item) {/* ... */})?
@ScottSauyet . My problem is how to present my json that contain parents and thier children into a graph like i explain before how to create this recursive, my function kinda work but insted 1->2->3,4 its make 2->3 , 2->4 , 1->3 , 1->4 Do you have any idea why according to my function above?
1

I would build this upon simpler functions to collect the nodes and to collect the edges. It means running two traversals of your tree, but it makes for much simpler code.

Here we have a recursive function to flatten the nodes of a tree into an array, transforming the name property to a label one as we go. And we have a second recursive function to collect the edges as from-to pairs.

Then we write a very simple function to combine them:

const collectNodes = (xs) => 
  xs .flatMap (({id, name, children = []}) => [
    {id, label: name},
    ... collectNodes (children)
  ])

const collectEdges = (xs) => 
  xs .flatMap (({id: from, children = []}) => [
    ... children .map (({id: to}) => ({from, to})),
    ... collectEdges (children),
  ])
 
const collect = (items) => ({
  nodes: collectNodes (items),
  edges: collectEdges (items)
})

const items = [{id: 1, name: "root", children: [{id: 2, name: "child1", children: [{id: 3, name: "child3"}, {id: 4, name: "child34"}]}, {id: 5, name: "subroot", children: [{id: 6, name: "Mike", children: [{id: 7, name: "Mini Mike"}]}, {id: 8, name: "Hunt"}]}, {id: 9, name: "test", children: [{id: 10, name: "Brandon"}, {id: 11, name: "Sean"}]}]}]

console .log (collect (items))
.as-console-wrapper {max-height: 100% !important; top: 0}

Could we do this in a single traversal? Certainly, but I think it would make for more convoluted code. I would only bother doing so if the performance of this is not acceptable.

I ignored this: "when i click on a item in the tree". I'm assuming that you want to convert all the data. If you only want it up to a certain node, then please add a clarification to the question.

5 Comments

Thank You SO MUCH IS WOKING LIKE A CHARM,
If I want to do this when i click on item in the tree , i need to send the id of the item and do the same for all the tree and check only if i see this id add it to the array? like i click on id = 6 its show me onlinr the relevent 6->7
I did it, to make it work when i click on item inside a tree i make it like this ``` var obj = find(this.items); var newObj = [JSON.parse(JSON.stringify(obj))] console.dir(collect(newObj)) ``` the find function is lister and return a object type then i turn it to json arrays like items , and send it to the collect function that map all the nodes and edges that you wrote. :)
I'm afraid I'm not following what it is you need to do. If you got it working, great! If not, perhaps edit this question with more details or open a new one.
its okay haha... i got all i need working fine tank to your help

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.