¿Una forma sencilla de usar un objeto existente como un trazado de recorte?

Tengo el siguiente ejemplo simple, cuando la línea se extiende fuera del rectángulo, quiero recortarla. Ya tengo el rectángulo usado como contorno, ¿de qué se trata de una manera simple para el mismo rectángulo que un trazado de recorte? Mi enfoque actual usando id es ignorado. Esta pregunta relacionada tiene una respuesta, pero requiere la creación del área del clip por separado. Me gustaría reutilizar mi información en lugar de repetir casi la misma información.

       var margin = {top: 100, right: 20, bottom: 20, left: 20}, width = 600 - margin.left - margin.right, height = 270 - margin.top - margin.bottom; var xdata = d3.range(0, 20); var ydata = [1, 4, 5, 9, 10, 14, 15, 15, 11, 10, 5, 5, 4, 8, 7, 5, 5, 5, 8, 10]; var xy = []; // start empty, add each element one at a time for(var i = 0; i < xdata.length; i++ ) { xy.push({x: xdata[i], y: ydata[i]}); } var xscl = d3.scale.linear() .domain(d3.extent(xy, function(d) {return dx;})) //use just the x part .range([margin.left, width + margin.left]) var yscl = d3.scale.linear() .domain([1, 8]) // use just the y part .range([height + margin.top, margin.top]) var slice = d3.svg.line() .x(function(d) { return xscl(dx);}) // apply the x scale to the x data .y(function(d) { return yscl(dy);}) // apply the y scale to the y data var svg = d3.select("body") .append("svg") svg.append('rect') // outline for reference .attr({x: margin.left, y: margin.top, width: width, height: height, id: "xSliceBox", stroke: 'black', 'stroke-width': 0.5, fill:'white'}); svg.append("path") .attr("class", "line") .attr("d", slice(xy)) .attr("clip-path", "#xSliceBox") .style("fill", "none") .style("stroke", "red") .style("stroke-width", 2);   

No puede hacer referencia al rectángulo directamente en la propiedad de clip-path , debe crear un elemento . Luego, dentro del elemento , puede usar un elemento para hacer referencia al rectángulo.

(Sí, es redondo y más complicado de lo que uno pensaría que debería ser, pero así es como lo definieron las especificaciones de SVG).

Trabajando desde su código:

 var svg = d3.select("body") .append("svg") var clip = svg.append("defs").append("clipPath") .attr("id", "clipBox"); svg.append('rect') // outline for reference .attr({x: margin.left, y: margin.top, width: width, height: height, id: "xSliceBox", stroke: 'black', 'stroke-width': 0.5, fill:'white'}); clip.append("use").attr("xlink:href", "#xSliceBox"); svg.append("path") .attr("class", "line") .attr("d", slice(xy)) .attr("clip-path", "url(#clipBox)") //CORRECTION .style("fill", "none") .style("stroke", "red") .style("stroke-width", 2); 

También puede hacer esto al revés, definiendo el rectángulo dentro del elemento clipPath y luego usando un elemento para dibujarlo en la pantalla. De cualquier manera, solo quieres definir el rectángulo una vez, de modo que si decides cambiarlo solo tienes que hacerlo en un lugar y el otro se actualizará para que coincida.