我創建了一個可滾動的熱圖,我想讓 x 軸在滾動 y 軸時固定。我在這里查看了一些帖子并嘗試使解決方案起作用,例如位置固定,但沒有成功。
編輯:我試圖用這個例子來解決這個問題Fix x-axis position in scrollable Heatmap d3 但現在我的 x 軸描述消失了,x 軸被放置在底部。
var width = 500,
height = 600,
margintop = 50,
marginbottom = 50,
marginright = 10,
marginleft = 50
d3.csv("https://raw.githubusercontent.com/Lea1216/d3/main/heatmap.csv", function(data) {
var svg = d3.select("#my_dataviz")
.append("div")
.classed("chart",true)
.append("svg")
.attr("width",width marginleft marginright)
.attr("height",height margintop marginbottom)
.append("g")
.attr("transform",
"translate(" marginleft "," margintop ")");
var axis = d3.select("#my_dataviz")
.append("svg")
.attr("width", width marginleft marginright)
.attr("height",40)
.append("g")
.attr("transform", "translate(" marginleft ", 0)");
var x_axis = d3.scaleBand()
.range([0, width])
.domain(data.map(function(d) {
return d.group;
}))
.padding(0.01);
axis.call(d3.axisTop(x_axis))
.selectAll("text")
.style("text-anchor", "end")
.style("position","fixed")
.attr("dx",15)
.attr("dy",5)
.attr("transform", "rotate(-65)");
var y_axis = d3.scaleBand()
.range([height, 0])
.domain(data.map(function(d) {
return d.activity;
}))
.padding(0.01);
svg.append("g")
.call(d3.axisLeft(y_axis))
.attr("class", "y_axis")
.selectAll("text")
.on("click", function(d) {
window.open(d.url, "_blank")
});
var myColor = d3.scaleLinear()
.range(["white", "#C37B89"])
.domain([1, 100])
svg.selectAll()
.data(data, function(d) {
return d.group ':' d.activity;
})
.enter()
.append("rect")
.attr("x", function(d) {
return x_axis(d.group)
})
.attr("y", function(d) {
return y_axis(d.activity)
})
.attr("width", x_axis.bandwidth())
.attr("height", y_axis.bandwidth())
.style("fill", function(d) {
return myColor(d.value)
})
.style("stroke-width", 1)
.style("stroke", "none")
})
.rect {
opacity: 0.8;
}
#my_dataviz {
width: 600px;
height: 500px;
overflow-y: scroll;
padding: 50px;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="my_dataviz"></div>
uj5u.com熱心網友回復:
對此有幾種可能的解決方案。第一種是在同一層繪制兩個SVG元素,并position: fixed在X軸元素上使用。您可以看到這些塊仍然顯示在軸的后面,但是您可以通過繪制rect軸 SVG 元素的總大小并給出它來解決這個問題fill: white:
var width = 500,
height = 600,
margintop = 50,
marginbottom = 50,
marginright = 10,
marginleft = 50
d3.csv("https://raw.githubusercontent.com/Lea1216/d3/main/heatmap.csv", function(data) {
// Add the axis *before* adding the SVG, because the order matters in HTML
var axis = d3.select("#my_dataviz")
.append("svg")
.attr("width", width marginleft marginright)
// Add 2 so you have a little bit of room left for the black bar
// i.e. margin top has to be less than total height!
.attr("height", margintop 2)
.style("position", "fixed") // this makes the axis fixed
.append("g")
.attr("transform", "translate(" marginleft ", " margintop ")");
var svg = d3.select("#my_dataviz")
.append("svg")
.attr("width", width marginleft marginright)
.attr("height", height margintop marginbottom)
.append("g")
.attr("transform", "translate(" marginleft ", " margintop ")");
var x_axis = d3.scaleBand()
.range([0, width])
.domain(data.map(function(d) {
return d.group;
}))
.padding(0.01);
axis.call(d3.axisTop(x_axis))
.selectAll("text")
.style("text-anchor", "end")
.style("position", "fixed")
.attr("dx", 15)
.attr("dy", 5)
.attr("transform", "rotate(-65)");
var y_axis = d3.scaleBand()
.range([height, 0])
.domain(data.map(function(d) {
return d.activity;
}))
.padding(0.01);
svg.append("g")
.call(d3.axisLeft(y_axis))
.attr("class", "y_axis")
.selectAll("text")
.on("click", function(d) {
window.open(d.url, "_blank")
});
var myColor = d3.scaleLinear()
.range(["white", "#C37B89"])
.domain([1, 100])
svg.selectAll()
.data(data, function(d) {
return d.group ':' d.activity;
})
.enter()
.append("rect")
.attr("x", function(d) {
return x_axis(d.group)
})
.attr("y", function(d) {
return y_axis(d.activity)
})
.attr("width", x_axis.bandwidth())
.attr("height", y_axis.bandwidth())
.style("fill", function(d) {
return myColor(d.value)
})
.style("stroke-width", 1)
.style("stroke", "none")
})
.rect {
opacity: 0.8;
}
#my_dataviz {
border: solid 1px red;
width: 600px;
height: 300px;
overflow-y: scroll;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="my_dataviz"></div>
第二個選項是將另一個 SVG 放在 a 中div并滾動div而不是 SVG。然后,您確實需要對 CSS 執行更多操作,并且需要將一些 CSS 規則從#my_dataviz元素移動到.chart元素:
var width = 500,
height = 600,
margintop = 50,
marginbottom = 50,
marginright = 10,
marginleft = 50
d3.csv("https://raw.githubusercontent.com/Lea1216/d3/main/heatmap.csv", function(data) {
// Add the axis *before* adding the SVG, because the order matters in HTML
var axis = d3.select("#my_dataviz")
.append("svg")
.attr("width", width marginleft marginright)
// Add 2 so you have a little bit of room left for the black bar
// i.e. margin top has to be less than total height!
.attr("height", margintop 1)
.append("g")
.attr("transform", "translate(" marginleft ", " margintop ")");
var svg = d3.select("#my_dataviz")
.append("div")
// Note the CSS rules for .chart
.attr("class", "chart")
.append("svg")
.attr("width", width marginleft marginright)
// No margin-top required here, because the other element already took care of it
.attr("height", height marginbottom)
.append("g")
// Same, no margin-top
.attr("transform", "translate(" marginleft ", 0)");
var x_axis = d3.scaleBand()
.range([0, width])
.domain(data.map(function(d) {
return d.group;
}))
.padding(0.01);
axis.call(d3.axisTop(x_axis))
.selectAll("text")
.style("text-anchor", "end")
.style("position", "fixed")
.attr("dx", 15)
.attr("dy", 5)
.attr("transform", "rotate(-65)");
var y_axis = d3.scaleBand()
.range([height, 0])
.domain(data.map(function(d) {
return d.activity;
}))
.padding(0.01);
svg.append("g")
.call(d3.axisLeft(y_axis))
.attr("class", "y_axis")
.selectAll("text")
.on("click", function(d) {
window.open(d.url, "_blank")
});
var myColor = d3.scaleLinear()
.range(["white", "#C37B89"])
.domain([1, 100])
svg.selectAll()
.data(data, function(d) {
return d.group ':' d.activity;
})
.enter()
.append("rect")
.attr("x", function(d) {
return x_axis(d.group)
})
.attr("y", function(d) {
return y_axis(d.activity)
})
.attr("width", x_axis.bandwidth())
.attr("height", y_axis.bandwidth())
.style("fill", function(d) {
return myColor(d.value)
})
.style("stroke-width", 1)
.style("stroke", "none")
})
.rect {
opacity: 0.8;
}
#my_dataviz {
width: 600px;
border: solid 1px red;
}
/* To make sure there is no space between the DIV and the SVG */
#my_dataviz > * {
display: block;
}
.chart {
overflow-y: scroll;
max-height: 300px;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="my_dataviz"></div>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/371161.html
標籤:javascript d3.js
