【发布时间】:2016-12-28 22:21:52
【问题描述】:
我使用 d3js (v4),我想填充由多个路径定义的特定区域。
这是我的形状:
这是我的代码:
var width = 400,
height = 350;
var svg = d3.select('#svgContainer')
.append('svg')
.attr('width', width)
.attr('height', height)
.style('background-color', 'white');
var shape = {
leftEdge: [],
topCurve: [],
supportJunction: [],
bottomCurve: [],
centralSupport: [],
width: 0
};
/* Set path data */
var startX = 200,
startY = 80,
centralSupportW = 10,
centralSupportH = 25;
shape.centralSupport.push({
x: startX - centralSupportW,
y: startY - centralSupportH
});
shape.centralSupport.push({
x: startX + centralSupportW,
y: startY - centralSupportH
});
shape.centralSupport.push({
x: startX + centralSupportW,
y: startY + centralSupportH
});
shape.centralSupport.push({
x: startX - centralSupportW,
y: startY + centralSupportH
});
var shapeW = 80,
shapeH = 60,
curve = 40,
intensity = 6;
shape.leftEdge.push({
x: startX - shapeW + curve,
y: startY + shapeH,
id: 1
});
shape.leftEdge.push({
x: startX - shapeW + curve / intensity,
y: startY + shapeH,
id: 2
});
shape.leftEdge.push({
x: startX - shapeW,
y: startY,
id: 3
});
shape.leftEdge.push({
x: startX - shapeW + curve / intensity,
y: startY - shapeH,
id: 4
});
shape.leftEdge.push({
x: startX - shapeW + curve,
y: startY - shapeH,
id: 5
});
var topCurveIntensity = 10;
var centralPosition = 5;
shape.topCurve.push({
x: shape.leftEdge[shape.leftEdge.length - 1].x,
y: shape.leftEdge[shape.leftEdge.length - 1].y,
id: 6
});
shape.topCurve.push({
x: shape.leftEdge[shape.leftEdge.length - 1].x - topCurveIntensity,
y: shape.centralSupport[0].y + centralPosition,
id: 7
});
shape.topCurve.push({
x: shape.centralSupport[0].x,
y: shape.centralSupport[0].y + centralPosition,
id: 8
});
shape.supportJunction.push({
x: shape.centralSupport[0].x,
y: shape.centralSupport[0].y + centralPosition,
id: 9
});
shape.supportJunction.push({
x: shape.centralSupport[shape.centralSupport.length - 1].x,
y: shape.centralSupport[shape.centralSupport.length - 1].y - centralPosition,
id: 10
});
shape.bottomCurve.push({
x: shape.centralSupport[shape.centralSupport.length - 1].x,
y: shape.centralSupport[shape.centralSupport.length - 1].y - centralPosition,
id: 11
});
shape.bottomCurve.push({
x: shape.leftEdge[0].x - topCurveIntensity,
y: shape.centralSupport[shape.centralSupport.length - 1].y - centralPosition,
id: 12
});
shape.bottomCurve.push({
x: shape.leftEdge[0].x,
y: shape.leftEdge[0].y,
id: 13
});
/* */
/* draw paths */
var regularLine = d3.line()
.x(function(d) {
return d.x;
})
.y(function(d) {
return d.y;
});
var curvedLine = d3.line()
.curve(d3.curveBundle)
.x(function(d) {
return d.x;
})
.y(function(d) {
return d.y;
});
var closedLine = d3.line()
.curve(d3.curveLinearClosed)
.x(function(d) {
return d.x;
})
.y(function(d) {
return d.y;
});
/*
svg.append('path')
.datum(shape.centralSupport)
.attr('d', closedLine)
.style('fill', 'none')
.style('stroke', 'black')
.style('stroke-width', '3px');
*/
svg.append('path')
.datum(shape.leftEdge)
.attr('d', curvedLine)
.style('fill', 'none')
.style('stroke', '#A0A3A5')
.style('stroke-width', '3px');
svg.append('path')
.datum(shape.topCurve)
.attr('d', curvedLine)
.style('fill', 'none')
.style('stroke', '#A0A3A5')
.style('stroke-width', '3px');
svg.append('path')
.datum(shape.bottomCurve)
.attr('d', curvedLine)
.style('fill', 'none')
.style('stroke', '#A0A3A5')
.style('stroke-width', '3px');
svg.append('path')
.datum(shape.supportJunction)
.attr('d', regularLine)
.style('fill', 'none')
.style('stroke', '#A0A3A5')
.style('stroke-width', '3px');
var data = '';
svg.selectAll('path')
.each(function() {
data += d3.select(this).attr('d');
});
svg.append('path')
.attr('d', data)
.style('fill', 'lightgray')
.style('stroke', 'black')
.style('stroke-width', '1px')
.style('fill-rule', 'evenodd');
/* */
/* draw points used */
svg.selectAll('circles')
.data(shape.leftEdge)
.enter()
.append('circle')
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('r', 3)
.style('fill', 'black');
svg.selectAll('circles')
.data(shape.topCurve)
.enter()
.append('circle')
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('r', 3)
.style('fill', 'blue');
svg.selectAll('circles')
.data(shape.bottomCurve)
.enter()
.append('circle')
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('r', 3)
.style('fill', 'red');
/* */
/* draw labels */
svg.selectAll('circles')
.data(shape.leftEdge)
.enter()
.append('text')
.attr('x', function(d) {
return d.x - 16;
})
.attr('y', function(d) {
return d.y + 10;
})
.attr('dy', 1)
.text(function(d) {
return d.id;
});
svg.selectAll('circles')
.data(shape.topCurve)
.enter()
.append('text')
.attr('x', function(d) {
return d.x;
})
.attr('y', function(d) {
return d.y - 8;
})
.attr('dy', 1)
.text(function(d) {
return d.id;
})
.style('fill', 'blue');
svg.selectAll('circles')
.data(shape.supportJunction)
.enter()
.append('text')
.attr('x', function(d) {
return d.x + 16;
})
.attr('y', function(d) {
return d.y - 8;
})
.attr('dy', 1)
.text(function(d) {
return d.id;
})
.style('fill', 'purple');
svg.selectAll('circles')
.data(shape.bottomCurve)
.enter()
.append('text')
.attr('x', function(d) {
return d.x - 16;
})
.attr('y', function(d) {
return d.y - 8;
})
.attr('dy', 1)
.text(function(d) {
return d.id;
})
.style('fill', 'red');
/* */
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="svgContainer"></div>
注意:这个 sn-p 使用一些随机值来生成形状(以反映我真正需要的)。
每条路径都由一组坐标定义。他们每个人都使用不同的曲线或直线。
这是单个路径的代码:
g.append('path')
.datum(foobar)
.attr('d', d3.line()
.curve(d3.curveBundle)
.x(function (d) { return d.x; })
.y(function (d) { return d.y; }))
.style('fill', 'none')
.style('stroke', 'purple')
.style('stroke-width', '3px');
我尝试连接每个路径的数据,但填充没有正确完成:
var data = '';
svg.selectAll('path')
.each(function () { data += d3.select(this).attr('d'); });
svg.append('path')
.attr('d', data)
.style('fill', 'red')
.style('stroke', 'black')
.style('stroke-width', '3px');
在所有用于绘制路径的点的形状下方(每条路径一种颜色)。其中一些在路径之间共享(1 13、5 6、8 9、10 11)
您知道如何填充这些路径的包含(即内部部分)吗?
【问题讨论】:
-
您需要将路径的 d 属性连接到单个路径中。
-
如果您需要更多帮助,请创建 minimal reproducible example。
-
@RobertLongson 对,我创建了一个 JSFiddle 来重现问题:jsfiddle.net/ev4821c6/3