【问题标题】:Plotting Name of States on Map using Node js and D3 in real time使用 Node js 和 D3 在地图上实时绘制状态名称
【发布时间】:2016-09-04 15:23:32
【问题描述】:

我一直在尝试使用 Redis Pub/Sub 系统、Node js 和 D3 在地图上绘制州名。 问题是当我第一次在 Redis 通道上输入一个状态时,它被完美地绘制,但是当我输入第二个状态时,什么也没有发生。由于我是 D3.js 的新手,因此无法找出问题所在。 任何帮助将不胜感激。谢谢。

d3.json("india-states.json", function (json) {
    india.selectAll("path")
    .data(json.features)
    .enter().append("path")
    .attr("d", path);
    var socket = io();
    socket.on('tags', function(data){
        console.log(data.message1);
        india.selectAll("text")
        .data(json.features)
        .enter()
        .append("text")
        .attr("fill", "black")
        .attr("transform", function(d) {
            console.log(data.message1 + "Second Time"); 
            var centroid = path.centroid(d);
            return "translate(" + centroid[0] + "," + centroid[1] + ")"
        })
        .attr("text-anchor", "middle")
        .attr("dy", ".35em")
        .style('fill', 'white')
        .text(function(d) {
            console.log("2");
            if (d.id == data.message1) {
                console.log("1");    
                return data.message1;
            }
        });
    });
});

我尝试探索我的代码,发现它每次都能正确获取状态名称。但只有在第一次尝试时,州名才会在

console.log(data.message1);

在所有其他情况下,我只得到一个控制台输出,即“console.log(data.message1);”

【问题讨论】:

    标签: javascript node.js d3.js redis


    【解决方案1】:

    为文本创建一个变量并将其移到socket之外:

    d3.json("india-states.json", function (json) {
    india.selectAll("path")
      .data(json.features)
      .enter().append("path")
      .attr("d", path);
    
    var stateText = india.selectAll(".text")
      .data(json.features)
      .enter()
      .append("text");//variable outside socket
    
    var socket = io();
    
    socket.on('tags', function(data){
    
        stateText.attr("fill", "black")
          .attr("transform", function(d) {
            console.log(data.message1 + "Second Time"); 
            var centroid = path.centroid(d);
            return "translate(" + centroid[0] + "," + centroid[1] + ")"
          })
          .attr("text-anchor", "middle")
          .attr("dy", ".35em")
          .style('fill', 'white')
          .text(function(d) {
            if (d.id == data.message1) {   
                return data.message1;
              }
          });
      });
    });
    

    如果你想跟踪你之前的message1,你可以在函数外创建一个数组,然后循环遍历它:

    d3.json("india-states.json", function (json) {
    india.selectAll("path")
      .data(json.features)
      .enter().append("path")
      .attr("d", path);
    
    var stateText = india.selectAll(".text")
      .data(json.features)
      .enter()
      .append("text");
    
    var arrayStates = [];//this array will hold all the names
    
    var socket = io();
    
    socket.on('tags', function(data){
    
        arrayStates.push(data.message1);//for each input, a new string
    
        stateText.attr("fill", "black")
        .attr("transform", function(d) {
            var centroid = path.centroid(d);
            return "translate(" + centroid[0] + "," + centroid[1] + ")"
        })
        .attr("text-anchor", "middle")
        .attr("dy", ".35em")
        .style('fill', 'white')
        .text(function(d) {
            for(var i = 0; i < arrayStates.length; i++){
              if (d.id == arrayStates[i]) {   
                return arrayStates[i];
              }
            }
         });
      });
    });
    

    【讨论】:

    • console.log 给出了我在频道上发布的相同状态名称。但问题是第一次一切正常。每当我输入第二个状态时,只有 sockets.on() 开头的第一个 console.log 有效,并且在控制台中看不到其他输出。所以这意味着数据无法第二次通过。我还没有尝试为“文本”创建变量,很快就会这样做。
    • 你为什么有style("fill", "white")
    • 只是想改变文本的颜色:-P
    • 嘿,我尝试了您在套接字块外声明变量的代码,它成功了!!!谢谢 :D 现在唯一剩下的是,每当我输入一个州的名称时,之前标记的州名就会消失,并显示新的州名。如何保持地图之前的状态不变?
    • 这是意料之中的,因为您的“消息”只有一种状态。您必须创建一个累积数据,然后创建一个 for 循环来匹配所有 ID。我将编辑答案并向您展示如何操作。
    猜你喜欢
    • 2015-01-13
    • 1970-01-01
    • 2020-09-09
    • 2014-01-26
    • 2015-09-06
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    相关资源
    最近更新 更多