Javascript d3.js v4条形图,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

我在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 - 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"]))
});