d3.由ClipPath区域

时间:2017-01-05 07:52:09

标签: d3.js symbols clip-path d3.js-v4

仍然在提高我对D3的能力的过程中,我遇到了一个问题,我试图在带有边距的SVG元素中绘制可缩放的曲线(因此我需要一个clipPath矩形以避免该绘图侵入边距当缩放时)但是clipPath边距会从图中删除d3.symbols的显示。

这是情节的相关代码

var margin = {top: 20, right: 60, bottom: 30, left: 30},
    w = 960 - margin.left - margin.right,
    h = 500 - margin.top - margin.bottom;

var svg = d3.select("body").append("svg")
                .attr("width", w + margin.left + margin.right)
            .attr("height", h + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg.append("defs").append("clipPath")
        .attr("id", "clip")
    .append("rect")
        .attr("width", w)
        .attr("height", h);

// The curve I want to plot: y=x^2
var my_curve = d3.range(10).map(function(d) { var my_y = d * d; return { "x" : d, "y" : my_y }; });

var x_range_min = d3.min(my_curve, function(d) { return d.x; }); 
var x_range_max = d3.max(my_curve, function(d) { return d.x; });
var y_range_min = d3.min(my_curve, function(d) { return d.y; }); 
var y_range_max = d3.max(my_curve, function(d) { return d.y; });

var xScale = d3.scaleLinear().domain([x_range_min, x_range_max]).range([0, w]);
var yScale = d3.scaleLinear().domain([y_range_max, y_range_min]).range([0, h]);

var xAxis = d3.axisBottom().scale(xScale);
var yAxis = d3.axisLeft().scale(yScale);


// symbols
svg.selectAll(".my_pts").data(my_curve).enter().append("path")
    .attr("class", "my_pts")
    .attr("d", d3.symbol().type(d3.symbolTriangle).size(200))
    .attr("transform", function(d) { return "translate(" + xScale(d.x) + "," + yScale(d.y) + ")"; })
    // with this zoomed line does not enter margin area
    .attr("clip-path", "url(#clip)");

...正如你所看到的,只有三角形符号的一部分被描绘出来,我猜是因为路径是在0,0处绘制的并且在执行翻译之前被clipPath剪切。

我也发布了这个小提琴https://jsfiddle.net/fabio_p/988c1sjv/ 在那里你可以找到一个更完整的代码版本,刷子和放大器缩放功能,以便您可以看到为什么需要clipPath(如果您之前从未遇到过边距问题)

我的问题如下:这个问题有解决方法吗?我希望找到一种方法直接在正确的位置绘制符号,而无需后续翻译(可能使用“自定义符号类型”),但它似乎超出了我目前的技能,因为我无法生产任何实际的解决方案。

欢迎提出任何建议。提前谢谢。

1 个答案:

答案 0 :(得分:2)

使用剪辑路径创建一个组:

var clipping = svg.append("g")
    .attr("clip-path", "url(#clip)");

并将行和符号附加到组中:

clipping.append("path")
    .data([my_curve])
    //etc...

这是您更新的小提琴:https://jsfiddle.net/cvtvrL2q/