问题描述
您好我正在使用d3对角线图,并希望添加一个渐变到路径链接我的圈子...
我生成我的树与: / p>
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 (1000))
.selectAll(stop)
.data([
{offset:0%,color:red},
{offset: 40%,颜色:red},
{offset:40%,color:black},
{offset:62% b $ b {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('+ dy +','+ dx +')';
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 $ d
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');
我发现这个例子: co我创建了变量颜色与 d3.interpolateLab(#008000,#c83a22 );
然后添加 .style(fill,function(d){return color(dt);})
到路径元素,但它不工作:(任何人都可以帮助我?
.style函数(d){return color(dt);})
你缺少的Mike Bostock的代码方面是,他将路径分成几百条不同的子路径,并分别设置每一条路径的颜色。 ,然后检查DOM以了解实际发生的情况。 / p>
为什么会这样做?因为,虽然你可以设置SVG线或者一个渐变的路径的笔画,你不能告诉它让渐变遵循斜率或曲线。渐变的角度是在创建渐变时基于以下任一方式定义的:
-
元素的矩形边界框使用它
(如果gradientUnits
设置为ObjectBoundingBox
)或 -
绘制对象的用户坐标系
(如果gradientUnits
设置为userSpaceOnUse
)。
设置方式(在注释掉的代码中)基本上会在整个图像,然后让它显示通过任何地方绘制线条。显然不是你想要的。
因此,Mike的复杂函数和它创建的数百个子路径。也许不是你想要的,或者,特别是如果你想图表是互动的。
对于简单的行,还有另一种方法可以让渐变从行的开始到结束正确排列。
我有一个非常简单的例子,简单的SVG(无D3)在这里:
简而言之,您必须定义您的线在与渐变匹配的方向上移动,然后使用transforms(scale / rotate / translate)你想要的行。
在D3中实现的棘手之处取决于布局的复杂程度。如果你只是使用简单的行,我认为这将工作:
-
计算线的长度和其斜率使用简单(x1,y1)和(x2,y2)值绘制几何,
- 假设垂直梯度),
-
添加
translate(x1,y1)rotate c>
对于路径,您需要知道要处理的路径类型,表达式来解析和编辑路径的d属性。非常混乱。
也许只是尝试开始和结束的线标记?
Hello I am working with d3 diagonal diagram and would like to add a gradient to path which links my circles...
I am generating my tree with:
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');
I found this example: https://gist.github.com/mbostock/4163057 co I created variable color with d3.interpolateLab("#008000", "#c83a22");
and then added .style("fill", function(d) { return color(d.t); }) .style("stroke", function(d) { return color(d.t); })
to path element but it doesn't work :( can anyone help me?
The aspect of Mike Bostock's code that you're missing is where he divides the path up into hundreds of different sub-paths and sets the color on each one separately. Go to the live version at http://bl.ocks.org/mbostock/4163057 and check the DOM to see what's really going on.
Why does he do that? Because, while you can set the stroke of an SVG line or path to a gradient, you can't tell it to make the gradient follow the slope or curve of that line. The angle of the gradient is defined when the gradient is created, based on either:
the rectangular bounding box for the element that uses it
(ifgradientUnits
is set toObjectBoundingBox
), orthe user coordinate system where the object is drawn
(ifgradientUnits
is set touserSpaceOnUse
).
The way you have it set up (in your commented out code) basically creates a hidden gradient background over the entire image, and then lets it show through wherever you draw your lines. Clearly not what you wanted.
Hence, Mike's complex function and the hundreds of sub-paths it creates. Probably not what you want, either, especially if you want the graph to be interactive.
For simple lines, there is another way to get gradients to line up correctly from start to finish of your line.
I've got a very simple example with plain SVG (no D3) up here: http://codepen.io/AmeliaBR/pen/rFtGs
In short, you have to define your line to go in the direction that matches up with the gradient, and then use transforms (scale/rotate/translate) to actually position the line where you want it.
How tricky that would be to implement in D3 depends on how complex your layout is. If you were just using simple lines, I think this would work:
calculate the length of the line and its slope using simple geometry from the (x1,y1) and (x2,y2) values,
draw the line from (0,0) to (0,length) (assuming a vertical gradient),
add a transform attribute of
translate(x1,y1) rotate(slope)
With paths, you'd need to know what type of path you're dealing with and use regular expressions to parse and edit the path's d attribute. Very messy.
Maybe just try line markers for start and end?
这篇关于d3路径梯度行程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!