Svg 更改D3中三角形的高度和方向

Svg 更改D3中三角形的高度和方向,svg,d3.js,Svg,D3.js,我有一个红色和绿色三角形的基本条形图。红色三角形表示数据的负数比较,绿色三角形表示数据为正数。绿色三角形应始终指向上方,红色三角形应始终指向下方,如果数据为中性,则应显示圆圈。我无法将箭头/三角形与底部对齐(触摸x轴),也无法根据条件将箭头旋转为指向上或向下。这是我的密码 svg.selectAll("line.arrow") .data(input.filter(function (d) { return d.AverageValue})) .enter().append("l

我有一个红色和绿色三角形的基本条形图。红色三角形表示数据的负数比较,绿色三角形表示数据为正数。绿色三角形应始终指向上方,红色三角形应始终指向下方,如果数据为中性,则应显示圆圈。我无法将箭头/三角形与底部对齐(触摸x轴),也无法根据条件将箭头旋转为指向上或向下。这是我的密码

svg.selectAll("line.arrow")
    .data(input.filter(function (d) { return d.AverageValue}))
    .enter().append("line")
    .attr("class", "arrow")
    .attr("x1", function (d) {
        return xScale(d.AppName) + xScale.rangeBand() / 2;
    })
    .attr("x2", function (d) {
        return xScale(d.AppName) + xScale.rangeBand() / 2;
    })
    .attr("y1", function (d) {
        return yScale(20);//bring arrows to bottom
    })
    .attr("y2", function (d) {
        var getValue = d.AverageValue;
        if (getValue >= 0) {
            return yScale(10)-37;
        } else {
            return yScale(23) - 6;
        }
    }) 
    .attr("marker-end", function (d) {
        var getValue = d.ComparedToPreviousMonth;
        if (getValue < 0) {
            return "url(#redArrow)";
        } else if (getValue > 0) {
            return "url(#greenArrow)";
        }
    });
svg.selectAll(“line.arrow”)
.data(input.filter(函数(d){返回d.AverageValue}))
.enter().append(“行”)
.attr(“类”、“箭头”)
.attr(“x1”,函数(d){
返回xScale(d.AppName)+xScale.rangeBand()/2;
})
.attr(“x2”,函数(d){
返回xScale(d.AppName)+xScale.rangeBand()/2;
})
.attr(“y1”,函数(d){
返回yScale(20);//将箭头带到底部
})
.attr(“y2”,功能(d){
var getValue=d.平均值;
如果(getValue>=0){
返回yScale(10)-37;
}否则{
返回yScale(23)-6;
}
}) 
.attr(“标记结束”,功能(d){
var getValue=d.ComparedToPreviousMonth;
如果(getValue<0){
返回“url(#redArrow)”;
}否则如果(getValue>0){
返回“url(#绿色箭头)”;
}
});
整个代码都乱七八糟 这是我的建议。我已经

  • 拆分绿色和红色箭头,以便它们可以进行单独的变换

  • 将标记向下平移到条的底部

  • 使标记溢出可见,以便在转换数据后仍显示标记

                            // add text and arrow
                            svg.selectAll("line.arrow")
                                .data(["red"])
                                .enter()
                              .append("defs").append("marker")
                                .attr("id", function (d) {
    
                                    return d + "Arrow";
    
                                })
                                .attr("viewBox", "0 -5 10 10")
                                .attr("refX", 8)
                                .attr("markerWidth", 12)
                                .attr("markerHeight", 20)
                                .attr("orient", "auto")
                                .attr("overflow", "visible")
                              .append("svg:path")
                                .attr("d", "M0,-5L10,0L0,5")
                                .attr("transform", "rotate(90, 5, 0)  translate(56, 0)")
                                .attr("class", function (d) {
                                    return "marker_" + d;
    
                                });
    
                            svg.selectAll("line.arrow")
                                .data(["green"])
                                .enter()
                              .append("defs").append("marker")
                                .attr("id", function (d) {
    
                                    return d + "Arrow";
    
                                })
                                .attr("viewBox", "0 -5 10 10")
                                .attr("refX", 8)
                                .attr("markerWidth", 12)
                                .attr("markerHeight", 20)
                                .attr("orient", "auto")
                                .attr("overflow", "visible")
                              .append("svg:path")
                                .attr("d", "M0,-5L10,0L0,5")
                                .attr("transform", "rotate(270, 5, 0) translate(-56, 0)")
                                .attr("class", function (d) {
                                    return "marker_" + d;
    
                                });
    

查看生成的svg输出,您会注意到用于设置标记的线是几何点而不是线,即
x1
equals
x2
y1
equals
y2

<line class="arrow" x1="33.5" x2="33.5" y1="296" y2="296" marker-end="url(#redArrow)"></line>
对于纯粹主义者,
y2
生成器甚至可以缩短为:

.attr("y2", function (d) {
    return d.ComparedToPreviousMonth < 0 ? h - .001 : h + .001;
}) 

请参阅更新的。

@user4895544:尽管这可能会起作用,但它似乎是一种绕过根本问题的解决方法。我已经发布了另一个你可能也会觉得有用的帖子。谢谢你的回答。我想这对我很有帮助,一旦我将它与动态数据集成,从而避免了解决方法。还有一个问题。需要为列AverageOrganizationValue(在整个数组中为常量)绘制一条水平线。你有什么可以推荐的例子吗?我更新了。请考虑把这个问题或其他问题放在另一个问题上。谢谢。这就是我要找的。修复了使用lil调整的三角形问题。
.attr("y2", function (d) {
    return d.ComparedToPreviousMonth < 0 ? h - .001 : h + .001;
}) 
.attr("refX", function(d) {
    return d == "red" ? 0 : 10;
})