d3.js:用于多个svg:text元素的可重用clipPath

d3.js:用于多个svg:text元素的可重用clipPath,svg,d3.js,Svg,D3.js,我有一个d3.js图表,其中有许多文本字符串,如果太长,则需要截断这些字符串 根据我的研究,在svg中处理文本截断的方法似乎是: 使用SVG clipPath 使用SVG getBBox()并循环截断字符,直到边界框小于max 只需使用最大字符长度的最佳猜测并截断字符串 也许可以使用foreignObject将HTML对象插入图表,然后使用css 我正在考虑选项1,并且正在努力 是否有方法创建特定维度的clipPath,然后为多个svg:g或svg:text元素引用该clipPath,并将cli

我有一个d3.js图表,其中有许多文本字符串,如果太长,则需要截断这些字符串

根据我的研究,在svg中处理文本截断的方法似乎是:

  • 使用SVG clipPath
  • 使用SVG getBBox()并循环截断字符,直到边界框小于max
  • 只需使用最大字符长度的最佳猜测并截断字符串
  • 也许可以使用foreignObject将HTML对象插入图表,然后使用css
  • 我正在考虑选项1,并且正在努力

    是否有方法创建特定维度的clipPath,然后为多个svg:g或svg:text元素引用该clipPath,并将clipPath放置在对象的本地转换坐标中?

    有没有办法使用“symbol”或“use”使其可重用,或者我必须为每个文本字符串生成唯一的clipPath

    不确定这是否有意义

    以下是我对不起作用的概念的粗略证明:


    回答我自己的问题

    该问题涉及clippath和g之间的坐标空间不匹配。clippath需要应用相反的坐标空间

    请参阅更新的小提琴:

    var svg = d3.select("#test")
                .append("svg")
                .attr("width", 300)
                .attr("height", 300)
                .attr("class", "test-container");
    
    var defs = d3.select('.test-container').append("svg:defs");
    
        defs.append("svg:clipPath")
            .attr("id", "textclip")
            .append("svg:rect")
            .attr("width", 200)
            .attr("height", 20)
            .attr("x", 0)
            .attr("y", 0)
            .attr("clipPathUnits","objectBoundingBox");
    
        svg.append("g")
            .attr("class", "textgroup")
            .attr("transform", "translate(10, 100)")
            .attr("clip-path", "url(#textclip)")
            .append("text")
            .attr("x", 0)
            .attr("y", 0)
            .attr("fill", "#000")
            .text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
    
        svg.append("g")
            .attr("class", "textgroup")
            .attr("transform", "translate(10, 150)")
            //.attr("clip-path", "url(#textclip)")
            .append("text")
            .attr("x", 0)
            .attr("y", 0)
            .attr("fill", "#000")
            .text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");    
    
        defs.append("svg:clipPath")
        .attr("id", "textclip")
        .attr("transform", "translate(-10, -20)")
        .append("svg:rect")
        .attr("width", 200)
        .attr("height", 20)
        .attr("x", 0)
        .attr("y", 0)
        .attr("clipPathUnits","objectBoundingBox");