D3:组合圆和图像 [英] D3: combine circles and images

查看:147
本文介绍了D3:组合圆和图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有生成圈子和图片的功能

I have function to generate circle and images

        node.append("circle")
        .attr("r", function(d) { return d.weight * 2+ 12; })
        .attr("class", "logo")
        .style("fill", "transparent")       
        .style("stroke", "black")     
        .style("stroke-width", 0.25)
         .on("mouseover", function(){ 
           d3.select(this)
               .style("fill", "url(#/images/fake/FakeTree/100331934)");
             })
              .on("mouseout", function(){ 
                   d3.select(this)
                       .style("fill", "transparent");
             });


        node.append("image")
            .attr("xlink:href", d=> d.url)

                .classed("MakeItround", true)

            .attr("x", function(d) { return d.weight * 2-35; })
            .attr("y", height/15 -38)

            .attr("width", width/20)
            .attr("height", height/20)

             .on("click", function(d) { alert("CLicked"); });

我如何使用模式将它们放在一起以形成带圆圈的图片?

How can i use pattern to put them together in order to make an circled image?

JSfiddle: http://jsfiddle.net/qvco2Ljy/124/

JSfiddle:http://jsfiddle.net/qvco2Ljy/124/

推荐答案

您可以使用 clip-path 按照Brad的建议来实现。

You can use clip-path property to implement this as suggested by Brad.

node.append("circle")
  .attr("r", function(d) {
    d.radius = d.weight * 2 + 12;
    return d.radius;
  })
  .attr("class", "logo")  
  .style("fill", "transparent")
  .style("stroke", "black")
  .style("stroke-width", 0.25)
  .on("mouseover", function() {
    d3.select(this)
      .style("fill", "url(#/images/fake/FakeTree/100331934)");
  })
  .on("mouseout", function() {
    d3.select(this)
      .style("fill", "transparent");
  });

node.append("clipPath")
  .attr('id', function(d, i) {
    return "clip" + i
  })
  .append("circle")
  .attr("class", "clip-path")
  .attr("r", function(d) {
    return d.radius;
  })
  .style("fill", function(d) {
    return color(1 / d.rating);
  });

node.append("svg:image")
  .attr("class", "circle")
  .attr("xlink:href", d => d.url)
  .attr("clip-path", function(d, i) {
    return "url(#clip" + i + ")"
  })
  .attr("x", function(d) {
    return -d.radius;
  })
  .attr("y", function(d) {
    return -d.radius;
  })
  .attr("width", function(d) {
    return d.radius * 2;
  })
  .attr("height", function(d) {
    return d.radius * 2;
  });

var graph = {
  "nodes": [{
      "name": "1",
      "rating": 90,
      "id": 2951,
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.pngo"
    }, {
      "name": "2",
      "rating": 80,
      "id": 654654,
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.png"
    }, {
      "name": "3",
      "rating": 80,
      "id": 6546544,
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.pngo"
    }, {
      "name": "4",
      "rating": 1,
      "id": 68987978,
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.png"
    }, {
      "name": "5",
      "rating": 1,
      "id": 9878933,
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.png"
    }, {
      "name": "6",
      "rating": 1,
      "id": 6161,
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.png"
    }, {
      "name": "7",
      "rating": 1,
      "id": 64654,
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.png"
    }, {
      "name": "8",
      "rating": 20,
      "id": 354654,
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.png"
    }, {
      "name": "9",
      "rating": 50,
      "id": 8494,
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.png"
    }, {
      "name": "10",
      "rating": 1,
      "id": 6846874,
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.png"
    }, {
      "name": "11",
      "rating": 1,
      "id": 5487,
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.png"
    }, {
      "name": "12",
      "rating": 80,
      "id": "parfum_kenzo",
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.png"
    }, {
      "name": "13",
      "rating": 1,
      "id": 65465465,
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.png"
    }, {
      "name": "14",
      "rating": 90,
      "id": "jungle_de_kenzo",
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.png"
    }, {
      "name": "15",
      "rating": 20,
      "id": 313514,
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.png"
    }, {
      "name": "16",
      "rating": 40,
      "id": 36543614,
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.png"
    }, {
      "name": "17",
      "rating": 100,
      "id": "Yann_YA645",
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.png"
    }, {
      "name": "18",
      "rating": 1,
      "id": 97413,
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.png"
    }, {
      "name": "19",
      "rating": 1,
      "id": 97414,
      "url": "http://a4.mzstatic.com/us/r30/Purple71/v4/67/24/35/672435a3-3f19-4a13-21e6-057a8e5a3ca7/icon175x175.pngg"
    },



  ],
  "links": [{
      "source": 6,
      "target": 5,
      "value": 6,
      "label": "publishedOn"
    }, {
      "source": 8,
      "target": 5,
      "value": 6,
      "label": "publishedOn"
    }, {
      "source": 7,
      "target": 1,
      "value": 4,
      "label": "containsKeyword"
    }, {
      "source": 8,
      "target": 10,
      "value": 3,
      "label": "containsKeyword"
    }, {
      "source": 7,
      "target": 14,
      "value": 4,
      "label": "publishedBy"
    }, {
      "source": 8,
      "target": 15,
      "value": 6,
      "label": "publishedBy"
    }, {
      "source": 9,
      "target": 1,
      "value": 6,
      "label": "depicts"
    }, {
      "source": 10,
      "target": 1,
      "value": 6,
      "label": "depicts"
    }, {
      "source": 16,
      "target": 1,
      "value": 6,
      "label": "manageWebsite"
    }, {
      "source": 16,
      "target": 2,
      "value": 5,
      "label": "manageWebsite"
    }, {
      "source": 16,
      "target": 3,
      "value": 6,
      "label": "manageWebsite"
    },


  ]
}

//seting size and position
var margin = {
  top: -5,
  right: -5,
  bottom: -5,
  left: -5
};
var width = 1000 - margin.left - margin.right,
  height = 400 - margin.top - margin.bottom;

//give out random color for circle (currently disable)
var color = d3.scale.category20();

//the Link porperty
var force = d3.layout.force()
  .charge(-200)
  .linkDistance(150)
  .size([width + margin.left + margin.right, height + margin.top + margin.bottom]);

//interactive
var zoom = d3.behavior.zoom()
  .scaleExtent([1, 10])
  .on("zoom", zoomed);

var drag = d3.behavior.drag()
  .origin(function(d) {
    return d;
  })
  .on("dragstart", dragstarted)
  .on("drag", dragged)
  .on("dragend", dragended);

//the main body
var svg = d3.select("#map").append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.right + ")")
  .call(zoom)

var rect = svg.append("rect")
  .attr("width", width)
  .attr("height", height)
  .style("fill", "none")
  .style("pointer-events", "all");


//fake data - should have some score and the peoplo s name1
var x = {
  name: 'test',
  Id: '9999',
  score: '100'
};

//var z = "<b>"+x.Id+"</b>""<b>"+x.name+"</b>""<b>"+x.score+"</b>";

var tooltip = d3.select("body")
  .append("div")
  .attr("class", "tooltip")
  .style("position", "absolute")
  .style("z-index", "9999")
  .style("visibility", "hidden")
  //.html(API); should get data from api
  .html("<b>Name : " + x.name + "</b>" + "<p>Id :" + x.Id + "</p>" + "<p>Score :" + x.score + "</p>");
//.html(function(d) { return d.name});


var container = svg.append("g");

//d3.json('http://blt909.free.fr/wd/map2.json', function(error, graph) {

force
  .nodes(graph.nodes)
  .links(graph.links)
  .start();

var link = container.append("g")
  .attr("class", "links")
  .selectAll(".link")
  .data(graph.links)
  .enter().append("line")
  .attr("class", "link")
  .style("stroke-width", function(d) {
    return Math.sqrt(d.value);
  });

var node = container.append("g")
  .attr("class", "nodes")
  .selectAll(".node")
  .data(graph.nodes)
  .enter().append("g")
  .attr("class", "node")
  .attr("cx", function(d) {
    return d.x;
  })
  .attr("cy", function(d) {
    return d.y;
  })
  .call(drag);

node.append("circle")
  .attr("r", function(d) {
    d.radius = d.weight * 2 + 12;
    return d.radius;
  })
  .attr("class", "logo")  
  .style("fill", "transparent")
  .style("stroke", "black")
  .style("stroke-width", 0.25);

