Skip to content

Instantly share code, notes, and snippets.

@csessig86
Last active May 11, 2016 16:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save csessig86/ae48abdd5c3cdee572dd to your computer and use it in GitHub Desktop.
Save csessig86/ae48abdd5c3cdee572dd to your computer and use it in GitHub Desktop.
D3: Split icons into columns
<htmL>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-1.12.1.min.js" charset="utf-8"></script>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<style>
#svg-table, #svg-container {
width: 100%;
height: 100%;
}
#tr-svg {
height: 75%;
}
#tr-btn {
height: 25%;
text-align: center;
}
</style>
</head>
<body>
<table id="svg-table">
<tr id="tr-svg">
<td>
<svg id="svg-container">
<defs>
<g id="doctor">
<circle fill="#636464" cx="24" cy="9.6" r="9.6"/>
<path fill="#636464" d="M33.9,43.5c-1.2,0-2.2-1-2.2-2.2s1-2.2,2.2-2.2c0.6,0,1.2,0.2,1.6,0.6c0.8-0.4,1.3-0.8,1.4-1
c0-0.6-0.2-3.5-1.3-6.3c-1.3-3.2-3.2-4.8-5.8-4.8c-2.5,0-4.5,1.6-5.8,4.8c-1.1,2.7-1.3,5.6-1.3,6.3c0,0.2,0.6,0.6,1.4,1
c0.4-0.4,1-0.6,1.6-0.6c1.2,0,2.2,1,2.2,2.2s-1,2.2-2.2,2.2c-1,0-1.8-0.6-2.1-1.5c-2.9-1.2-3.1-2.8-3.1-3.3
c0-2.7,1.4-12.3,8.3-13.3c0-0.6,0-1.9-0.4-3.2H17c-0.9,1-1.2,2.3-1.2,3.7c1.9,0.2,3.5,1.6,4,3.5c0.5,2.5-1,4.9-3.5,5.5
c-2.5,0.5-4.9-1-5.5-3.5c-0.5-2.2,0.7-4.4,2.7-5.2c0-1.3,0.1-2.7,0.7-4h-0.6C6.1,22.2,0,28.6,0,36.4v32.8c0,0.7,0.1,1.3,0.4,1.9
c0.7,1.6,2.4,2.8,4.3,2.8c2.6,0,4.7-2.1,4.7-4.7v-0.4V37.9h1.8v30.3v55.9c0,3.2,2.6,5.9,5.9,5.9c3.2,0,5.9-2.6,5.9-5.9V75.2h2.2
v48.9c0,3.2,2.6,5.9,5.9,5.9c3.2,0,5.9-2.6,5.9-5.9V57.2V41.6c-0.3,0.1-0.6,0.3-0.9,0.4C35.7,42.9,34.9,43.5,33.9,43.5z"/>
<path fill="#636464" d="M34.3,22.2h-3.7c0.3,1.3,0.3,2.6,0.3,3.2c6.8,1,8.2,10.6,8.2,13.3c0,0.2-0.1,0.7-0.4,1.3v16.6v12.6
c0,2.6,2.1,4.7,4.7,4.7c2.6,0,4.7-2.1,4.7-4.7V54.5V36.4C48,28.6,41.9,22.2,34.3,22.2z"/>
<path fill="#636464" d="M12.9,31c0.3,1.3,1.6,2.1,2.9,1.8c1.3-0.3,2.1-1.6,1.8-2.9c-0.3-1.3-1.6-2.1-2.9-1.8
C13.5,28.4,12.7,29.7,12.9,31z M15,29.2c0.7-0.1,1.3,0.3,1.5,0.9c0.1,0.7-0.3,1.3-0.9,1.5c-0.7,0.1-1.3-0.3-1.5-0.9
C13.9,30,14.4,29.4,15,29.2z"/>
</g>
</defs>
</svg>
</td>
</tr>
<tr id="tr-btn">
<td>
<div id="click" class="btn btn-primary">Click here</div>
</td>
</tr>
</table>
<script>
var height = $(window).height() * 0.75;
var width = $(window).width();
// Info on size of doctor icons
// So we can be a little dynamic
// These shouldn't be changed
// Unless the icon is changed
var icon_width_small = 25;
var padding_width = 5;
// Total width of icon plus padding
var width_padding_small = icon_width_small + padding_width;
var width_padding_large = (icon_width_small * 2) + padding_width;
var icon_height_small = 65;
var padding_top = 10;
// Total height of icon plus padding
var height_padding_small = icon_height_small + padding_top;
var height_padding_large = (icon_height_small * 2) + padding_top;
// Entire SVG
var svg = d3.select('svg');
// Group for doctor icons
var doctors = svg.append("g")
.attr('class', 'doctors')
.attr('transform','translate(10,10)')
// Step keeps track of icons on the DOM
// Used when we're clicking
// These shouldn't be changed
var step = 0;
var total_step = 0;
var data = [];
var rows = 0;
// How many icons per row
// Before we go to another row
var row_length = 4;
// Number of columns were breaking the icons into
var columns_length = 3;
// In order for the clicks to work, we need the data array
// To be the same length as column_length
// Ex: If column_length is 3, data should be: [0,1,2]
for (var num = 0; num < columns_length; num ++ ) {
data[num] = num;
}
// Duration, delay info
var duration_length = 500;
var delay_length = 100;
// The icon that is eventually transitioned
var doctor;
// Add large icon to DOM
function addIcon() {
doctor = doctors.selectAll()
.data(data)
.enter()
.append("g")
.attr({
transform: function(d) {
return "translate(" + (width / 2 - (width_padding_large / 2)) + "," + (height_padding_small * 3) + ") scale(1)";
},
opacity: 0
})
// Grab svg path from defs and append to DOM
doctor.append("use")
.attr("xlink:href","#doctor")
doctor.transition()
.duration(duration_length - delay_length)
.attr({
opacity: 1
})
}
// Transition large doctor icon to smaller icon
function transitionIcon() {
doctor.transition()
.delay(delay_length)
.duration(duration_length)
.ease("sin-in-out")
.attr({
transform: function(d) {
// We're placing the icons in three different columns
// This calcluates where the icons need to be placed within those column
// It divides the width of the SVG by three to get the three column positions
// Then multiplies it by the data value of the icon, which is either 0, 1 or 2
// This allows the icons to spread across the DOM
var columns = d * (width / columns_length + (row_length / 2 * width_padding_small) );
// The first icon in each row
if (step % row_length === 0) {
var translate_one = columns;
// To prevent the second, third, etc. icon from being placed on top of the first icon
// We add the width plus padding times the step to have the icons appear next to each other
} else {
var translate_one = columns + (width_padding_small * step)
}
return "translate(" + translate_one + "," + (rows * height_padding_small) + ") scale(0.5)";
},
})
}
// Add another icon every click
function clickToAdd() {
// Transition icon
transitionIcon();
// Every several icons we are going to create a new row
// And place the icons on that row
if (step > 0 && step % (row_length - 1) === 0) {
step = -1;
rows += 1;
}
// Keeps track of what icon we're on
// So we can create new rows
step += 1;
total_step += 1;
// Add another to DOM
setTimeout(addIcon, duration_length + delay_length);
// Close icon add
};
// Add initial icon
addIcon();
// Click event
$('#click').click(function() {
clickToAdd();
})
</script>
</body>
</htmL>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment