Javascript d3.js v4条形图,y轴为负值
我在d3.js中使用了相当多的图表,这些图表在x轴上有负值,但我看到很少有在y轴上有负值的示例,并且没有一个能够正常工作 我正在尝试创建一个图表,其中日期在x轴上,相应的值在y轴上 我尝试通过操纵下面链接中的代码来实现这一点: 我的代码如下:Javascript d3.js v4条形图,y轴为负值,javascript,d3.js,svg,charts,Javascript,D3.js,Svg,Charts,我在d3.js中使用了相当多的图表,这些图表在x轴上有负值,但我看到很少有在y轴上有负值的示例,并且没有一个能够正常工作 我正在尝试创建一个图表,其中日期在x轴上,相应的值在y轴上 我尝试通过操纵下面链接中的代码来实现这一点: 我的代码如下: var margin2 = { top: 20, right: 20, bottom: 40, left: 30 }; var height2 = 650 - margin2.top - margin2.bottom; var width2 = 900
var margin2 = { top: 20, right: 20, bottom: 40, left: 30 };
var height2 = 650 - margin2.top - margin2.bottom;
var width2 = 900 - margin2.left - margin2.right;
// Add svg to
var svg = d3.select('#macdChart').
append('svg').
attr('width', width2 + margin2.left + margin2.right).
attr('height', height2 + margin2.top + margin2.bottom).
append('g').
attr('transform', 'translate(' + margin2.left + ',' + margin2.top + ')');
//title
svg.append("text")
.attr("x", (width2 / 2))
.attr("y", 0 - (margin2.top / 3))
.attr("text-anchor", "middle")
.style("font-size", "16px")
.style("text-decoration", "underline")
.text("Title");
// X scale
var x2 = d3.scaleBand().
range([width2, 0])
.padding(0.1);
//y scale
var y2 = d3.scaleLinear()
.range([height2, 0]);
var xAxis = d3.axisBottom(x2);
var yAxis = d3.axisLeft(y2).
tickSize(6, 0);
// text label for the x axis
svg.append("text")
.attr("transform", "translate(" + (width2 / 2) + " ," + (height2 + margin2.top + 20) + ")")
.style("text-anchor", "middle")
.text("X Label");
function render(data) {
data.forEach(function (d) {
d.Macd = +d.Macd;
d.MacdSignal = +d.MacdSignal;
d.MacdHistogram = +d.MacdHistogram;
});
x2.domain(data.map(function (d) { return d["date"]; }));
y2.domain(d3.extent(data, function (d) { return d["MacdHistogram"]; })).nice();
svg.selectAll('.bar').
data(data).
enter().append('rect').
attr('class', function (d) {
return "bar bar--" + (d["MacdHistogram"] < 0 ? "negative" : "positive");
}).
attr('x', function (d) { return x2(d["date"]); }).
attr('y', function (d) { return y2(Math.min(0, d["MacdHistogram"])); }).
attr('height', function (d) { return Math.abs(y2(d["MacdHistogram"]) - y2(0)); }).
attr('width', x2.bandwidth());
svg.append('g').
attr('class', 'y axis').
attr('transform', 'translate(' + width2 + ',0)').
call(yAxis);
var tickNegative = svg.append('g').
attr('class', 'x axis').
attr('transform', 'translate(0,' + y2(0) + ')').
call(xAxis).
selectAll('.tick').
filter(function (d, i) { return data[i].value < 0; });
}
致:
我得到的图表下面的条形图值显示正确,但负数在顶部,正数在底部(正如您在我的y轴标签上看到的):
有人能建议如何让图表看起来准确,现在它只是翻转了一下,所以负片在底部吗?在
y
位置使用Math.max
,而不是Math.min
:
.attr('y', function (d) {
return y2(Math.max(0, d["MacdHistogram"]))
});
原因是,无论范围的方向如何,SVG矩形始终(除非您弄乱了变换)的宽度从左到右增长,高度从上到下增长
下面是一个使用虚假数据进行更改的演示:
var margin2={
前20名,
右:20,,
底数:20,
左:20
};
var height2=400-margin2.top-margin2.bottom;
var width2=500-边缘2.左-边缘2.右;
//将svg添加到
var svg=d3。选择('body')。
追加('svg')。
属性('width',width2+margin2.left+margin2.right)。
属性('height',height2+margin2.top+margin2.bottom)。
附加('g')。
attr('transform','translate('+margin2.left+','+margin2.top+'));
//头衔
svg.append(“文本”)
.attr(“x”,(宽度2/2))
.attr(“y”,0-(margin2.top/3))
.attr(“文本锚定”、“中间”)
.style(“字体大小”、“16px”)
.style(“文本装饰”、“下划线”)
.文本(“标题”);
//X刻度
var x2=d3.scaleBand()。
范围([width2,0])
.填充(0.1);
//y刻度
变量y2=d3.scaleLinear()
.范围([height2,0]);
var xAxis=d3.轴底(x2);
var yAxis=d3。轴左(y2)。
尺寸(6,0);
//x轴的文本标签
svg.append(“文本”)
.attr(“变换”、“平移”(+(宽度2/2)+),“+(高度2+margin2.top+20)+”)
.style(“文本锚定”、“中间”)
.文本(“X标签”);
函数渲染(数据){
x2.域(数据)映射(函数(d){
返回d[“日期”];
}));
y2.域(d3.范围(数据、函数(d)){
返回d[“MacdHistogram”];
})).nice();
svg.selectAll('.bar')。
数据(数据)。
enter().append('rect')。
属性('类',函数(d){
返回“条形图--”+(d[“MacdHistogram”]<0?“负”:“正”);
}).
属性('x',函数(d){
返回x2(d[“日期]);
}).
属性('y',函数(d){
返回y2(数学最大值(0,d[“MacdHistogram”));
}).
属性(高度),功能(d){
返回Math.abs(y2(d[“MacdHistogram”])-y2(0));
}).
attr('width',x2.bandwidth());
append('g')。
属性(“类”,“y轴”)。
attr('transform','translate('+width2+',0')。
呼叫(yAxis);
var tickNegative=svg.append('g')。
属性(“类”,“x轴”)。
attr('transform','translate(0',+y2(0)+'))。
调用(xAxis)。
选择全部('.tick')。
过滤器(功能(d,i){
返回数据[i]。值<0;
});
}
风险值数据=[{
日期:1,
MacdHistogram:1
}, {
日期:二〇〇四年四月二日,
MacdHistogram:-2
}, {
日期:2007年3月3日,
MacdHistogram:8
}, {
日期:2007年4月4日,
MacdHistogram:3
}, {
日期:5,,
MacdHistogram:12
}, {
日期:6,
MacdHistogram:-5
}, {
日期:2007年7月7日,
MacdHistogram:1
}, {
日期:2007年8月8日,
MacdHistogram:9
}, {
日期:2007年9月9日,
MacdHistogram:-1
}, {
日期:10,,
MacdHistogram:10
}, {
日期:2007年11月11日,
MacdHistogram:7
}, {
日期:12,
MacdHistogram:-8
}, {
日期:2008年12月13日,
MacdHistogram:7
}, {
日期:2004年12月14日,
MacdHistogram:-4
}, {
日期:2004年12月15日,
MacdHistogram:1
}];
渲染(数据)
太好了!我很欣赏你对为什么这样做的清晰解释。d3.js无疑是一条学习曲线,我正在等待d3.js《行动》第二版的出版[。你还有其他参考建议吗?我发现很多例子,但解释较少。根据你的水平(对于初学者),斯科特·默里的书非常好:
var y2 = d3.scaleLinear()
.range([0, height2]);
.attr('y', function (d) {
return y2(Math.max(0, d["MacdHistogram"]))
});