简体   繁体   中英

elements on ellipse edge in d3js

I try put images to oval edge. But they are to a large extent on the poles. I have oval:

  var oval = group.append("ellipse")
            .attr("cx", this.svgWidth / 2)
            .attr("cy", this.svgHeight / 2)
            .attr("rx", this.rx)
            .attr("ry", this.ry)
            .style("stroke", "#BCBBB6")
            .style("stroke-width", "3px")
            .style("fill", "transparent");

and i have image coordinates:

var imgX = Math.cos(that.angle * j) * that.rx - this.model.radius;
var imgY = Math.sin(that.angle * j) * that.ry - this.model.radius;

How can I arrange them evenly? 在此处输入图片说明

You cannot add image to ellipse tag but you can set image to ellipse background, to add picture to position you mention, Create circle then set image to background of them like this :

var oval = group.append("ellipse")
        .attr("cx", this.svgWidth / 2)
        .attr("cy", this.svgHeight / 2)
        .attr("rx", this.rx)
        .attr("ry", this.ry)
        .style("stroke", "#BCBBB6")
        .style("stroke-width", "3px")
        .style("fill", "transparent");

oval.selectAll("circle")
        .append("circle")
        .attr("cx" ,imgX )
        .attr("cy",imgY)
        .attr("r","8px")
        .attr("fill","Url(#img)");

var imgX = Math.cos(that.angle * j) * that.rx - this.model.radius;
var imgY = Math.sin(that.angle * j) * that.ry - this.model.radius;

Update1

To get the real position you have to change Polar angle to Cartesian.

var imgX = Math.cos((that.angle)*Math.PI * j/180.0) * that.rx - this.model.radius;
var imgY = Math.sin((that.angle)*Math.PI * j/180.0) * that.ry - this.model.radius;  

Update 2

I create a sample like you asked, Hope to help you.

    var width = 600, height = 600;
    var rx = 200, ry = 150;
    var circleNumbers = 20;

    var svg = d3.select("body").append("svg")
        .attr("width", width).attr("height", height)
        .attr("transform", "translate(0,150)");

    var ellipse = svg.append("ellipse")
        .attr("cx", width / 2)
        .attr("cy", height / 2)
        .attr("rx", rx)
        .attr("ry", ry)
        .style("stroke", "#BCBBB6")
        .style("stroke-width", "3px")
        .style("fill", "transparent");
    var degree = 360 / circleNumbers;

    for (var i = 0; i < circleNumbers; i++) {
        var circlePosition = polarToCartesian(width / 2, height / 2, rx, ry, i * degree);
        svg.append("circle")
            .attr("cx", circlePosition.x)
            .attr("cy", circlePosition.y)
            .attr("r", "8px")
            .attr("fill", "red");
    }

This function return position on ellipse with specific degree:

     function polarToCartesian(centerX, centerY, radiusX, radiusY, angleInDegrees) {

        var angleInRadians = (angleInDegrees* Math.PI / 180.0);


        return {
            x: centerX + (radiusX * Math.cos(angleInRadians)),
            y: centerY + (radiusY * Math.sin(angleInRadians))
        };
    }

Complete jsfiddle here .

Update 3

I made some changes to PolarToCartesian() function and it make the ellipse better.I changed the begin Angle to -90 and it's seem better.

        function polarToCartesian(centerX, centerY, radiusX, radiusY, angleInDegrees) {

        var angleInRadians = ((angleInDegrees-90)* Math.PI / 180.0);


        return {
            x: centerX + (radiusX * Math.cos(angleInRadians)),
            y: centerY + (radiusY * Math.sin(angleInRadians))
        };
    }

Complete jsfiddle here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM