Im working on a Vue component, where the user can add circles in to other circles, with support for unlimited levels of nesting, but im having some problems with the CSS.
Here is a simplified version of the problem:
Im trying to achieve something like this.
I thought flexbox
would be a great choice for that job, but cant make it work how i want it to, it always ends up way too big and not breaking up into separate lines or breaking out of the circles.
I have tried this approach, im open for a new structure if there is an easer way to do this. As long as the circle have a title and content, thought about using before
and after
for the title and content to simplify the structure, but haven't explored that option yet.
document.querySelectorAll(".circle").forEach( el => el.style.height = window.getComputedStyle(el).width);
* {
margin: 0;
padding: 0;
}
.flex {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
flex-flow: row wrap;
justify-content: space-around;
}
.circle {
border-radius: 50%;
padding: 40px;
box-shadow: 7px 7px 5px 0px rgba(50, 50, 50, 0.75);
}
.head {
color: #fff;
text-align: center;
margin-bottom: 10px;
height: 20px;
}
.body {
align-items: center;
}
.red {
background-color: rgba(255, 17, 0, 0.76);
}
.blue {
background-color: rgba(8, 0, 255, 0.76);
}
.green {
background-color: rgba(0, 157, 11, 0.76);
}
<div id="circle_test">
<div id="master" class="red circle flex">
<div class="head">
Parent
</div>
<div class="body flex">
<div class="blue circle">
<div class="head">
child-0
</div>
<div class="body flex">
<div class="green circle">
<div class="head">sub-child-0</div>
<div class="body">content here</div>
</div>
<div class="green circle">
<div class="head">sub-child-1</div>
<div class="body">content here</div>
</div>
<div class="green circle">
<div class="head">sub-child-2</div>
<div class="body">content here</div>
</div>
</div>
</div>
<div class="blue circle">
<div class="head">
child-1
</div>
<div class="body flex">
<div class="green circle">
<div class="head flex">sub-child-0</div>
<div class="body">content here</div>
</div>
</div>
</div>
</div>
</div>
</div>
or as a jsfiddle.net link
Any inputs are appreciated, thanks :)
To create a circle we can set the border-radius on the element. This will create curved corners on the element. If we set it to 50% it will create a circle. If you set a different width and height we will get an oval instead.
The method that we used in the example above is the simplest one and has good browser support. Now, let's see an example, where we use <span> elements within a <div>. Here, we also specify the display as “inline-block” and add the text-align property set to “center” to the <div> to align the circles to the center.
I think you could achieve something visually similar with d3.js:
var svg = d3.select("svg"),
diameter = +svg.attr("width"),
g = svg.append("g").attr("transform", "translate(2,2)"),
format = d3.format(",d");
var pack = d3.pack()
.size([diameter - 4, diameter - 4]);
var circles = '{ "name": "Parent", "children": [ { "name": "child-0", "children": [ {"name": "sub-child-0", "size": 100}, {"name": "sub-child-1", "size": 100}, {"name": "sub-child-2", "size": 100} ] }, { "name": "child-1", "children": [ {"name": "sub-child-0", "size": 100} ] } ]}';
var circlesParse = JSON.parse(circles);
circlesParse = d3.hierarchy(circlesParse)
.sum(function(d) { return d.size; })
.sort(function(a, b) { return b.value - a.value; });
var node = g.selectAll(".node")
.data(pack(circlesParse).descendants())
.enter().append("g")
.attr("class", function(d) { return d.children ? "node" : "leaf node"; })
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
node.append("title")
.text(function(d) { return d.data.name + "\n" + format(d.value); });
node.append("circle")
.attr("r", function(d) { return d.r; });
node.filter(function(d) { return !d.children; }).append("text")
.attr("dy", "0.3em")
.text(function(d) { return d.data.name.substring(0, d.r / 3); });
circle {
fill: rgb(31, 119, 180);
fill-opacity: .25;
stroke: rgb(31, 119, 180);
stroke-width: 1px;
}
.leaf circle {
fill: #ff7f0e;
fill-opacity: 1;
}
text {
font: 10px sans-serif;
text-anchor: middle;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="250" height="250"></svg>
Inspired by https://bl.ocks.org/mbostock/4063530
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With