Jojo01
Jojo01

Reputation: 1289

d3 svg how to center multiple circles

i have a json file:

{
    "circles": [
        {"name": "Circle", "x":13.284199,"y":-12.223403, "group":1}, 
        {"name": "Circle", "x":13.277986,"y":-30.081020, "group":0}, 
        {"name": "Circle", "x":37.270324,"y":-46.266050, "group":0}, 
        {"name": "Circle", "x":49.085207,"y":-50.323903, "group":1}, 
        {"name": "Circle", "x":17.334599,"y":-76.113029, "group":1}, 
        {"name": "Circle", "x":40.067553,"y":-76.576700, "group":0}, 
        {"name": "Circle", "x":11.616747,"y":-107.550639, "group":0}, 
        {"name": "Circle", "x":10.827147,"y":-134.892190, "group":0}, 
        {"name": "Circle", "x":18.657633,"y":-171.319351, "group":0}, 
        {"name": "Circle", "x":50.023818,"y":-182.810422, "group":0}
    ]
}

And i am drawing circles and positioning them based on those x and y coordinates. So far i have tried to set the svg element's transform="translate()" to the x and y coordinates of the first circle, but that wasn't successfull.

Upvotes: 0

Views: 1126

Answers (2)

thatOneGuy
thatOneGuy

Reputation: 10642

enter image description here

If the image is what you want, youll have to move the element the circles are appended to. Like so:

svg.attr("transform",function(){
                movementX = windowWidth/2 - svgWidth /2;
                movementY = windowHeight/2 - svgHeight /2;
                return "translate("+movementX+","+movementY +")";
                }
                );

That's if svg is of type SVG. If not youll have to use offset.

$(svg).offset({top : movementY, left: movementX});

This will center the svg to the center of the screen. I cant answer it 100% as ill need to see your code and what elements you have used, but the basics are there and should be easily understood.

EDIT

I just realized this wasn't resolved.

I added an ID to the <g> tag, i.e the container of the circles and added the following code. I have commented to explain :)

var circleContainer = d3.select('#circleContainer') //get circle container

var circleContainerBBox = getBoundingBox('#circleContainer'); //get bounding box of circle container to get x,y,width and height
var svgBBox = getBoundingBox('#svg'); //same for svg to find offset

var differenceX = circleContainerBBox.x - svgBBox.x - (circleContainerBBox.width / 2); //difference between svg x and circleContainer x take away half the width of the circle container as it draws from top left
var differenceY = circleContainerBBox.y - svgBBox.y - (circleContainerBBox.height / 2); //same for y direction



var width = 800, //set width
  height = 400; //and height

circleContainer.attr('transform', function(d) {
  return "translate(" + ((width / 2) + differenceX) + ',' + ((height / 2) + differenceY) + ')'; //here's were you transform the circle container based on the values calculated above
})


function getBoundingBox(element) { //function to get bbox
  var thisEl = document.querySelector(element)
  var thisElBBox = thisEl.getBBox();
  console.log(thisElBBox)

  return thisElBBox;

}
svg {
  width: 800px;
  height: 400px;
  border: 1px solid #00667A;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg id='svg'>
  <!--Make a javascript script, that sets a transform to the g to center the circles.-->
  <g id='circleContainer'>
    <!-- Transform here <---- -->
    <circle cx="20" cy="10" fill="red" r="10"></circle>
    <circle cx="20" cy="36" fill="red" r="10"></circle>
  </g>
</svg>

Upvotes: 2

DevGrowth.Tech
DevGrowth.Tech

Reputation: 1563

If you already transform these circles by "translate(" + d.x + "," + d.y + "), check if it is because the position y value is negative, and the circle is not visible in your svg area.

Upvotes: 0

Related Questions