首先,我是D3.Js的新手。我花了大约一个星期左右的时间研究D3.JS问题 - 专门制作一个带有Y轴标签的图表。但是,我无法准确地获得图表。它几乎就在那里但反转或我的数据出错了。现在,在显示所有代码之前,我将简要展示一些我的主要问题的代码和图像。我花时间查看其他类似问题的Stack Overflow帖子,我在那些帖子上做了什么,但仍然有同样的问题。
例如,我认为这篇文章会有解决方案:reversed Y-axis 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或高度值,并花时间在那里乱搞没有结果。
答案 0 :(得分:2)
这不是D3问题,而是SVG功能:在SVG中,原点(0,0)位于左上角角落,而不是左下角,如同常见的笛卡儿平面。这就是为什么使用[0, h]
作为范围会使轴看起来倒置 ...实际上,它没有被反转:这是SVG中正确的方向。顺便说一句,HTML5 Canvas具有相同的坐标系统,使用画布你会遇到同样的问题。
因此,您必须翻转范围,而不是域名
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>
&#13;