2014-04-30 100 views
0

我是D3.js的新手,我被要求接管其他人在工作中开始的项目。D3.js和jQuery - 多个地图点和点击事件

目标是有一个地图,为点拉入json数据,然后当点击点时,jQuery对话框会弹出每个点都有正确的json数据。

我已经能够让jQuery弹出窗口在地图上工作,但是每一个被点击的点都使用完全相同的文本填充。

我还测试了使用$ .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方法中使用循环,或者它可能与未定义的数据有关。如果您有任何提示,请告诉我。谢谢。

UPDATE /解决方案 我意识到,我并不需要使用$ .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. 
+0

你在哪里数据绑定的社交圈吗? – FernOfTheAndes

+0

感谢您的回复。我只将数据绑定到jQuery对话框的html,而不是圆圈。也许这是我的问题? – NeilS

+0

我会这么认为,因为您从圆圈的上下文中调用了click事件,但没有绑定到它们的数据......在侦听器开始时未定义数据的原因。 – FernOfTheAndes

回答

0

当你使用D3的selection.on(类型,回调)绑定(点击鼠标悬停等)的处理程序,您的回调函数被调用它的上下文( “本”)约束到被点击的DOM节点,以及元素的数据作为它的第一个参数。 为了使其发挥作用,您需要先将数据绑定到D3创建的DOM/SVG节点。

我推荐使用声明性数据绑定,而不是循环遍历数据元素。 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); 
} 
+0

感谢您的代码重写,解释和链接。现在地图并没有填充点,弹出窗口也不能正常工作,所以我会像FernOfTheAndes所建议的那样完成一个完整的工作,因为你们只看到了我的部分代码。 – NeilS