Skip to content

Instantly share code, notes, and snippets.

@bhvaleri
Created April 3, 2015 22:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bhvaleri/dc976f091acced61c6e4 to your computer and use it in GitHub Desktop.
Save bhvaleri/dc976f091acced61c6e4 to your computer and use it in GitHub Desktop.
Bars vs Lines
<!DOCTYPE html>
<html>
<style>
rect {
fill: tomato
}
.minWidthBar {
background-color: tomato;
height: 50px;
}
.line {
fill: none;
stroke: tomato
}
.minWidthBar {
margin: 0 auto;
}
.minWidthBarContainer {
width: 100px;
}
.widthAdjust {
width: 100%;
}
</style>
<script src="http://d3js.org/d3.v3.js"></script>
<body>
<svg></svg>
<div class="minWidthBarContainer">
<input type="range" min=0 max=10 oninput="updateMinBarWidth(this.value)" class='widthAdjust'>
<div class='minWidthBar'></div>
</div>
</body>
<script>
var margin = { top: 0, right: 30, bottom: 30, left: 30 };
var height = 300 - margin.top - margin.bottom;
var svg = d3.select('svg')
.attr('height', height + margin.top + margin.bottom).append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var mainLayer = svg.append('g').attr('class', 'mainLayer');
var path = mainLayer.append('path')
.attr('class', 'line');
var yRange = [0, 200];
var days = 365;
var minBarWidth = 2;
var updateMinBarWidth = function (newWidth) {
document.getElementsByClassName('minWidthBar')[0].style.width = newWidth + 'px';
minBarWidth = newWidth;
updateWithNewWidth();
};
var giveMeThisMuch = function(n) {
var endingDay = new Date();
var startingDay = (new Date()).setDate(-n); //very sure this is slightly wrong
var dateRange = d3.time.days(startingDay, endingDay);
var dataToGive = [];
dateRange.forEach(function(date) {
dataToGive.push( { x: date,y: Math.random() * yRange[1] })
});
return dataToGive;
}
var data = giveMeThisMuch(days);
var currentBarWidth = function(data, width) {
return width / data.length;
};
var drawBars = function (data, width) {
var mainLayer = svg.select('.mainLayer');
var bars = mainLayer.selectAll('rect').data(data);
bars.enter().append('rect');
var barWidth = currentBarWidth(data, width);
bars.transition().style('opacity', 1).attr('height', function(d) { return yScale(d.y); })
.attr('width', barWidth)
.attr('y', function(d) { return height - yScale(d.y); })
.attr('x', function(d) { return xScale(d.x); });
}
var line = d3.svg.line()
.x(function(d) { return xScale(d.x); })
.y(function(d) { return yScale(d.y); });
var drawLine = function (data) {
path.datum(data)
.transition()
.style('opacity', 1)
.attr('d', line);
}
var fadeLine = function () {
path.transition().style('opacity', 0);
}
var fadeBars = function () {
var mainLayer = svg.select('.mainLayer');
var bars = mainLayer.selectAll('rect');
bars.transition().style('opacity', 0);
};
var xScale = d3.time.scale();
var yScale = d3.scale.linear();
var xAxis = d3.svg.axis()
.tickFormat(function(d) { return d.getDate(); })
.orient('bottom');
var xAxisLayer = svg.append('g').attr('class', 'x axis')
.attr('transform', 'translate(0,' + height + ')');
var updateWithNewWidth = function () {
var screenWidth = window.innerWidth;
var width = screenWidth - margin.left - margin.right
d3.select('svg').attr('width', width + margin.left + margin.right)
xScale.domain(d3.extent(data, function(d) { return d.x; }))
.range([0, width]);
yScale.domain([0, d3.max(data, function(d) { return d.y; })])
.range([height, 0])
.nice();
var tickValues = data.map(function(d) { return d.x; });
xAxis.scale(xScale)
xAxisLayer.transition().call(xAxis);
if (currentBarWidth(data, width) < minBarWidth) {
fadeBars();
drawLine(data);
}
else {
fadeLine();
drawBars(data, width);
}
}
updateMinBarWidth(minBarWidth);
d3.select(window).on('resize', updateWithNewWidth);
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment