Skip to content

Instantly share code, notes, and snippets.

@jermspeaks
Last active October 16, 2015 17:16
Show Gist options
  • Save jermspeaks/9902b56ec6dc1a3c5b25 to your computer and use it in GitHub Desktop.
Save jermspeaks/9902b56ec6dc1a3c5b25 to your computer and use it in GitHub Desktop.
fun block
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
svg { width: 100%; height: 100%; }
</style>
</head>
<body>
<div class="container"></div>
<script>
/* =======================================
Attributes
======================================= */
var w = $(window).width() - 200;
var h = 200;
// Padding
var textPadding = 10;
var rightEdgePadding = 40;
var leftViewButtonPadding = 5;
var rightViewButtonPadding = 10;
// Text Line Height
var lineHeight = 8;
// Label Value Formatter
var valueFormatter = d3.format('.2s');
// Element Widths
var yAxisLabelWidth = 100;
var viewButtonWidth = 75;
// Start Position for Bars
var startBars = viewButtonWidth + yAxisLabelWidth;
// End Position for Y Axis Labels
var endYAxisLabels = viewButtonWidth + yAxisLabelWidth - textPadding;
// Color of Selected Group
var selectedColor = '150,222,136';
// Find Start Position for Bar Label
function startBarLabelPosition(d) {
return viewButtonWidth + yAxisLabelWidth + xScale(d) + textPadding;
}
/* =======================================
Data
======================================= */
var dataset = {
data: [{
value: 934,
category: '10+ Page Views',
color: '186, 38, 43'
}, {
value: 6000,
category: '5-9 Page Views',
color: '212, 80, 51'
}, {
value: 12000,
category: '2-4 Page Views',
color: '246, 142, 53'
}, {
value: 48000,
category: '1 Page View',
color: '255,190,55'
}, {
value: 64000,
category: 'All',
color: '35,80,116'
}],
// data: [934, 6000, 12000, 48000, 64000],
// categories: ['10+ Page Views', '5-9 Page Views', '2-4 Page Views', '1 Page View', 'All'],
// colors: ['186, 38, 43', '212,80,51', '246,142,53', '255,190,55', '35,80,116', '150,222,136'],
selected: 0
};
/* =======================================
Scales
======================================= */
// Max Range for width of bars
var maxRange = w - viewButtonWidth - yAxisLabelWidth - rightEdgePadding;
var xScale = d3.scale.linear()
.domain([0, d3.max(dataset.data, function(d) {
return d.value;
})])
.range([10, maxRange]);
var yScale = d3.scale.ordinal()
.domain(d3.range(dataset.data.length))
.rangeRoundBands([0, h], 0.2);
/* =======================================
SVG Element
======================================= */
var svg = d3.select('.container')
.append('svg')
.attr('width', w)
.attr('height', h);
// .style('border', '1px solid black');
// Create Chart
createChart();
/* =======================================
Event Handlers
======================================= */
// Mouse Events
function createBarEvents() {
svg.selectAll('.bar')
.on('mouseover', function(d, i) {
d3.select(this)
.attr('fill', function(d) {
var index = dataset.data.indexOf(d);
return 'rgba(' + dataset.data[index].color + ', 0.4)';
});
})
.on('mouseout', function(d, i) {
d3.select(this)
.attr('fill', function(d, i) {
var index = dataset.data.indexOf(d);
return 'rgb(' + dataset.data[index].color + ')';
});
});
}
function createViewButtonEvents() {
svg.selectAll('.view-button-group')
.on('mouseover', function(d, i) {
d3.select(this).select('rect')
.attr('fill', function(d) {
return 'rgba(' + dataset.data[2].color + ', 0.4)';
});
d3.select(this).select('text')
.attr('fill', 'black');
})
.on('mouseout', function(d, i) {
d3.select(this).select('rect')
.attr('fill', function(d) {
return 'rgb(' + dataset.data[2].color + ')';
});
d3.select(this).select('text')
.attr('fill', 'white');
})
.on('click', function(d, i) {
event.preventDefault();
console.log(d);
// remove view button
// insert new selected bar group
// insert view button in previously selected bar group
});
}
// On Window Resize
window.onresize = function(event) {
// Update Width
w = $(window).width() - 200;
// Update Max Range
maxRange = w - viewButtonWidth - yAxisLabelWidth - rightEdgePadding;
// Update xScale
xScale = d3.scale.linear()
.domain([0, d3.max(dataset.data, function(d) {
return d.value;
})])
.range([10, maxRange]);
// Resize SVG
svg.attr('width', w);
// Resize Bar Labels
svg.selectAll(".bar-label")
.data(dataset.data)
.transition()
.delay(function(d, i) {
return i / dataset.data.length * 1000;
})
.duration(150)
.attr("x", function(d, i) {
return startBarLabelPosition(d.value);
});
// Resize Bars
svg.selectAll('.bar')
.data(dataset.data)
.transition()
.delay(function(d, i) {
return i / dataset.data.length * 1000;
})
.duration(200)
.ease('linear')
.attr('width', function(d) {
return xScale(d.value);
});
};
/* =======================================
Chart Generation Functions
======================================= */
function createChart() {
selectedBarGroup();
createBarGroups();
createBarEvents();
createViewButtonEvents();
selectedBarGroup();
}
function createBarGroups() {
var barGroups = svg.selectAll('.bar-group')
.data(dataset.data)
.enter()
.append("g")
.classed("bar-group", true);
createBar(barGroups);
createYAxisLabel(barGroups);
createBarLabel(barGroups);
createViewButton(barGroups);
removeViewButton(barGroups);
}
// Create Bar
function createBar(groupSelector) {
groupSelector.append('rect')
.classed('bar', true)
.attr('x', viewButtonWidth + yAxisLabelWidth)
.attr('y', function(d, i) {
return yScale(i);
})
.attr('width', function(d) {
return xScale(d.value);
})
.attr('height', yScale.rangeBand())
.attr('fill', function(d, i) {
return 'rgb(' + d.color + ')';
});
}
// Create yAxis Labels
function createYAxisLabel(groupSelector) {
groupSelector.append("text")
.classed('xAxis-label', true)
.text(function(d, i) {
return d.category;
})
.attr("x", 90 + viewButtonWidth)
.attr("y", function(d, i) {
return yScale(i) + (lineHeight / 2) + (yScale.rangeBand() / 2);
})
.attr("font-family", "sans-serif")
.attr("font-size", "12px")
.attr("fill", "black")
.style({
"text-anchor": "end"
});
}
// Create Bar Labels
function createBarLabel(groupSelector) {
groupSelector.append("text")
.classed('bar-label', true)
.text(function(d, i) {
return valueFormatter(d.value);
})
.attr("x", function(d, i) {
return startBarLabelPosition(d.value);
})
.attr("y", function(d, i) {
return yScale(i) + (lineHeight / 2) + (yScale.rangeBand() / 2);
})
.attr("font-family", "sans-serif")
.attr("font-size", "12px")
.attr("font-weight", 600)
.attr("fill", "black");
}
// View Buttons
function createViewButton(groupSelector) {
var viewButtonGroup = groupSelector.append("g")
.classed("view-button-group", true)
.style({
'cursor': 'pointer'
});
// View Button Rectangle
viewButtonGroup.append("rect")
.classed('view-button', true)
.attr("x", leftViewButtonPadding)
.attr("y", function(d, i) {
return yScale(i);
})
.attr("width", viewButtonWidth - rightViewButtonPadding)
.attr("height", yScale.rangeBand())
.attr("rx", 5)
.attr("ry", 5)
.attr("fill", function(d) {
return 'rgb(' + dataset.data[2].color + ')';
});
// View Button Text
viewButtonGroup.append("text")
.classed('view-text', true)
.text('View')
.attr("x", (leftViewButtonPadding + (viewButtonWidth - rightViewButtonPadding)) / 2)
.attr("y", function(d, i) {
return yScale(i) + (lineHeight / 2) + (yScale.rangeBand() / 2);
})
.attr("font-family", "sans-serif")
.attr("font-size", "12px")
.attr("fill", "white")
.attr("text-anchor", "middle");
}
// Remove Selected View Button
function removeViewButton(groupSelector) {
groupSelector.each(function(d, i) {
if (i === dataset.selected) {
d3.select(this).select('.view-button-group').remove();
}
})
}
// Selected Bar Group Rectangle
function selectedBarGroup() {
var selectedBarGroup = svg.selectAll('.selected-bar-group')
.data([dataset.selected])
.enter()
.append("g")
.classed("selected-bar-group", true)
selectedBarGroup.append("rect")
.classed('selected-bar-overlay', true)
.attr("x", leftViewButtonPadding)
.attr("y", function(d, i) {
return yScale(d);
})
.attr("width", viewButtonWidth + yAxisLabelWidth - rightViewButtonPadding)
.attr("height", yScale.rangeBand())
.attr("rx", 5)
.attr("ry", 5)
.attr("fill", function(d) {
return 'rgb(' + selectedColor + ')';
});
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment