gpt4 book ai didi

javascript - 将 Dynamic Attr() 添加到 d3.tip

转载 作者:行者123 更新时间:2023-11-30 20:11:01 24 4
gpt4 key购买 nike

问题:

我正在尝试将带有数据集第一个索引的 data-data 属性添加到我的每个工具提示中,因为它们是由代码生成的,但我终生做不到我想出了如何根据数据集动态设置它。

例如,我想实现等价于此:

const tip = d3.tip()
.attr('data-date', d => d[0])
//...

这是一个代码片段:

//need to fix tooltip data-date attr.. don't know how I'll do that yet though

const endpoint =
"https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/GDP-data.json";

d3.json(endpoint).then(data => {
const gc = d3.select(document.getElementById("graph-container")),
dataset = data.data,
canvasWidth = 900,
canvasHeight = 477,
padding = 50,
years = dataset.map(s => s[0].slice(0, 4)),
xScale = d3
.scaleLinear()
.domain([0, dataset.length])
.range([padding, canvasWidth - padding]),
yScale = d3
.scaleLinear()
.domain([0, d3.max(dataset, d => d[1])])
.range([padding, canvasHeight - padding]),
tip = d3 //making a tooltip
.tip()
.attr("id", "tooltip")
.direction("e")
.offset([0, 25])
.html(
d =>
`${d[0].slice(0, 4)} Q${
d[0].slice(5, 7) === "01"
? "1"
: d[0].slice(5, 7) === "04"
? "2"
: d[0].slice(5, 7) === "07"
? "3"
: d[0].slice(5, 7) === "10" ? "4" : null
}<br />$${d[1]} Billion`
),
xAxis = d3
.axisBottom(
d3
.scaleLinear()
.domain([d3.min(years), d3.max(years)])
.range([padding, canvasWidth - padding])
)
.tickFormat(d3.format("d")),
yAxis = d3.axisLeft(
d3
.scaleLinear()
.domain([0, d3.max(dataset, d => d[1])])
.range([canvasHeight - padding, padding])
); //not sure how to make this work without redefining the range. point is, however, it works... so... take that

gc //making the title element
.append("div")
.attr("id", "title")
.text("National Income and Product Accounts of the United States (NIPA)");

gc //making the graph
.append("svg")
.attr("id", "canvas")
.attr("width", canvasWidth)
.attr("height", canvasHeight)
.call(tip)
.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("class", "bar")
.style('fill', (d, i) => d[1] <= dataset[i === 0 ? 0 : i - 1][1] ? '#f92727' : '#00cc58')
.attr("x", (d, i) => xScale(i))
.attr("y", d => canvasHeight - yScale(d[1]))
.attr("width", canvasWidth / dataset.length)
.attr("height", d => yScale(d[1]) - padding)
.attr("data-date", d => d[0])
.attr("data-gdp", d => d[1])
.on("mouseover", tip.show)
.on("mouseout", tip.hide);

d3 //add x-axis
.select(document.getElementById("canvas"))
.append("g")
.attr("id", "x-axis")
.attr("transform", `translate(0, ${canvasHeight - padding})`)
.call(xAxis);

d3 //add y-axis
.select(document.getElementById("canvas"))
.append("g")
.attr("id", "y-axis")
.attr("transform", `translate(${padding}, 0)`)
.call(yAxis);
});
@import url('https://fonts.googleapis.com/css?family=Lato');

* {
overflow: hidden;
font-family: 'Lato';
}

html, body {
padding: 0;
margin: 0;
}

#container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
background-image: linear-gradient(to bottom right, white, #ffffe6);
}

#graph-container {
box-shadow: 2px 2px 10px 1px gray;
height: 550px;
width: 950px;
border-radius: 5px;
background-color: white;
display: flex;
flex-direction: column;
align-items: center;
}

#title {
text-align: center;
padding-top: 15px;
font-size: 20px;
width: 100%;
padding-bottom: 15px;
box-shadow: 0 0 5px 0 gray;
}

#canvas {
background-color: transparent;
margin-top: 15px;
}

.bar:hover {
fill: yellow;
}

#tooltip {
background-color: orange;
padding: 15px;
border-radius: 5px;
min-width: 100px;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.9.1/d3-tip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="container">
<div id="graph-container"></div>
</div>

我已经尝试将数据集附加到 tip 变量并在 .attr 上传递它,但不幸的是数据集只能通过 .html 传递 没有中断。

我已经尝试移动 .call 以获取提示以传递数据,但这也不起作用。

我必须使用 .attr 并且不能通过将属性附加到生成的 div/span/etc 来在 html 中伪造它。

有人有什么想法吗?

