Creating CSS circles connected by lines to middle

2019-04-02 05:14发布

问题:

I need to create a page something like this. The blue circle is the main circle and green circles should place around the main circle. The green circles count is random (around 0 - 10). All green circles are connected to blue circle with a line.

I know to draw circle in CSS. I need to know,

  1. How to place green circles around the blue circle
  2. How to connect green circles to the blue circle

Is it possible to do with CSS. If not what is the way?

Thank you.

回答1:

What you will need is a position: relative; container with child elements positioned absolute

Demo

Demo 2 (Using transform)

Explanation: What am doing here is using position: relative; on the parent element which is .ball_wrap, than am using position: absolute; for the child elements AS WELL AS the :after pseudo elements to connect the child elements with the parent. If you are not aware of the pseudo elements than take them as a virtual element, these elements do not exist literally in the DOM but they do render graphically. So am using display: block; as they are inline by default..along with content: "";... Rest, set them accordingly using top, right, bottom and left properties.

.ball_wrap {
    position: relative;
    margin: 150px;
    width: 90px;
}

.green_ball {
    background: #00C762;
    height: 50px;
    width: 50px;
    border-radius: 50%;
    border: 3px solid #ccc;
    position: absolute;
}

.blue_ball {
    background: #2F9BC1;
    height: 80px;
    width: 80px;
    border-radius: 50%;
    border: 3px solid #ccc;
}

.ball_wrap div:nth-of-type(2) {
    top: 20px;
    left: -100px;
}

.ball_wrap div:nth-of-type(2):after {
    content: "";
    display: block;
    border-bottom: 1px solid #000;
    position: absolute;
    width: 50px;
    right: -50px;
    top: 50%;
}

.ball_wrap div:nth-of-type(3) {
    top: 20px;
    right: -100px;
}

.ball_wrap div:nth-of-type(3):after {
    content: "";
    display: block;
    border-bottom: 1px solid #000;
    position: absolute;
    width: 50px;
    left: -52px;
    top: 50%;
}

.ball_wrap div:nth-of-type(4) {
    right: 20px;
    bottom: -100px;
}

.ball_wrap div:nth-of-type(4):after {
    content: "";
    display: block;
    border-left: 1px solid #000;
    position: absolute;
    height: 50px;
    left: 50%;
    top: -52px;
}

Also you might take a look at these types of charts using jQuery



回答2:

You can create the round shapes just with plain CSS:

html:

<div id="ball" class="border"> 
    <div class="blue ball"> </div>
</div>
<div id="ball1" class="border"> 
    <div class="green ball"> </div>
</div>

css:

.border
{
    position: relative;
    width: 115px;
    height: 115px;
    background: #e7e9e9;
    border-radius: 100px;
    border: 2px solid #d1d1d1;
}

.ball
{
    position: absolute;
    left: 9%;    
    top: 9%;

    width: 90px;
    height: 90px;

    border-radius: 100px;
}

.blue
{
    background: #2f9bc1;
    border: 2px solid #266a8e;
}

.green
{
   background: #00c762; 
   border: 2px solid #00be58;
}

#ball
{
    top: 200px;   
    left: 300px;
}

Where you place each shape at the right position with position: relative; offset.

For the lines you could use HTML 5 canvas:

html:

<canvas id="myCanvas" class="line"></canvas>

javascript canvas:

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');

context.beginPath();
context.moveTo(350, 150);
context.lineTo(50, 50);
context.stroke();

Where i use a position: absolute; for the line, so it doesn't push the shapes away and a z-index so it is beneath the shapes:

.line
{
    position: absolute;
    width: 320px;
    z-index: -1;
}

jsFiddle



回答3:

Here is a rough sample html in using canvas.
--- html ---

<div style="border:solid thick #000">
    <canvas id="canvas"></canvas>
</div>


--- javascript ---

<script>
            var ctx;
            window.onload = function() {
                canvas = document.getElementById('canvas');
                if (!canvas || !canvas.getContext) {
                    return false;
                }
                canvas.width = 600;
                canvas.height = 600;
                ctx = canvas.getContext('2d');           
                ctx.strokeStyle = '#000';
                ctx.fillStyle = "green";
                ctx.translate(300, 300);
                drawChildCircles(5);
                ctx.arc(0, 0, 20, 0, Math.PI * 2);//center circle
                ctx.stroke();
                ctx.fill();                 
            }

            function drawChildCircles(n) {
                var ang_unit = Math.PI * 2 / n;
                ctx.save();
                for (var i = 0; i < n; i++) {
                    ctx.rotate(ang_unit);
                    ctx.beginPath();
                    ctx.moveTo(0,0);
                    ctx.lineTo(100,0);
                    ctx.arc(100, 0, 20, 0, Math.PI * 2);
                    ctx.stroke();
                    ctx.fill();
                }
                ctx.restore();
            }
        </script>

However, I believe that the best way is to use svg with d3.js,
especially if you want to draw some data visualization or relation map.



回答4:

Here's another example using svg elements. SVG elements are very good for these kinda cases.

You'll get more info over here.

If you're trying to do some visualizations out of it. I'd suggest you to get along with d3. A javascript library that used svg elements to create amazing visualization.

HTML:

 <div id="container">
   <svg id="red">
        <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
    </svg>
    <svg id="red-line">
        <line x1="130" y1="50" x2="300" y2="50" style="stroke:rgb(255,0,0);stroke-width:2"/>
    </svg>
    <svg id="blue">
        <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="blue"/>
    </svg>
    <svg id="blue-line">
        <line x1="130" y1="50" x2="260" y2="50" style="stroke:rgb(255,255,0);stroke-width:2"/>
    </svg>
    <svg id="green">
        <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="green"/>
    </svg>
    <svg id="green-line">
        <line x1="100" y1="0" x2="100" y2="70" style="stroke:rgb(255,0,255);stroke-width:2"/>
    </svg>
    <svg id="yellow">
        <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="yellow"/>
    </svg>

CSS :


    #container {
      position: relative;
      margin: 150px 0 0 250px;
    }
    #container svg {
      position: absolute;
    }
    #blue {
      top: -150px;
    }
    #green {
      left: -200px;
    }
    #yellow {
      left: 200px;
    }
    #blue-line {
      margin-left: -200px;
    }
    #green-line {
      margin-top: -60px;
    }