簡體   English   中英

節點/圓頂上的d3圖像不適用於clipPath

[英]d3 image on top of node / circle doesn't work with clipPath

試圖在D3中找到一種在圓圈內放置圖像的方法。

img被加載到DOM中,但我無法在圓圈內進行渲染。

要點是將圖片放在頂部,這樣圓圈背景顏色必須保持原樣(顏色編碼目的)。

我在這做錯了什么?

Codepen

期望的輸出:

在此輸入圖像描述

我的代碼:

function render(name) {
    let markerCircles = svg.selectAll("circle")
        .data([1, 2, 3, 4, 5])
        .enter()
        .append("circle")
        .style("fill", "none")
        .attr("stroke", "#ff97c4")
        .style("stroke-width", "1.5px")
        .attr("cy", fullSVGHeight / 2)
        .attr("cx", markerCirclesScale(name) + 330)
        .attr("r", 0)

    markerCircles
        .transition()
        .duration(1000)
        .attr("r", function(d) {
            return d * 65;
        });

    let personCircles = svg.selectAll("a")
        .data(data)
        .enter()
        .append("a")
        .attr("id", function(d) {
            console.log(d["Person Name"]);
            if (d && d.length !== 0) {
                return d["Person Name"].replace(/ |,|\./g, '_');
            }
        })
        .style("opacity", 1)
        .call(d3.drag()
            .on("start", dragstarted)
            .on("drag", dragged)
            .on("end", dragended));

    //Define defs 
    let defs =  personCircles.append("defs");

     defs.append('rect')
            .attr('id', 'pic')
            .attr('x', function(d){
                return markerCirclesScale(name)
            })
             .attr('y', function(d){
                return fullSVGHeight / 2;
            })
            .attr('width', 120)
            .attr('height', 30)
            .attr('rx', 10)
            .style('fill', 'blue')

     defs.append("clipPath")
        .append("use")
        .attr('xlink:href', '_')
        .attr("z-index", 1000)

    d3.timeout(function() {
        personCircles
            .append("use")
            .attr('xlink:href', "_")
            .append('image')
            .attr('xlink:href', function(d){
                return 'https://vignette.wikia.nocookie.net/ideas/images/8/82/Donald_Trump.png/revision/latest/scale-to-width-down/640?cb=20170512015233'})
            .attr("clip-path", "url(#pic)")
            .attr("width", 120)
            .attr("height", 30)
            .attr("y", fullSVGHeight / 2)
            .attr("x", markerCirclesScale(name))
            .attr("opacity", .8)
            .append("circle")
            .attr("cy", fullSVGHeight / 2)
            .attr("cx", markerCirclesScale(name) + 330)
            .attr("r", 20)
            .append("title")
            .text(function(d) {
                return "Name: " + d["Person Name"] + ", " + "Time in the company: " + (+d["Period"] + " years");
            });
        simulation.restart().on("tick", ticked);

    }, 2000)

D3代碼幾乎沒問題,但是受到SVG元素層次結構的影響。 它似乎應該按此順序:

此處不需要<a> ID用於特定圖片顯示任務

let personCircles = svg.selectAll("a")
            .data(data)
            .enter()
            .append("a")
            .attr("id", function(d) {
                console.log(d["Person Name"]);
                if (d && d.length !== 0) {
                    return d["Person Name"].replace(/ |,|\./g, '_');
                }
            })
            .style("opacity", 1)
            .call(d3.drag()
                .on("start", dragstarted)
                .on("drag", dragged)
                .on("end", dragended));

然后defs

<defs>
//Define defs 
        let defs =  personCircles.append("defs");

然后第一個容器進入其中放置圖片

<rect id = "RECT" / > // ID是必需的

defs.append('rect')
                    .attr('id', 'rect-ggg')
                    .attr('x', function(d){
                        return markerCirclesScale(name)
                    })
                     .attr('y', function(d){
                        return fullSVGHeight / 2;
                    })
                    .attr('width', 60)
                    .attr('height', 60)
                    .attr('rx', 40)
                    .style('fill', 'red')

容器附有一個夾子來創建一個面具

<clipPath id = "the CLIP"> //此處也需要ID

defs.append("clipPath")
                .attr('id', 'clip-ggg')

將蒙版綁定到容器

<use the href = "# a RECT"> </use> //對容器的引用

.append("use")
                    .attr('href', function(d){
                        return  "#rect-ggg";

                    })

<use>根據我的理解,這需要向頁面添加容器,因為瀏覽器不會呈現DEFS內容本身

<use href = "# RECT" > </ use> //對容器的引用

personCircles
                .append("use")
                .attr('href', function(d){
                return  "#rect-ggg";

            })

最后添加照片

<image href clip-path = " url (#CLIP)" /> //參考掩碼

personCircles.append('image')
                .attr('href', function(d){
                    return 'https://vignette.wikia.nocookie.net/ideas/images/8/82/Donald_Trump.png/revision/latest/scale-to-width-down/640?cb=20170512015233'})


                .attr("clip-path", function(d){ 
                    return "url(#clip-ggg)";
                })
                .attr("width", 60)
                .attr("height", 60)
                .attr('x', function(d){
                    return markerCirclesScale(name)
                })
                .attr('y', function(d){
                   return fullSVGHeight / 2 + 8;
                })

circle //這個圓圈不是必需的,我在我的布局中用它來添加筆划

 //Define SVG width and height let fullSVGHeight = 700; let fullSVGWidth = 900; //Define margins // let margins = { // top: 10, // right: 50, // bottom: 10, // left: 10 // } //Define chart width, height, x/y scale // let chartHeight = fullSVGHeight - margins.top - margins.bottom; // let chartWidth = fullSVGWidth - margins.left - margins.right; //Define marker circles scale let markerCirclesScale = d3.scalePoint() .range([0, fullSVGWidth]) //Fetch data d3.json("https://api.myjson.com/bins/7gjbe").then(data => { // data.forEach(function(d){ // console.log("This is initial d.Period: ", +d.Period) // return data.filter(function() { // if (+d["Period"] === 0){ // return d["Period"] = 1; // } else { // return d.Period = Math.floor(+d["Period"]); // } // })}); console.log(data); markerCirclesScale .domain(data.map(function(d) { return d["Person Name"]; })) let svg = d3.select("body") .append("svg") .attr("width", fullSVGWidth) .attr("height", fullSVGHeight) .append("g") .attr("transform", "translate(" + 0 + "," + 0 + ")"); data.forEach(function(d) { return render(d["Person Name"]) }); function render(name) { let markerCircles = svg.selectAll("circle") .data([1, 2, 3, 4, 5]) .enter() .append("circle") .style("fill", "none") .attr("stroke", "#ff97c4") .style("stroke-width", "1.5px") .attr("cy", fullSVGHeight / 2) .attr("cx", markerCirclesScale(name) + 330) .attr("r", 0) markerCircles .transition() .duration(1000) .attr("r", function(d) { return d * 65; }); let personCircles = svg.selectAll("a") .data(data) .enter() .append("a") .attr("id", function(d) { console.log(d["Person Name"]); if (d && d.length !== 0) { return d["Person Name"].replace(/ |,|\\./g, '_'); } }) .style("opacity", 1) .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)); //Define defs let defs = personCircles.append("defs"); defs.append('rect') .attr('id', 'rect-ggg') .attr('x', function(d){ return markerCirclesScale(name) }) .attr('y', function(d){ return fullSVGHeight / 2; }) .attr('width', 60) .attr('height', 60) .attr('rx', 40) .style('fill', 'red') defs.append("clipPath") .attr('id', 'clip-ggg') .append("use") .attr('href', function(d){ return "#rect-ggg"; }) let simulation = d3.forceSimulation(data) .force("charge", d3.forceCollide().radius(3)) .force('center', d3.forceCenter(fullSVGWidth / 2, fullSVGHeight / 2)) .force("radius", d3.forceRadial(function(d) { return +d["Period"] * 60 }, fullSVGWidth / 2, fullSVGHeight / 2).strength(0.3)) .on("tick", ticked) .velocityDecay(0.07) .stop(); function ticked() { personCircles .attr("cx", function(d) { return dx - 100; }) .attr("cy", function(d) { return dy; }); } d3.timeout(function() { personCircles .append("use") .attr('href', function(d){ return "#rect-ggg"; }) personCircles.append('image') .attr('href', function(d){ return 'https://vignette.wikia.nocookie.net/ideas/images/8/82/Donald_Trump.png/revision/latest/scale-to-width-down/640?cb=20170512015233'}) .attr("clip-path", function(d){ return "url(#clip-ggg)"; }) .attr("width", 60) .attr("height", 60) .attr('x', function(d){ return markerCirclesScale(name) }) .attr('y', function(d){ return fullSVGHeight / 2 + 8; }) simulation.restart().on("tick", ticked); }, 2000) function dragstarted(d) { d.dragged = true; simulation.alphaTarget(0.8).restart(); d.fx = dx; d.fy = dy; } function dragged(d) { d.fx = d3.event.x; d.fy = d3.event.y; } function dragended(d) { simulation.alphaTarget(0); d.fx = null; d.fy = null; d3.timeout(function() { d.dragged = false; }, 1000) } } }).catch(error => console.log(error)); 
 body, body *{ top:0; padding: 0; margin: 0; background-color: #80d6c7; overflow: hidden; font-family: Lucida Console, Monaco, monospace; } a { background-color: transparent; color: #679fa5; text-decoration: none; } svg { margin-top: 2% ; margin-left: 29%; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM