D3 将 XML 多边形 ID 映射到 JSON 数据
D3 Map XML Polygon ids to JSON data
我有一个 svg/xml file 正在使用 d3.xml(...)
加载到 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(多边形和路径)。您知道我如何将可选择的 paths/polygons 限制为仅 JSON 数据中的那些吗?所以只有可用的ID会受到鼠标事件的影响?
这是我的jsfiddle
如有任何帮助,我们将不胜感激
在您的 fiddle 中您有 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 changes)
我已将您的 fiddle 更改为具有单个可见 div
,其中鼠标悬停和鼠标移出处理程序仅填充标签(如果在 data
中可用)或清除文本。
工作示例:
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");
const svgUrl = "https://raw.githubusercontent.com/gangrel11/samplefiles/main/house.svg";
d3.xml(svgUrl).then(render);
// on render set an event for any polygon of the svg
function render(data) {
d3.select("body").node().append(data.documentElement)
d3.selectAll("svg polygon, svg path")
.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>
编辑
如果你想将 paths/polygons 限制为仅 JSON 数据中的那些,你可以换掉这个:
function render(data) {
d3.select("body").node().append(data.documentElement)
d3.selectAll("svg polygon, svg path")
.on("mouseover", mouseover)
.on("mouseout", mouseout);
}
为此(注意 render
的函数签名必须更改,因为我们在函数中引用 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)
);
}
工作示例:
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>
我有一个 svg/xml file 正在使用 d3.xml(...)
这是 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(多边形和路径)。您知道我如何将可选择的 paths/polygons 限制为仅 JSON 数据中的那些吗?所以只有可用的ID会受到鼠标事件的影响?
这是我的jsfiddle
如有任何帮助,我们将不胜感激
在您的 fiddle 中您有 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 changes)
我已将您的 fiddle 更改为具有单个可见 div
,其中鼠标悬停和鼠标移出处理程序仅填充标签(如果在 data
中可用)或清除文本。
工作示例:
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");
const svgUrl = "https://raw.githubusercontent.com/gangrel11/samplefiles/main/house.svg";
d3.xml(svgUrl).then(render);
// on render set an event for any polygon of the svg
function render(data) {
d3.select("body").node().append(data.documentElement)
d3.selectAll("svg polygon, svg path")
.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>
编辑
如果你想将 paths/polygons 限制为仅 JSON 数据中的那些,你可以换掉这个:
function render(data) {
d3.select("body").node().append(data.documentElement)
d3.selectAll("svg polygon, svg path")
.on("mouseover", mouseover)
.on("mouseout", mouseout);
}
为此(注意 render
的函数签名必须更改,因为我们在函数中引用 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)
);
}
工作示例:
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>