最佳答案

d3-tip 是一个非常独立的实体,所以如果你想这样做,你基本上必须破解它;没有通过官方 API 完成此操作的好方法。在 html 函数期间,您可以操作 tip DOM 元素并使用当前数据项向其添加属性:

            .html(
d => {
// slightly horrible hack
d3.select('#tooltip').attr('data-date', d[0]);
return `${d[0].slice(0, 4)} Q${
d[0].slice(5, 7) === "01"
? "1"
: d[0].slice(5, 7) === "04"
? "2"
: d[0].slice(5, 7) === "07"
? "3"
: d[0].slice(5, 7) === "10" ? "4" : null
}<br />$${d[1]} Billion`
}),

集成到整个代码中:

//need to fix tooltip data-date attr.. don't know how I'll do that yet though

const endpoint =
"https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/GDP-data.json";

d3.json(endpoint).then(data => {
const gc = d3.select(document.getElementById("graph-container")),
dataset = data.data,
canvasWidth = 900,
canvasHeight = 477,
padding = 50,
years = dataset.map(s => s[0].slice(0, 4)),
xScale = d3
.scaleLinear()
.domain([0, dataset.length])
.range([padding, canvasWidth - padding]),
yScale = d3
.scaleLinear()
.domain([0, d3.max(dataset, d => d[1])])
.range([padding, canvasHeight - padding]),
tip = d3 //making a tooltip
.tip()
.attr("id", "tooltip")
.direction("e")
.offset([0, 25])
.html(
d => {
d3.select('#tooltip').attr('data-date', d[0]);
return `${d[0].slice(0, 4)} Q${
d[0].slice(5, 7) === "01"
? "1"
: d[0].slice(5, 7) === "04"
? "2"
: d[0].slice(5, 7) === "07"
? "3"
: d[0].slice(5, 7) === "10" ? "4" : null
}<br />$${d[1]} Billion`
}),
xAxis = d3
.axisBottom(
d3
.scaleLinear()
.domain([d3.min(years), d3.max(years)])
.range([padding, canvasWidth - padding])
)
.tickFormat(d3.format("d")),
yAxis = d3.axisLeft(
d3
.scaleLinear()
.domain([0, d3.max(dataset, d => d[1])])
.range([canvasHeight - padding, padding])
); //not sure how to make this work without redefining the range. point is, however, it works... so... take that

gc //making the title element
.append("div")
.attr("id", "title")
.text("National Income and Product Accounts of the United States (NIPA)");

gc //making the graph
.append("svg")
.attr("id", "canvas")
.attr("width", canvasWidth)
.attr("height", canvasHeight)
.call(tip)
.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("class", "bar")
.style('fill', (d, i) => d[1] <= dataset[i === 0 ? 0 : i - 1][1] ? '#f92727' : '#00cc58')
.attr("x", (d, i) => xScale(i))
.attr("y", d => canvasHeight - yScale(d[1]))
.attr("width", canvasWidth / dataset.length)
.attr("height", d => yScale(d[1]) - padding)
.attr("data-date", d => d[0])
.attr("data-gdp", d => d[1])
.on("mouseover", tip.show)
.on("mouseout", tip.hide);

d3 //add x-axis
.select(document.getElementById("canvas"))
.append("g")
.attr("id", "x-axis")
.attr("transform", `translate(0, ${canvasHeight - padding})`)
.call(xAxis);

d3 //add y-axis
.select(document.getElementById("canvas"))
.append("g")
.attr("id", "y-axis")
.attr("transform", `translate(${padding}, 0)`)
.call(yAxis);
});
@import url('https://fonts.googleapis.com/css?family=Lato');

* {
overflow: hidden;
font-family: 'Lato';
}

html, body {
padding: 0;
margin: 0;
}

#container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
background-image: linear-gradient(to bottom right, white, #ffffe6);
}

#graph-container {
box-shadow: 2px 2px 10px 1px gray;
height: 550px;
width: 950px;
border-radius: 5px;
background-color: white;
display: flex;
flex-direction: column;
align-items: center;
}

#title {
text-align: center;
padding-top: 15px;
font-size: 20px;
width: 100%;
padding-bottom: 15px;
box-shadow: 0 0 5px 0 gray;
}

#canvas {
background-color: transparent;
margin-top: 15px;
}

.bar:hover {
fill: yellow;
}

#tooltip {
background-color: orange;
padding: 15px;
border-radius: 5px;
min-width: 100px;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.9.1/d3-tip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="container">
<div id="graph-container"></div>
</div>

关于javascript - 将 Dynamic Attr() 添加到 d3.tip,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52416779/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com