Anonymous
D3 Tooltip является частью DOM, но не виден
Сообщение
Anonymous » 06 окт 2025, 21:42
Я пытаюсь добавить всплывающую подсказку в точки данных в линейной диаграмме D3. Я определил, что не мог добавить всплеск инструментов к «SVG» - это никогда не было видно. Я мог бы добавить всплеск инструментов к тегу HTML тела, но тогда, если у меня было несколько линейных диаграмм на моей странице, подсказка не была прикреплена к каждому конкретному графику. Я попытался добавить всплывающую подсказку к форме прослушивания и прямолинейной формы. Я вижу всплеск инструментов в DOM, но она не видно. Почему это не видно и как следует подключить подсказку?
Код: Выделить всё
var data = [ {'year':'2007', 'percent':'.05'}, {'year':'2008', 'percent':'.10'}, {'year':'2009', 'percent':'.15'}, {'year':'2010', 'percent':'.25'} ];
sendData(data);
function sendData(data) {
const width = 1140;
const height = 400;
const marginTop = 20;
const marginRight = 20;
const marginBottom = 50;
const marginLeft = 70;
//var data = [ {'year':'2007', 'percent':'.05'}, {'year':'2008', 'percent':'.10'}, {'year':'2009', 'percent':'.15'} ]
const x = d3.scaleUtc()
.domain([new Date("2007-01-01"), new Date("2023-01-01")])
.range([marginLeft, width - marginRight]); //same as .range([70,1120])
const y = d3.scaleLinear()
.domain([0, .5])
.range([height - marginBottom, marginTop]); //same as .range([350, 20])
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height);
svg.append("g")
.attr("transform", `translate(0,${height - marginBottom})`)
.call(d3.axisBottom(x)
.ticks(d3.utcYear.every(1))
);
svg.append("text")
.attr("class", "x label")
.attr("text-anchor", "end")
.attr("x", width/2)
.attr("y", height - 6)
.text("Year");
svg.append("text")
.attr("class", "y label")
.attr("text-anchor", "end")
.attr("x", -height/3)
.attr("y", 6)
.attr("dy", ".75em")
.attr("transform", "rotate(-90)")
.text("Percent");
svg.append("g")
.attr("transform", `translate(${marginLeft},0)`)
.call(d3.axisLeft(y));
var heightOfY = height-marginBottom;
var Xmin = 2007;
var Xmax = 2023;
var numTicks = Xmax - Xmin + 1; //have to count the 0 point, so add 1
var XmaxRange = width - marginRight;
var eachTickWidth = XmaxRange / numTicks;
let path=svg.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("d", d3.line()
.x(function(d) {
//return x(d.year)
var mine = ((d.year - Xmin)*eachTickWidth) + marginLeft;
//return x(d.year);
return(mine); console.log(d.year);
})
.y(function(d) {
return y(d.percent)
})
);
/*const tooltip = d3.select("svg") //doesn't appear
.append("div")
.attr("class", "tooltip");
*/
const circle = svg.append("circle")
.attr("r", 0)
.attr("fill","steelblue")
.style("stroke","white")
.attr("opacity", .70)
.style("pointer-events","none");
const listeningRect = svg.append("rect")
.datum(data)
.attr("width", width)
.attr("height", height);
const tooltip = listeningRect //will appear if attached to d3.select("body"), but won't be linked to a particular chart if there are multiple charts
.append("div")
.attr("class", "tooltip");
const dataToDate = d => new Date(d.year, 0, 1);
listeningRect.on("mousemove", function(event){
const [xCoord] = d3.pointer(event, this);
const bisectData = d3.bisector(d => dataToDate(d)).left;
const x0 = x.invert(xCoord);
const i = bisectData(data, x0, 1);
const d0 = data[i-1];
const d1 = data[i];
const d = d1 && (x0 - dataToDate(d0) > dataToDate(d1) - x0) ? d1 : d0;
const xPos = x(dataToDate(d));
const yPos = y(d.percent);
circle.attr("cx", xPos)
.attr("cy", yPos);
circle.transition()
.duration(50)
.attr("r", 5);
tooltip //is attached to listeningRect in the DOM
.style("display","block")
.style("left",`${xPos + 10}px`)
.style("top", `${yPos + 10}px`)
.html("[b]Year:[/b] " + d.year + "
[b]% with non-medial exemption: [/b] " + (d.percent*100) + "%");
//console.log({xCoord, x0, d0, d1, d: dataToDate(d), xPos});
});
listeningRect.on("mouseout", function(event){
tooltip
.style("display","none");
});
container.append(svg.node());
} //end function sendData< /code>
.x.label, .y.label {
font-weight: bold;
font-size: 1rem;
}
.x.label {
margin-left: -50%;
}
rect {
pointer-events: all;
fill-opacity: 0;
stroke-opacity: 0;
z-index: 1;
background-color: transparent;
}
.tooltip {
position: absolute;
padding: 10px;
background-color: steelblue;
color: white;
border: 1px solid white;
border-radius: 10px;
display: none;
opacity: .8;
z-index: 999;< /code>
Подробнее здесь:
https://stackoverflow.com/questions/797 ... ot-visible
1759776168
Anonymous
Я пытаюсь добавить всплывающую подсказку в точки данных в линейной диаграмме D3. Я определил, что не мог добавить всплеск инструментов к «SVG» - это никогда не было видно. Я мог бы добавить всплеск инструментов к тегу HTML тела, но тогда, если у меня было несколько линейных диаграмм на моей странице, подсказка не была прикреплена к каждому конкретному графику. Я попытался добавить всплывающую подсказку к форме прослушивания и прямолинейной формы. Я вижу всплеск инструментов в DOM, но она не видно. Почему это не видно и как следует подключить подсказку?[code]var data = [ {'year':'2007', 'percent':'.05'}, {'year':'2008', 'percent':'.10'}, {'year':'2009', 'percent':'.15'}, {'year':'2010', 'percent':'.25'} ]; sendData(data); function sendData(data) { const width = 1140; const height = 400; const marginTop = 20; const marginRight = 20; const marginBottom = 50; const marginLeft = 70; //var data = [ {'year':'2007', 'percent':'.05'}, {'year':'2008', 'percent':'.10'}, {'year':'2009', 'percent':'.15'} ] const x = d3.scaleUtc() .domain([new Date("2007-01-01"), new Date("2023-01-01")]) .range([marginLeft, width - marginRight]); //same as .range([70,1120]) const y = d3.scaleLinear() .domain([0, .5]) .range([height - marginBottom, marginTop]); //same as .range([350, 20]) const svg = d3.create("svg") .attr("width", width) .attr("height", height); svg.append("g") .attr("transform", `translate(0,${height - marginBottom})`) .call(d3.axisBottom(x) .ticks(d3.utcYear.every(1)) ); svg.append("text") .attr("class", "x label") .attr("text-anchor", "end") .attr("x", width/2) .attr("y", height - 6) .text("Year"); svg.append("text") .attr("class", "y label") .attr("text-anchor", "end") .attr("x", -height/3) .attr("y", 6) .attr("dy", ".75em") .attr("transform", "rotate(-90)") .text("Percent"); svg.append("g") .attr("transform", `translate(${marginLeft},0)`) .call(d3.axisLeft(y)); var heightOfY = height-marginBottom; var Xmin = 2007; var Xmax = 2023; var numTicks = Xmax - Xmin + 1; //have to count the 0 point, so add 1 var XmaxRange = width - marginRight; var eachTickWidth = XmaxRange / numTicks; let path=svg.append("path") .datum(data) .attr("fill", "none") .attr("stroke", "steelblue") .attr("stroke-width", 1.5) .attr("d", d3.line() .x(function(d) { //return x(d.year) var mine = ((d.year - Xmin)*eachTickWidth) + marginLeft; //return x(d.year); return(mine); console.log(d.year); }) .y(function(d) { return y(d.percent) }) ); /*const tooltip = d3.select("svg") //doesn't appear .append("div") .attr("class", "tooltip"); */ const circle = svg.append("circle") .attr("r", 0) .attr("fill","steelblue") .style("stroke","white") .attr("opacity", .70) .style("pointer-events","none"); const listeningRect = svg.append("rect") .datum(data) .attr("width", width) .attr("height", height); const tooltip = listeningRect //will appear if attached to d3.select("body"), but won't be linked to a particular chart if there are multiple charts .append("div") .attr("class", "tooltip"); const dataToDate = d => new Date(d.year, 0, 1); listeningRect.on("mousemove", function(event){ const [xCoord] = d3.pointer(event, this); const bisectData = d3.bisector(d => dataToDate(d)).left; const x0 = x.invert(xCoord); const i = bisectData(data, x0, 1); const d0 = data[i-1]; const d1 = data[i]; const d = d1 && (x0 - dataToDate(d0) > dataToDate(d1) - x0) ? d1 : d0; const xPos = x(dataToDate(d)); const yPos = y(d.percent); circle.attr("cx", xPos) .attr("cy", yPos); circle.transition() .duration(50) .attr("r", 5); tooltip //is attached to listeningRect in the DOM .style("display","block") .style("left",`${xPos + 10}px`) .style("top", `${yPos + 10}px`) .html("[b]Year:[/b] " + d.year + " [b]% with non-medial exemption: [/b] " + (d.percent*100) + "%"); //console.log({xCoord, x0, d0, d1, d: dataToDate(d), xPos}); }); listeningRect.on("mouseout", function(event){ tooltip .style("display","none"); }); container.append(svg.node()); } //end function sendData< /code> .x.label, .y.label { font-weight: bold; font-size: 1rem; } .x.label { margin-left: -50%; } rect { pointer-events: all; fill-opacity: 0; stroke-opacity: 0; z-index: 1; background-color: transparent; } .tooltip { position: absolute; padding: 10px; background-color: steelblue; color: white; border: 1px solid white; border-radius: 10px; display: none; opacity: .8; z-index: 999;< /code> [/code] Подробнее здесь: [url]https://stackoverflow.com/questions/79783868/d3-tooltip-is-part-of-the-dom-but-not-visible[/url]