[英]D3.JS Y-axis label issue
首先,我是D3.Js的新手。 過去一周左右,我一直在研究D3.JS問題,尤其是制作帶有Y軸標簽的圖形。 但是,我無法獲得所需的圖形。 快到了,但是倒掛了,或者我的數據出了錯。 現在,在顯示所有代碼之前,我將簡要展示一些代碼和主要問題的圖像。 我花了很多時間看其他有類似問題的Stack Overflow帖子,我做了這些帖子上的內容,但仍然有同樣的問題。
例如,我認為該帖子將提供解決方案: Y軸反轉D3
數據如下:
[0,20,3,8](實際上是一個對象數組,但是我認為這可能就是所需要的。
因此,首先,當yScale如下所示時:
var yScale = d3.scaleLinear()
.domain([0, maxPound]) //Value of maxpound is 20
.range([0, 350]);
可以看到,Y圖表的頂部從零開始,底部從20開始,起初我認為這是將域中的值翻轉到此的簡單解決方案:
var yScale = d3.scaleLinear()
.domain([0, maxPound]) //Value of maxpound is 20
.range([0, 350]);
我得到這張圖片:
在第二個圖像中,y軸是右20,位於頂部。 但是圖表是錯誤的。 現在,0將返回350像素的值,即SVG元素的高度。 那就是20應該返回的值! 如果嘗試切換圖像范圍值,則會遇到同樣的問題!
現在的代碼:
var w = 350;
var h = 350;
var barPadding = 1;
var margin = {top: 5, right: 200, bottom: 70, left: 25}
var maxPound = d3.max(poundDataArray,
function(d) {return parseInt(d.Pounds)}
);
//Y-Axis Code
var yScale = d3.scaleLinear()
.domain([maxPound, 0])
.range([0, h]);
var yAxis = d3.axisLeft()
.scale(yScale)
.ticks(5);
//Creating SVG element
var svg = d3.select(".pounds")
.append('svg')
.attr("width", w)
.attr('height', h)
.append("g")
.attr("transform", "translate(" + margin.left + "," +
margin.top + ")");
svg.selectAll("rect")
.data(poundDataArray)
.enter()
.append("rect")
.attr('x', function(d, i){
return i * (w / poundDataArray.length);
})
.attr('y', function(d) {
return 350 - yScale(d.Pounds);
})
.attr('width', (w / 4) - 25)
.attr('height', function(d){
return yScale(d.Pounds);
})
.attr('fill', 'steelblue');
//Create Y axis
svg.append("g")
.attr("class", "axis")
.call(yAxis);
感謝您的任何幫助! 我認為錯誤可能出在y或height值上,並花了很多時間在那里弄亂了結果。
這不是一個D3的問題,而是一個SVG功能:在SVG,原點(0,0)是在左上角 ,而不是左下角,作為普通的笛卡爾平面。 這就是為什么使用[0, h]
作為范圍會使軸看起來像是反轉的 ...實際上,它不是反轉的:這是SVG中正確的方向。 順便說一句,HTML5 Canvas具有相同的坐標系,並且使用Canvas也會遇到相同的問題。
因此,您必須翻轉range而不是domain:
var yScale = d3.scaleLinear()
.domain([0, maxPound])
.range([h, 0]);//the range goes from the bottom to the top now
或者,在您的情況下,使用邊距:
var yScale = d3.scaleLinear()
.domain([0, maxPound])
.range([h - margin.bottom, margin.top]);
除此之外,y位置和高度的數學運算是錯誤的。 它應該是:
.attr('y', function(d) {
return yScale(d.Pounds);
})
.attr('height', function(d) {
return h - margin.bottom - yScale(d.Pounds);
})
另外,請注意,請勿硬編碼x的位置和寬度。 請改用帶刻度。
這是您所做的更改的代碼:
var poundDataArray = [{ Pounds: 10 }, { Pounds: 20 }, { Pounds: 5 }, { Pounds: 8 }, { Pounds: 14 }, { Pounds: 1 }, { Pounds: 12 }]; var w = 350; var h = 350; var barPadding = 1; var margin = { top: 5, right: 20, bottom: 70, left: 25 } var maxPound = d3.max(poundDataArray, function(d) { return parseInt(d.Pounds) } ); //Y-Axis Code var yScale = d3.scaleLinear() .domain([0, maxPound]) .range([h - margin.bottom, margin.top]); var xScale = d3.scaleBand() .domain(d3.range(poundDataArray.length)) .range([margin.left, w - margin.right]) .padding(.2); var yAxis = d3.axisLeft() .scale(yScale) .ticks(5); //Creating SVG element var svg = d3.select("body") .append('svg') .attr("width", w) .attr('height', h) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); svg.selectAll("rect") .data(poundDataArray) .enter() .append("rect") .attr('x', function(d, i) { return xScale(i); }) .attr('y', function(d) { return yScale(d.Pounds); }) .attr('width', xScale.bandwidth()) .attr('height', function(d) { return h - margin.bottom - yScale(d.Pounds); }) .attr('fill', 'steelblue'); //Create Y axis svg.append("g") .attr("class", "axis") .attr("transform", "translate(" + margin.left + ",0)") .call(yAxis);
<script src="https://d3js.org/d3.v4.min.js"></script>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.