简体   繁体   中英

vue.js with d3.js Uncaught TypeError

Im currently having an issue to use Vue.js and d3.js in conjuction with axios. I'm trying to consume an Restful-API and give the response to an d3.js force-simulation.

I'm not sure what the problem is, since in the vue-devtool webGraph is shown like i needs to.

And the code works with static Data...Does it have something to do with the Reactiv nature of vue?

<template>
  <div>
    <h2>Hello There</h2>
    <div id="chart"></div>
  </div>
</template>

<script>
import * as d3 from "d3";
import * as axios from "axios";

export default {
  url: "NetworkSample",
  data (){
    return{
       webGraph: {
        nodes:[],
        edges:[]
      }
    }
  },
  mounted(){
    axios.get('http://localhost:8080/apiV1/graph')
        .then(r => {
            let nodes = r.data.nodes;
            let edges = r.data.edges;
            for(let i = 0; i < nodes.length; i++){
              let node = {
                  url: nodes[i].url,
                  type: nodes[i].type,
                  outgoing: nodes[i].outgoing.length
              }
              this.webGraph.nodes.push(node);
            }

            for(let i = 0; i< edges.length; i++){
              let edge = {
                  weight: edges[i].weight.double,
                  source: edges[i].from.url,
                  target: edges[i].to.url.toString(),
                  type:edges[i].type,
              }
              this.webGraph.edges.push(edge);
            }
        })
    
    function simu() {
      d3.forceSimulation(this.webGraph.nodes)
          .force("charge", d3.forceManyBody().strength(-25))
          .force("link", d3.forceLink().id(d => d).links(this.webGraph.edges))
          .on('end', function () {
             render();
          });
    }
    this.$nextTick(simu());

webGraph

data

The exception:

link.js?f3d7:41 Uncaught TypeError: Cannot create property 'vx' on string 'www.site.com'
    at force (link.js?f3d7:41)
    at eval (simulation.js?5481:48)
    at Map.forEach (<anonymous>)
    at tick (simulation.js?5481:47)
    at step (simulation.js?5481:31)
    at timerFlush (timer.js?74f4:61)
    at wake (timer.js?74f4:71)

 const URL = 'https://jsonplaceholder.typicode.com/posts'; new Vue({ el: '#app', data() { return { loading: true, webGraph: { nodes: [], edges: [] } } }, created() { axios.get(URL).then((response) => { let node1 = { url: response.data[1].body } let node2 = { url: response.data[1].body + "22" } let edge = { source: response.data[1].body, target: response.data[1].body + "22" } this.webGraph.nodes.push(node1) this.webGraph.nodes.push(node2) this.webGraph.edges.push(edge) }) d3.forceSimulation(this.webGraph.nodes).force("charge", d3.forceManyBody().strength(-25)).force("link", d3.forceLink().id(d => d.id).links(this.webGraph.edges)).on('end', function() {}); } })
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> </div>

I'm not sure without a minimal reproducible example, but it looks like the nodes are strings, while they need to be objects. I get a similar error in the following scenario:

 const nodes = 'ab'.split(''); const edges = [ { source: 'a', target: 'b' } ]; const circles = d3.select('body').append('svg').selectAll('circle').data(nodes).join( enter => enter.append('circle').attr('r', 10) ); d3.forceSimulation(nodes).force("charge", d3.forceManyBody().strength(-25)).force("link", d3.forceLink().id(d => d.id).links(edges)).force("x", d3.forceX(150)).force("y", d3.forceY(100)).on('tick', () => circles.attr('cx', d => dx).attr('cy', d => dy) );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>

But when I replace the very first line, it works:

 const nodes = 'ab'.split('').map(d => ({ id: d })); const edges = [ { source: 'a', target: 'b' } ]; const circles = d3.select('body').append('svg').selectAll('circle').data(nodes).join( enter => enter.append('circle').attr('r', 10) ); d3.forceSimulation(nodes).force("charge", d3.forceManyBody().strength(-25)).force("link", d3.forceLink().id(d => d.id).links(edges)).force("x", d3.forceX(150)).force("y", d3.forceY(100)).on('tick', () => circles.attr('cx', d => dx).attr('cy', d => dy) );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM