我正在用D3js做這個專案,現在我遇到了一個問題。 當我有更多的資料時,我的 Barchart 的條形圖將正確地追加到與名稱相同的行中,但當我從資料庫中獲取更少的資料時,條形圖將 "失去控制 "并追加到比其名稱更高的位置,導致我的圖表出現糟糕的視圖。
這是一張如果我加載更多的資料就會出現的圖片。
這是我的第二張圖片,如果我加載更少的資料,就會有這樣的圖表。
我不太明白我在這里錯過了什么,但我相信是與Y軸的高度和柱子的Y位置有關。你能幫我解決這個問題嗎?
這是我的代碼。
下面是我的代碼:
var margin = { top: 20, right: 30, bottom: 40, left: 90 },
寬度 = 360 - margin.left - margin.right。
height = 300 - margin.top - margin.bottom;
//append the svg object to the body of the page。
var svg = d3.select("#my_dataviz"/span>)
.append("svg")
.attr("width", width margin.left margin.right)
.attr("height", height margin.top margin.bottom)
.append("g"/span>)
.attr("transform",
"translate(" margin.left "," margin.top ")")。)
//決議資料
var data2 = d3.json("/Events/BarChart/4") 。 then(function (data) {
console.log(資料)。
//添加X軸。
var x = d3.scaleLinear()
.domain([0, 5] )
.range([0, width] )。
svg.append("g"/span>)
.attr("transform", "translate(0," height ") ")
.call(d3.axisBottom(x))
.selectAll("text")
.attr("transform", "translate(-10,0)rotate(-45)")
.style("text-anchor","end")
;
//Y軸; //Y軸
var y = d3.scaleBand()
.range([0, height] )
.domain(資料。 map(function (d) { return d.name; })
svg.append("g"/span>)
.call(d3.axisLeft(y))
/Bars。
svg.selectAll("myRect"/span>)
.data(data)
.enter()
.append("rect"/span>)
.attr("x"/span>, 4)
. attr("y", function (d) { return y(d. name) 10; })
. attr("width", function (d) { return x(d。 value); })
.attr("height",20)
.attr("fill", function (d) {
if (d.value > 1) {
return "rgb(51,80,92)"。
}
else if (d.value > 1 && d. value < 4) {
return "rgb(118, 161, 179)"。
}
else {
return "rgb(171, 209, 224)"。
}
})
})
uj5u.com熱心網友回復:
問題的出現是因為你手動給每個矩形分配了一個20像素的高度,但是你給scale的范圍是0-240(height的值)。scale將把這個范圍分成相等的段(band),它的域中的每個值都有一個段。當你的域中只有兩個值時,它們將有每個120px的帶子(如果有填充物就會減少)。在任何地方,刻度尺都不 "知道 "你為每個條帶分配了20px的高度;畢竟,你告訴它要在0-240的范圍內均勻地分布數值。這些相互沖突的指令就是你的條形圖沒有與你的軸對齊的原因。
當使用 d3 標尺時,你會發現如果你將標尺用于軸和繪制資料本身(矩形/圓形/等)會更容易:這樣它們將始終保持對齊。
d3帶狀刻度提供了一個方便的方法。scale.bandwidth(),這將回傳刻度中一個帶的長度/寬度/高度:在最簡單的情況下(沒有填充),它是范圍的大小除以域中有多少不同的值。
var margin = { top: 20, right: 30, bottom: 40, left: 90 },
寬度 = 360 - margin.left - margin.right。
height = 300 - margin.top - margin.bottom;
//append the svg object to the body of the page。
var svg = d3.select("#my_dataviz"/span>)
.append("svg")
.attr("width", width margin.left margin.right)
.attr("height", height margin.top margin.bottom)
.append("g"/span>)
.attr("transform",
"translate(" margin.left "," margin.top ")")。)
var data = [
{name: "a"/span>, value: 1}。
{name: "b", value: 2}。
]
//增加X軸。
var x = d3.scaleLinear()
.domain([0, 5] )
.range([0, width] )。
svg.append("g"/span>)
.attr("transform", "translate(0," height ") ")
.call(d3.axisBottom(x))
.selectAll("text")
.attr("transform", "translate(-10,0)rotate(-45)")
.style("text-anchor","end")
;
//Y軸; //Y軸
var y = d3.scaleBand()
.range([0, height] )
.domain(資料。 map(function (d) { return d.name; })
svg.append("g"/span>)
.call(d3.axisLeft(y))
/Bars。
svg.selectAll("myRect"/span>)
.data(data)
.enter()
.append("rect"/span>)
.attr("x"/span>, 4)
. attr("y", function (d) { return y(d. name); })
. attr("width", function (d) { return x(d。 value); })
.attr("height", y.bandwidth()
.attr("fill", function (d) {
if (d.value > 1) {
return "rgb(51,80,92)"。
}
else if (d.value > 1 && d. value < 4) {
return "rgb(118, 161, 179)"。
}
else {
return "rgb(171, 209, 224)"。
}
})
<script src="https://cdnjs. cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>/span>
<div id="my_dataviz"/span>> </div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" class="snippet-box-edit snippet-box-result" frameborder="0"></iframe>
我還注意到,你在每個條形圖的y值上增加了10個像素:這可能是為了在多個資料條目下更好地手動對齊條形圖。一般來說,這將導致問題(除非手動糾正):對于y/x和高度/寬度,scale(value)和scale.width()分別產生以軸刻度為中心的條。如果你想要padding(條形之間的空間),最簡單的方法是使用scale來設定它。scale.padding(number)其中number是一個介于0和1之間的值,代表每段的空部分:
var margin = { top: 20, right: 30, bottom: 40, left: 90 },
寬度 = 360 - margin.left - margin.right。
height = 300 - margin.top - margin.bottom;
//append the svg object to the body of the page。
var svg = d3.select("#my_dataviz"/span>)
.append("svg")
.attr("width", width margin.left margin.right)
.attr("height", height margin.top margin.bottom)
.append("g"/span>)
.attr("transform",
"translate(" margin.left "," margin.top ")")。)
var data = [
{name: "a"/span>, value: 1}。
{name: "b", value: 2}。
]
//增加X軸。
var x = d3.scaleLinear()
.domain([0, 5] )
.range([0, width] )。
svg.append("g"/span>)
.attr("transform", "translate(0," height ") ")
.call(d3.axisBottom(x))
.selectAll("text")
.attr("transform", "translate(-10,0)rotate(-45)")
.style("text-anchor","end")
;
//Y軸; //Y軸
var y = d3.scaleBand()
.range([0, height] )
.padding(0.1)
.domain(資料。 map(function (d) { return d.name; })
svg.append("g"/span>)
.call(d3.axisLeft(y))
/Bars。
svg.selectAll("myRect"/span>)
.data(data)
.enter()
.append("rect"/span>)
.attr("x"/span>, 4)
. attr("y", function (d) { return y(d. name); })
. attr("width", function (d) { return x(d。 value); })
.attr("height", y.bandwidth()
.attr("fill", function (d) {
if (d.value > 1) {
return "rgb(51,80,92)"。
}
else if (d.value > 1 && d. value < 4) {
return "rgb(118, 161, 179)"。
}
else {
return "rgb(171, 209, 224)"。
}
})
<script src="https://cdnjs. cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>/span>
<div id="my_dataviz"/span>> </div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" class="snippet-box-edit snippet-box-result" frameborder="0"></iframe>
但是,如果您不想要120px寬的分段呢?你希望你的條形圖始終是20左右的像素,不管你有多少條形圖。
var margin = { top: 20, right: 30, bottom: 40, left: 90 },
寬度 = 360 - margin.left - margin.right。
height = 300 - margin.top - margin.bottom;
//append the svg object to the body of the page。
var svg = d3.select("#my_dataviz"/span>)
.append("svg")
.attr("width", width margin.left margin.right)
.attr("height", height margin.top margin.bottom)
.append("g"/span>)
.attr("transform",
"translate(" margin.left "," margin.top ")")。)
var data = [
{name: "a"/span>, value: 1}。
{name: "b", value: 2}。
]
//增加X軸。
var x = d3.scaleLinear()
.domain([0, 5] )
.range([0, width] )。
svg.append("g"/span>)
.attr("transform", "translate(0," data. length*20 ")")
.call(d3.axisBottom(x))
.selectAll("text")
.attr("transform", "translate(-10,0)rotate(-45)")
.style("text-anchor","end")
;
//Y軸; //Y軸
var y = d3.scaleBand()
.domain(data. map(function (d) { return d.name; })
.range([0, data.length*20] )
.padding(0.1)。
svg.append("g"/span>)
.call(d3.axisLeft(y))
/Bars。
svg.selectAll("myRect"/span>)
.data(data)
.enter()
.append("rect"/span>)
.attr("x"/span>, 4)
. attr("y", function (d) { return y(d. name); })
. attr("width", function (d) { return x(d。 value); })
.attr("height", y.bandwidth()
.attr("fill", function (d) {
if (d.value > 1) {
return "rgb(51,80,92)"。
}
else if (d.value > 1 && d. value < 4) {
return "rgb(118, 161, 179)"。
}
else {
return "rgb(171, 209, 224)"。
}
})
<script src="https://cdnjs. cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>/span>
<div id="my_dataviz"/span>> </div>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" class="snippet-box-edit snippet-box-result" frameborder="0"></iframe>
我還更新了x軸的變換,你可以進一步調整svg的高度,使其有更好的尺寸
。轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/331500.html
標籤:


