我有一個svg/xml 檔案,我正在使用它加載到 d3d3.xml(...)
這是SVG的輸出
我還有一個小的 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
任何幫助將非常感激
uj5u.com熱心網友回復:
在您的小提琴中,您可以使用不同的 CSS 選擇器d3.select('#polygon5256')將事件添加到任何多邊形:selectAll
d3.selectAll("svg polygon")
您也想要path(對于門階),因此您需要的 CSS 選擇器是:
d3.selectAll("svg polygon, svg path")
在處理程式中,您可以獲得id多邊形的(因為您使用 d3 v5.9.2):
d3.event.target.id
請注意,如果您使用的是更高版本的 D3 庫,則需要更改此處理方式(請參閱D3 v6 更改)
我已將您的小提琴更改為有一個可見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>
編輯
如果您想將路徑/多邊形限制為僅在 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>
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/462631.html
