javascript - D3.js 和 jQuery - 多个 map 点和点击事件

标签 javascript jquery json d3.js

我是 D3.js 的新人,我被要求接管工作中其他人启动的一个项目。

目标是拥有一个可以提取点的 json 数据的 map ,然后当单击这些点时,会弹出一个 jQuery 对话框,其中包含每个点的正确 json 数据。

我已经能够让 jQuery 弹出窗口在 map 上工作,但是单击的每个点都填充了完全相同的文本。

我还测试了使用 $.getJSON 在简单的 html 页面中加载和显示 json 数据,并且我能够让它很好地循环遍历所有 json 数据。

下面是创建点的函数:

function addCirclesForArray(element,index,array) {
  var coordinates = 
  projection([element.sendLocation.longitude,element.sendLocation.latitude]);
    g.append("circle")
     .attr("cx",coordinates[0])
     .attr("cy",coordinates[1])
     .attr("r",(index<array.length-1)?2:4)
     .attr("r",4)
     .style("fill",$colorScale(d3.round(element.profileReadings[0].psal))) 
     .attr("class","circle")
     g.selectAll("circle")
    .on("click",circleClicked) 
}

这是我循环遍历 jQuery 弹出窗口的 json 数据的方法:

function circleClicked(data, i) {       
    console.log(data) // undefined
    console.log(i); // index #
    $.getJSON("data/oc-readings3.json", function(data){ 
        $.each(data, function(key, value){
          //populate jQuery dialog
          $('#floatID').text("Float ID: "+value.platformNumber);
          $('#latitude').text("Latitude: "+value.sendLocation.latitude);
          $('#longitude').text("Longitude: "+value.sendLocation.longitude);

          // jQuery UI dialog and tabs
          $( "#tabs" ).tabs();
          $( "#dialog" ).dialog({ width: 400 })     

        });                 
    });                 
}

我可能在 getJSON 方法中缺少一些简单的循环,或者可能与未定义的数据有关。如果您有任何提示,请告诉我。谢谢。

更新/解决方案 我意识到我不需要使用 $.getJSON 因为我已经在 addCirclesForArray 方法中获取了 json 数据。我可以只使用传入的数组参数中的索引。

我还摆脱了circleClicked方法并将新逻辑添加到addCirclesForArray方法中。

g.selectAll("circle")   
  .on("mouseover", increaseSize)
  .on("mouseout", decreaseSize)  
  .on("click", function(d,i) {
   //console.log(array[i]); 
     //jQuery popup
     $( "#tabs" ).tabs();
     $( "#dialog" ).dialog({ 
        width: 418,
        resizable: false
      });        
     //populate tabs
     $('#floatID').text("Float ID: "+array[i].platformNumber);
     // etc.

最佳答案

当您使用 d3 的 selection.on(type, callback) 绑定(bind)(点击鼠标悬停等)处理程序时,您的回调函数被调用时,其上下文(“this”)绑定(bind)到被单击的 DOM 节点,并将元素的数据作为其第一个参数。 为了使其工作,您需要首先将数据绑定(bind)到 D3 创建的 DOM/SVG 节点。

我建议使用声明性数据绑定(bind),而不是循环访问数据元素。 D3 的创建者 Mike Bostock 提供了 a general overview on declarative binding in d3 (“连接”),以及 thorough, technical explanation .

对于对话框,基本思想是仅定义一个对话框/弹出窗口/工具提示,该对话框最初是隐藏的,并为每个单击的节点重用。通过回调函数,您可以将对话框中的占位符字段替换为数据对象中的实际值。

您的示例可能会修改为如下所示:

var containerElement = $('#container'),
    svg = d3.select(containerElement).append('svg')
             /* .attr('width', ...).attr('height',...)*/;

// jQuery UI dialog and tabs
$( "#tabs" ).tabs();
$( "#dialog" ).dialog({ width: 400 });

$.getJSON("data/oc-readings3.json", addCirclesForArray); 

/** called only once */
function addCirclesForArray(data) {
  var coordinates = [];
  $.each(data, function(key, value){
        coordinates.push(projection([value.sendLocation.longitude, value.sendLocation.latitude]));
  });

  // data join / declarative binding
  // caution: binding requires an array of array(s)!
  var groups = svg.selectAll('g').data([data]); 

  // exit
  groups.exit().remove();

  // enter
  groups.enter().append("svg:circle");

  // enter + update
  groups.attr("cx",coordinates[0])
      .attr("cy",coordinates[1])
      .attr("r", function(d,index) { 
          return (index<array.length-1)? 2: 4;
      })
      //.attr("r", 4) // duplicate assignment of r
      .style("fill", function(d) { 
          return $colorScale(d3.round(d.profileReadings[0].psal));
      }) 
      .attr("class","circle");
  groups.selectAll("circle")
      .on("click", circleClicked); // :TODO: bind circleClicked to your preferred context
}

/**
 * @param {arrayElement} data
 * @this {svg:circle} 
 */
function circleClicked(data) {
   var dialog = $('dialogPlaceholder');
   $('#floatID', dialog).text("Float ID: " + data.platformNumber);
   $('#latitude', dialog).text("Latitude: " + data.sendLocation.latitude);
   $('#longitude', dialog).text("Longitude: " + data.sendLocation.longitude);
}

关于javascript - D3.js 和 jQuery - 多个 map 点和点击事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23377633/

相关文章:

javascript - 将原始 json 转换为 d3 兼容数据集

javascript - crm 2011 如何使用 javascript 隐藏/显示功能区按钮

javascript - 获取表的 thead 标签内输入的 IDS

javascript - HTML 5音频播放器剩余时间显示延迟

jquery - 什么是处理网站上字体大小调整的好方法

jquery - Ajax 调用在 ios 中立即失败,文本状态为 : error and HTTP status 0 on Cordova,

javascript - Jquery .first 行为

javascript - Node —— Node 类型错误 : options must be an object

python - 将平面制表符分隔文件转换为 Json 嵌套结构

javascript - 在 jQuery 中迭代 json 对象数组