這是在反應應用程式上,可能出了什么問題?每次都會附加一個新的 svg,而不是現有的更新...我不確定我應該添加哪些其他詳細資訊,我已經包含了您可能需要幫助我的所有資訊,如果有任何資訊,請告訴我否則我應該補充。謝謝你。

這是我的組件,我通過道具傳遞資料。
export const FourDirectionsTimeChart = ({data}) => {
useEffect(() => {
const width = document.getElementById("container").clientWidth;
const height = document.getElementById("container").clientHeight;
const R = (width height) / 8;
const CX = width / 2;
const CY = height / 2;
const smallR = R * 0.1;
const circleColor = "bisque";
const itemColor = "#3F4200";
let svg = d3.select("#container")
.append("svg")
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", `0 0 ${width} ${height}`)
let mainCircle = svg.append("circle")
.attr("fill", circleColor)
.attr("r", R)
.attr("cx", CX)
.attr("cy", CY);
let centerCircle = svg.append("circle")
.attr("fill", "white")
.attr("r", smallR)
.attr("cx", CX)
.attr("cy", CY);
const timePercentage = (time) => {
const percentage = (time * 100 / 23) / 100;
return percentage;
};
function timeToRadius(time) {
return (smallR timePercentage(time) * (R - smallR))
}
// Times concentric circles ---
for (let i = 0; i <= 23; i = 4) {
svg.append("circle")
.attr("fill", "none")
.attr("cx", CX)
.attr("cy", CY)
.attr("stroke-dasharray", "4 20")
.attr("stroke", "gray")
.attr("stroke-width", 1)
.attr("r", timeToRadius(i))
}
// Cardinal points ---
const textTime = 25;
const fontSize = R * 0.25;
svg.append("text")
.attr("dx", getPosition(0, textTime).x)
.attr("dy", getPosition(0, textTime).y)
.text("N")
.attr("fill", "black")
.attr("font-size", fontSize)
.attr("text-anchor", "middle")
.style("font-family", "serif")
svg.append("text")
.attr("dx", getPosition(180, textTime).x)
.attr("dy", getPosition(180, textTime).y)
.text("S")
.attr("fill", "black")
.attr("font-size", fontSize)
.attr("text-anchor", "middle")
.style("font-family", "serif")
.attr("alignment-baseline", "hanging")
svg.append("text")
.attr("dx", getPosition(-90, textTime).x)
.attr("dy", getPosition(-90, textTime).y)
.text("E")
.attr("fill", "black")
.attr("font-size", fontSize)
.attr("text-anchor", "start")
.attr("alignment-baseline", "middle")
.style("font-family", "serif");
svg.append("text")
.attr("dx", getPosition(90, textTime).x)
.attr("dy", getPosition(90, textTime).y)
.text("O")
.attr("fill", "black")
.attr("font-size", fontSize)
.attr("text-anchor", "end")
.attr("alignment-baseline", "middle")
.style("font-family", "serif")
// Ships positions ---
function getPosition(degrees, time) {
const getRadians = (degrees) => degrees * Math.PI / 180 Math.PI / 2;
let x = (smallR timePercentage(time) * (R - smallR)) * Math.cos(getRadians(degrees)) CX;
let y = (smallR timePercentage(time) * (R - smallR)) * Math.sin(getRadians(degrees)) * -1 CY;
return { x, y };
}
// Data mapping ---
let parsedData = [];
(() => {
data?.forEach((x) => {
parsedData.push({
id: x.Patente,
course: x.Rumbo,
speed: x.Velocidad,
time: new Date(x.Fecha_gps).getHours()
})
});
let position;
parsedData.map(d => {
position = getPosition(d.course, d.time);
svg.append("circle")
.attr("fill", () => {
if (d.speed == 0) return "brown";
else return "brown";
})
.attr("r", R * 0.015)
.attr("cx", position.x)
.attr("cy", position.y)
.attr("opacity", 0.4);
});
})();
}, [data]);
return (
<div id="container" style={{ width: '100%', height: '100%' }}></div>
)
}
uj5u.com熱心網友回復:
你認為這條線let svg = d3.select("#container").append("svg")有什么作用?它選擇具有 ID 的"container"元素并向其附加一個新的 SVG 元素。
您基本上可以做以下兩件事之一:
- 選擇并洗掉容器中所有現有的 SVG 元素,然后在更新時從頭開始繪制圖表:
d3.select("#container svg").remove(),然后d3.select("#container").append("svg"); - 將初始化(附加 svg、設定大小、繪制軸)邏輯與可能需要多次運行(更新值)的邏輯分開,并確保在更新時僅呼叫第二部分。這更復雜,但也更高效,尤其是在像 React 這樣已經是 DOM 密集型的生態系統中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/375818.html
