Good day/night!
I got this code on Codepen https://codepen.io/alextechflow/pen/QxeJwv
How can I get it to show up in a div?
I have the D3.js link added to my index.html
Is there something else I am missing here? My div is empty.
Good day/night!
I got this code on Codepen https://codepen.io/alextechflow/pen/QxeJwv
How can I get it to show up in a div?
I have the D3.js link added to my index.html
Is there something else I am missing here? My div is empty.
Like this perhaps…
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">
<title>untitled document</title>
<!--<link rel="stylesheet" href="screen.css" media="screen">-->
<style media="screen">
html, body {
height: 100%;
width: 100%;
margin: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
background-color: #f9f9f9;
font: 100% / 162% verdana, arial, helvetica, sans-serif;
}
#container {
position: relative;
display: inline-block;
border: 0.25em solid #56fefe;
border-radius: 0.75em;
background: #060200;
box-shadow: 0.5em 0.5em 0.5em rgba( 0, 0, 0, 0.4 );
}
#container ul {
position: absolute;
z-index: 2;
top: 50%;
left: 50%;
transform: translate( -50%, -50% );
margin: 0;
padding: 0;
list-style: none;
color: #fff;
}
.ring {
stroke: #56fefe;
stroke-width: 2;
}
</style>
</head>
<body>
<div id="container">
<svg height="0" width="0">
<defs>
<filter id="glow">
<feGaussianBlur stdDeviation="10" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
</svg>
<ul>
<li>item 1</li>
</ul>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
(function() {
'use strict';
// Configuration
const maxRadius = 100;
const gap = 10;
const padding = 25;
const height = (maxRadius + padding) * 2;
const width = (maxRadius + padding) * 2;
// Random data
const dataSet = [
{
value: 34,
total: 100
},
{
value: 21,
total: 100
},
{
value: 353,
total: 520
},
{
value: 35,
total: 340
}
];
// Append SVG element to body
const svg = d3.select('#container')
.append('svg')
.attr('height', height)
.attr('width', width)
.attr('class', 'rings');
// Append a bunch of circle elements based on number of items in the dataSet and set attributes
const rings = svg.selectAll('circle')
.data(dataSet)
.enter()
.append('circle')
.attr('cx', width/2)
.attr('cy', height/2)
.attr('fill', 'none')
.attr('class', 'ring');
// Build the initial state of the rings
rings.each(function(d, i) {
const element = this;
const radius = maxRadius - (gap * i);
// Calculates the circumference of the circle
const length = Math.PI * (radius * 2);
// Calculate the percentage of the data.value over data.total
const value = (d.value/d.total) * length;
// Animates the stroke depending on the percentage calculated
d3.select(element)
.attr('r', radius)
.attr('stroke-dasharray', length)
.attr('stroke-dashoffset', length)
.transition()
.duration(2000)
.attr('stroke-dashoffset', value);
});
function rotate(element) {
// Randomiser to set the direction of the rotation
const s = (Math.floor(Math.random() * 11) % 2 === 0 ? '-' : '');
// Initial position of rings
element.transform('r0, ' + width/2 + ',' + height/2);
// Randomised rotation animation which recursively calls itself as a callback
element.animate({ transform: 'r' + s + '360, ' + width/2 + ',' + height/2 },
(Math.random() * 1000) + 2000,
mina.linear, () => rotate(element));
};
// Rotating animation using Snap.svg
rings.each(function() {
const element = this;
// Start the animation
rotate(Snap(element));
})
}());
</script>
</body>
</html>
coothead
Ah, I see now. I did not have snap.svg linked to it.
Thank you very much. It is working now.
No problem, you’re very welcome.
Your actual problem was here…
// Append SVG element to body
const svg = d3.select('body')
…which I changed to …
// Append SVG element to body
const svg = d3.select('#container')
…the id of the div container.
coothead
I see. Thanks for pointing that out.
And how can I clone and add this same graph/svg to another HTML element (<ul> or <li>
)?
I’ve tried adding new IDs and creating extra variables for rings and the svg itself but I can’t get it to show up twice on my page.
The goal is to have each
<li>
s in total.Hi there AlexTechFlow,
try it like this…
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">
<title>untitled document</title>
<!--<link rel="stylesheet" href="screen.css" media="screen">-->
<style media="screen">
html, body {
height: 100%;
margin:0;
}
body {
display: flex;
align-items: center;
background-color: #f9f9f9;
font: 100% / 162% verdana, arial, helvetica, sans-serif;
overflow: hidden;
}
#container {
display: flex;
justify-content: center;
flex-direction: row;
flex-wrap: wrap;
max-width: 31em;
padding: 0;
margin: 1em auto;
list-style: none;
animation: spin 12s infinite linear;
}
#container li {
position: relative;
display: inline-block;
margin: 0.5em;
border: 0.25em solid #56fefe;
border-radius: 50%;
background: #060200;
box-shadow: 0.5em 0.5em 0.5em rgba( 0, 0, 0, 0.4 );
}
#container li span{
position: absolute;
z-index: 2;
top: 40%;
left: 30%;
font-size: 1.1em;
font-weight: bold;
color: #fff;
animation: spin2 12s infinite linear;
}
.ring {
stroke: #56fefe;
stroke-width: 2;
}
@keyframes spin {
0% {
transform: rotateZ( 0 );
}
100% {
transform: rotateZ( 360deg );
}
}
@keyframes spin2 {
0% {
transform: rotateZ( 0 );
}
100% {
transform: rotateZ( -360deg );
}
}
</style>
</head>
<body>
<ul id="container">
<li>
<svg height="0" width="0">
<defs>
<filter>
<feGaussianBlur stdDeviation="10" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
</svg>
<span>item 1</span>
</li><li>
<svg height="0" width="0">
<defs>
<filter>
<feGaussianBlur stdDeviation="10" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
</svg>
<span>item 2</span>
</li><li>
<svg height="0" width="0">
<defs>
<filter>
<feGaussianBlur stdDeviation="10" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
</svg>
<span>item 3</span>
</li>
</ul>
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
(function() {
'use strict';
// Configuration
const maxRadius = 60;
const gap = 10;
const padding = 20;
const height = (maxRadius + padding) * 2;
const width = (maxRadius + padding) * 2;
// Random data
const dataSet = [
{
value: 34,
total: 100
},
{
value: 21,
total: 100
},
{
value: 353,
total: 520
},
{
value: 35,
total: 340
}
];
// Append SVG element to body
const svg = d3.selectAll('#container li')
.append('svg')
.attr('height', height)
.attr('width', width)
.attr('class', 'rings');
// Append a bunch of circle elements based on number of items in the dataSet and set attributes
const rings = svg.selectAll('circle')
.data(dataSet)
.enter()
.append('circle')
.attr('cx', width/2)
.attr('cy', height/2)
.attr('fill', 'none')
.attr('class', 'ring');
// Build the initial state of the rings
rings.each(function(d, i) {
const element = this;
const radius = maxRadius - (gap * i);
// Calculates the circumference of the circle
const length = Math.PI * (radius * 2);
// Calculate the percentage of the data.value over data.total
const value = (d.value/d.total) * length;
// Animates the stroke depending on the percentage calculated
d3.select(element)
.attr('r', radius)
.attr('stroke-dasharray', length)
.attr('stroke-dashoffset', length)
.transition()
.duration(2000)
.attr('stroke-dashoffset', value);
});
function rotate(element) {
// Randomiser to set the direction of the rotation
const s = (Math.floor(Math.random() * 11) % 2 === 0 ? '-' : '');
// Initial position of rings
element.transform('r0, ' + width/2 + ',' + height/2);
// Randomised rotation animation which recursively calls itself as a callback
element.animate({ transform: 'r' + s + '360, ' + width/2 + ',' + height/2 },
(Math.random() * 1000) + 2000,
mina.linear, () => rotate(element));
};
// Rotating animation using Snap.svg
rings.each(function() {
const element = this;
// Start the animation
rotate(Snap(element));
})
}());
</script>
</body>
</html>
coothead
This is working also. Thank you very much
So I see that you changed the location for the svg
// Append SVG element to body
const svg = d3.select('#container li')
And then added a copy of the original svg to each li.
I tried to create #container2 and ran into trouble (no animation displayed).
// Append SVG element to body
const svg = d3.select('#container', '#container2')
But it is working well now with each <li>
animated. This is exactly what I was going after. Thank you so much!
No that would not have worked.
I actually used …
const svg = d3.selectAll('#container li')
coothead
Ah, I see. I need to learn more D3.js
Thanks for your help.
This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.