d3路径梯度行程

时间:2013-12-20 15:12:14

标签: javascript d3.js

您好我正在使用d3对角线图,并希望在路径上添加渐变来链接我的圈子......

我正在生成我的树:

            var width = 800,
                height = 700;

            element.html('');
            var color = d3.interpolateLab("#008000", "#c83a22");
            var scale = d3.scale.linear().domain([0, 100]).range(["red", "green"]);
            var cluster = d3.layout.cluster()
                .size([height, width - 160]);

            var diagonal = d3.svg.diagonal()
                .projection(function(d) { return [d.y, d.x]; });

            var svg = d3.select('#tab-manageAccess').append('svg')
                .attr('width', width)
                .attr('height', height)
                .append('g')
                .attr('transform', 'translate(40,0)');


            /*svg.append("linearGradient")
                .attr("id", "line-gradient")
                .attr("gradientUnits", "userSpaceOnUse")
                .attr("x1", 0).attr("y1", y(0))
                .attr("x2", 0).attr("y2", y(1000))
                .selectAll("stop")
                .data([
                    {offset: "0%", color: "red"},
                    {offset: "40%", color: "red"},
                    {offset: "40%", color: "black"},
                    {offset: "62%", color: "black"},
                    {offset: "62%", color: "lawngreen"},
                    {offset: "100%", color: "lawngreen"}
                ])
                .enter().append("stop")
                .attr("offset", function(d) { return d.offset; })
                .attr("stop-color", function(d) { return d.color; });*/

            var nodes = cluster.nodes(scope.accessTree),
                links = cluster.links(nodes);

            var link = svg.selectAll('.link')
                .data(links)
                .enter().append('path')
                .attr('class', 'link')
                .attr('d', diagonal);

            var node = svg.selectAll('.node')
                .data(nodes)
                .enter().append('g')
                .attr('class', 'node')
                .attr('transform', function(d) { return 'translate(' + d.y + ',' + d.x + ')'; });

            node.append('circle')
                .attr('r', 4.5);

            node.append('text')
                .attr('dx', function(d) { return d.children ? -8 : 8; })
                .attr('dy', 3)
                .style('text-anchor', function(d) { return d.children ? 'end' : 'start'; })
                .style('font-weight', 'bold')
                .attr('fill', function (d) {
                    var color = '#4D7B88';
                    if (d.depth === 0) {
                        color = '#7F3762';
                    } else if(d.depth === 1) {
                        color = '#83913D';
                    }

                    return color;
                })
                .text(function(d) { return d.name; });

            d3.select(self.frameElement).style('height', height + 'px');

我找到了这个示例:https://gist.github.com/mbostock/4163057我使用d3.interpolateLab("#008000", "#c83a22");创建了变量颜色,然后将.style("fill", function(d) { return color(d.t); }) .style("stroke", function(d) { return color(d.t); })添加到路径元素,但它不起作用:(任何人都可以帮助我吗?

1 个答案:

答案 0 :(得分:5)

Mike Bostock的代码中缺少的是他将路径划分为数百个不同的子路径并分别设置每个路径的颜色。转到http://bl.ocks.org/mbostock/4163057的实时版本并检查DOM以查看实际情况。

为什么他这样做?因为,虽然您可以将SVG线或路径的笔划设置为渐变,但您无法告诉它使渐变遵循该线的斜率或曲线。根据以下任一项创建渐变时定义渐变的角度:

  • 使用它的元素的矩形边界框
    (如果gradientUnits设置为ObjectBoundingBox),或

  • 绘制对象的用户坐标系
    (如果gradientUnits设置为userSpaceOnUse)。

您设置的方式(在注释掉的代码中)基本上会在整个图像上创建隐藏的渐变背景,然后让它显示在您绘制线条的任何位置。显然不是你想要的。

因此,迈克的复杂功能和它创造的数百个子路径。可能也不是你想要的,特别是如果你想让图形成为交互式的。

对于简单的线条,还有另一种方法可以使渐变从线的开始到结束正确排列 我在这里有一个非常简单的SVG(没有D3)的例子:http://codepen.io/AmeliaBR/pen/rFtGs

简而言之,您必须将线条定义为与渐变匹配的方向,然后使用变换(缩放/旋转/平移)将线条实际定位在您想要的位置。

在D3中实现的难度取决于布局的复杂程度。如果您只是使用简单的线条,我认为这样可行:

  • 使用(x1,y1)和(x2,y2)值中的简单几何计算线的长度及其斜率

  • 从(0,0)到(0,长度)画线(假设是垂直渐变),

  • 添加translate(x1,y1) rotate(slope)

  • 的转换属性

使用路径,您需要知道要处理的路径类型,并使用正则表达式来解析和编辑路径的d属性。非常凌乱。

也许只是尝试开始和结束的行标记?