node.append("clipPath")
  .attr('id', function(d, i) {
    return "clip" + i
  })
  .append("circle")
  .attr("class", "clip-path")
  .attr("r", function(d) {
    return d.radius;
  })
  .style("fill", function(d) {
    return color(1 / d.rating);
  });

node.append("svg:image")
  .attr("class", "circle")
  .attr("xlink:href", d => d.url)
  .attr("clip-path", function(d, i) {
    return "url(#clip" + i + ")"
  })
  .attr("x", function(d) {
    return -d.radius;
  })
  .attr("y", function(d) {
    return -d.radius;
  })
  .attr("width", function(d) {
    return d.radius * 2;
  })
  .attr("height", function(d) {
    return d.radius * 2;
  });


node.append("text")
  .attr("x", function(d) {
    return d.weight * 2 - 35;
  })
  .attr("y", height / 15 - 38)
  .style("opacity", "1")
  .html(function(d) {
    return d.name
  });


force.on("tick", function() {
  link.attr("x1", function(d) {
      return d.source.x;
    })
    .attr("y1", function(d) {
      return d.source.y;
    })
    .attr("x2", function(d) {
      return d.target.x;
    })
    .attr("y2", function(d) {
      return d.target.y;
    });

  node.attr("transform", function(d) {
    return "translate(" + d.x + "," + d.y + ")";
  });
});

var linkedByIndex = {};
graph.links.forEach(function(d) {
  linkedByIndex[d.source.index + "," + d.target.index] = 1;
});

function isConnected(a, b) {
  return linkedByIndex[a.index + "," + b.index] || linkedByIndex[b.index + "," + a.index];
}

//Show tooltip box
node.on("mouseover", function(d) {

  node.classed("node-active", function(o) {
    thisOpacity = isConnected(d, o) ? true : false;
    this.setAttribute('fill-opacity', thisOpacity);
    return thisOpacity;
  });

  link.classed("link-active", function(o) {
    return o.source === d || o.target === d ? true : false;
  });

  d3.select(this).classed("node-active", true);
  
  tooltip.style("visibility", "visible")
  tooltip.style("diplay", "block")
    .style('top', d3.event.pageY - 6 + 'px')
    .style('left', d3.event.pageX + 10 + 'px')

})

//hide tooltip box
.on("mouseout", function(d) {

  node.classed("node-active", false);
  link.classed("link-active", false);
  
  tooltip.style("visibility", "hidden")
});

// On Click, we want to add data to the array and chart
svg.on("click", function() {
  var coords = d3.mouse(this);

  // Normally we go from data to pixels, but here we're doing pixels to data
  var newData = {
    x: Math.round(xScale.invert(coords[0])), // Takes the pixel number to convert to number
    y: Math.round(yScale.invert(coords[1]))
  };

  dataset.push(newData); // Push data to our array

  svg.selectAll("circle") // For new circle, go through the update process
    .data(dataset)
    .enter()
    .append("circle")
    .attr(circleAttrs) // Get attributes from circleAttrs var
    .on("mouseover", handleMouseOver)
    .on("mouseout", handleMouseOut);
})


function dottype(d) {
  d.x = +d.x;
  d.y = +d.y;
  return d;
}

function zoomed() {
  container.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}

function dragstarted(d) {
  d3.event.sourceEvent.stopPropagation();

  d3.select(this).classed("dragging", true);
  force.start();
}

function dragged(d) {

  d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);

}

function dragended(d) {

  d3.select(this).classed("dragging", false);
}

.node {
  font: 10px sans-serif;
}
.node-active {
  stroke: #555;
  stroke-width: 1.5px;
}
.link {
  stroke: #555;
  stroke-opacity: .3;
}
.link-active {
  stroke-opacity: 1;
}
.overlay {
  fill: none;
  pointer-events: all;
}
#map {
  border: 2px #555;
  width: 1100px;
  height: 400px;
}
div.tooltip {
  position: absolute;
  padding: 2px;
  background: white;
  border-radius: 25px;
  padding: 20px;
  border: 2px solid steelblue;
  opacity: 1 !important;
}
.MakeItround {
  border-radius: 50%;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<body>
  <div id="map"></div>
</body>

这篇关于D3:组合圆和图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