d3.js D3将XML多边形IDMap到JSON数据

iszxjhcz  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(155)

我使用d3.xml(...)将一个svg/xml file加载到d3中
这是SVG的output
我还有一个小的JSON数据集

const data = [{
    "id": "polygon5256", //roof
    "value": 39.5
  },
  {
    "id": "polygon1628",  //grass
    "value": 3.93
  },
  {
    "id": "polygon5254", //left wall
    "value": 3.14
  },
  {
    "id": "path5894", //door step
    "value": 20.98
  }
]

我正在尝试将JSON数据集中的ID与XML数据中的相应ID(多边形和路径)连接起来。您知道我还可以如何将可选择的路径/多边形限制为JSON数据中的那些吗?因此,只有可用的ID会受到鼠标事件的影响?
这是我的jsfiddle
任何帮助都将不胜感激

hlswsv35

hlswsv351#

在你的小提琴中,你有d3.select('#polygon5256'),但是你可以用selectAll和一个不同的CSS选择器向任何多边形添加事件:

d3.selectAll("svg polygon")

您也需要path(用于门阶),因此需要的CSS选择器为:

d3.selectAll("svg polygon, svg path")

在处理程序中,您可以通过以下方式获取多边形的id(因为您使用的是d3 v5.9.2):

d3.event.target.id
  • 请注意,如果您使用的是更高版本的D3库,则需要更改此处理方式(请参阅D3 v6更改)*

我已经改变了你的fiddle有一个单一的可见div,其中mouseover和mouseout处理程序只是填充标签(如果在data中可用)或清除文本。
工作示例:
第一个

编辑

如果您想将路径/多边形限制为JSON数据中的路径/多边形,您可以换出以下内容:

function render(data) {

  d3.select("body").node().append(data.documentElement)
  d3.selectAll("svg polygon, svg path")
    .on("mouseover", mouseover)
    .on("mouseout", mouseout);
    
}

为此(请注意,当我们在函数中引用data数组时,render的函数签名必须更改):

function render(svg) {

  // add svg
  d3.select("body").node().append(svg.documentElement)
  
  // add events for ids  
  const ids = data.map(d => d.id);
  ids.forEach(id => d3.select(`#${id}`)
    .on("mouseover", mouseover)
    .on("mouseout", mouseout)
  );
  
}

工作示例:

const data = [
  { "id": "polygon5256", "value": 39.5 }, // roof
  { "id": "polygon1628", "value": 3.93 }, // grass
  { "id": "polygon5254", "value": 3.14 }, // left wall
  { "id": "path5894", "value": 20.98 } // door step
];

// just make one visible div and leave text till later
const tooltip = d3.select("body")
  .append("div")
  .style("position", "absolute")
  .style("z-index", "10")
  .style("visibility", "visible");

// load external svg and render
const svgUrl = "https://raw.githubusercontent.com/gangrel11/samplefiles/main/house.svg";
d3.xml(svgUrl).then(render);

// on render set an event for anything with an id within data
function render(svg) {

  // add svg
  d3.select("body").node().append(svg.documentElement)
  
  // add events for ids  
  const ids = data.map(d => d.id);
  ids.forEach(id => d3.select(`#${id}`)
    .on("mouseover", mouseover)
    .on("mouseout", mouseout)
  );
  
}

// set the text of the div if it's in the data set
function mouseover(d) {
  const id = d3.event.target.id;
  const obj = data.find(item => item.id === id);
  const text = obj ? `${id} - ${obj.value}` : "";
  tooltip.text(text);
  d3.select(`#${id}`).style("opacity", 0.5);
}

// clear the text of the div
function mouseout(d) {
  const id = d3.event.target.id;
  tooltip.text("");
  d3.select(`#${id}`).style("opacity", 1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

相关问题