Svg клип-путь внутри прямоугольника не работает
У меня есть простой график с осями X и Y. Я не хочу, чтобы область рисования, в которой я рисую, перекрывала оси.
Я использую d3 для создания своего графика, но путь к клипу не работает:
var margin = {top: 19.5, right: 19.5, bottom: 19.5, left: 39.5},
width = 960 - margin.right,
height = 500 - margin.top - margin.bottom;
var xScale = d3.scale.linear().
domain([xMin, xMax]). // your data minimum and maximum
range([0, width]); // the pixels to map to, e.g., the width of the diagram.
var yScale = d3.scale.linear().
domain([yMax, yMin]).
range([0, height]);
var xAxis = d3.svg.axis().orient("bottom").scale(xScale).ticks(10, d3.format(",d")),
yAxis = d3.svg.axis().orient("left").scale(yScale);
var chart = d3.select("#chart").append("svg")
.attr("class", "chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("pointer-events", "all")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(d3.behavior.zoom().scaleExtent([0.2, 5]).on("zoom", redraw));
var rect = chart.append('svg:rect')
.attr('width', width)
.attr('height', height)
.attr('fill', 'white');
var line = d3.svg.line()
.interpolate("basis")
.x(function(d, i) { return xScale(d.time); })
.y(function(d) { return yScale(d.value); });
var clip = chart.append("svg:clipPath")
.attr("id", "clip");
clip.append("svg:rect")
.attr("id", "clip-rect")
.attr("width", width)
.attr("height", height);
// .attr("fill", "white");
var path = chart.append("svg:path")
.attr("clip-path", "url(#clip-rect)")
.data([data])
.attr("class", "line")
.attr("fill", "none")
.attr("stroke", "maroon")
.attr("stroke-width", 2)
.attr("d", line);
// x-axis label
chart.append("text")
.attr("class", "x label")
.attr("text-anchor", "end")
.attr("x", width)
.attr("y", height - 6)
.text("time");
// y-axis label
chart.append("text")
.attr("class", "y label")
.attr("text-anchor", "end")
.attr("y", 6)
.attr("dy", ".75em")
.attr("transform", "rotate(-90)")
.text("value");
// x-axis
var xaxis = chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// y-axis
var yaxis = chart.append("g")
.attr("class", "y axis")
.call(yAxis);
function redraw()
{
console.log("here", d3.event.translate, d3.event.scale);
path.transition()
.ease("linear")
.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
}
2 ответа
Решение
Вы хотите что-то вроде этого:
http://jsfiddle.net/dsummersl/EqLBJ/1/
В частности:
- используйте "клип" вместо "клип-прямоугольник"
- поместите содержимое, которое вы хотите вырезать, внутри элемента 'g', и укажите атрибут 'clip-path' и преобразования для элемента 'g'.
Я предполагаю, что вы, как и я, хотите ограничить дальнейшее рисование меньшей областью внутри SVG? Вероятно, есть много причин, почему бы не сделать это таким образом, но я просто помещаю новый элемент SVG внутрь буквы G и выполняю все рисунки во внутреннем SVG.
Вот так:
var svg = d3.select(drawElement).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
var canvas = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.append("svg")
.attr("width", width)
.attr("height", height);