Skip to content

Instantly share code, notes, and snippets.

@itsbvk
Created April 15, 2020 00:26
Show Gist options
  • Save itsbvk/eca74dfeeb0c768274294f25daf5cc89 to your computer and use it in GitHub Desktop.
Save itsbvk/eca74dfeeb0c768274294f25daf5cc89 to your computer and use it in GitHub Desktop.
fresh block
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
<style>
text{
font-size: 16px;
font-family: Open Sans, sans-serif;
}
text.title{
font-size: 24px;
font-weight: 500;
}
text.subTitle{
font-weight: 500;
fill: #777777;
}
text.caption{
font-weight: 400;
font-size: 14px;
fill: #777777;
}
text.label{
font-weight: 600;
}
text.valueLabel{
font-weight: 300;
}
text.yearText{
font-size: 64px;
font-weight: 700;
opacity: 0.25;
}
.tick text {
fill: #777777;
}
.xAxis .tick:nth-child(2) text {
text-anchor: start;
}
.tick line {
shape-rendering: CrispEdges;
stroke: #dddddd;
}
.tick line.origin{
stroke: #aaaaaa;
}
path.domain{
display: none;
}
</style>
</head>
<body>
<script>
// Feel free to change or delete any of the code you see in this editor!
var svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 600);
var tickDuration = 500;
var top_n = 12;
var height = 600;
var width = 960;
const margin = {
top: 80,
right: 0,
bottom: 5,
left: 0
};
let barPadding = (height-(margin.bottom+margin.top))/(top_n*5);
let title = svg.append('text')
.attr('class', 'title')
.attr('y', 24)
.html('18 years of Interbrand’s Top Global Brands');
let subTitle = svg.append("text")
.attr("class", "subTitle")
.attr("y", 55)
.html("Brand value, $m");
let caption = svg.append('text')
.attr('class', 'caption')
.attr('x', width)
.attr('y', height-5)
.style('text-anchor', 'end')
.html('Source: Interbrand');
let year = 2000;
d3.csv('brand_values.csv').then(function(data) {
//if (error) throw error;
console.log(data);
data.forEach(d => {
d.value = +d.value,
d.lastValue = +d.lastValue,
d.value = isNaN(d.value) ? 0 : d.value,
d.year = +d.year,
d.colour = d3.hsl(Math.random()*360,0.75,0.75)
});
console.log(data);
let yearSlice = data.filter(d => d.year == year && !isNaN(d.value))
.sort((a,b) => b.value - a.value)
.slice(0, top_n);
yearSlice.forEach((d,i) => d.rank = i);
console.log('yearSlice: ', yearSlice)
let x = d3.scaleLinear()
.domain([0, d3.max(yearSlice, d => d.value)])
.range([margin.left, width-margin.right-65]);
let y = d3.scaleLinear()
.domain([top_n, 0])
.range([height-margin.bottom, margin.top]);
let xAxis = d3.axisTop()
.scale(x)
.ticks(width > 500 ? 5:2)
.tickSize(-(height-margin.top-margin.bottom))
.tickFormat(d => d3.format(',')(d));
svg.append('g')
.attr('class', 'axis xAxis')
.attr('transform', `translate(0, ${margin.top})`)
.call(xAxis)
.selectAll('.tick line')
.classed('origin', d => d == 0);
svg.selectAll('rect.bar')
.data(yearSlice, d => d.name)
.enter()
.append('rect')
.attr('class', 'bar')
.attr('x', x(0)+1)
.attr('width', d => x(d.value)-x(0)-1)
.attr('y', d => y(d.rank)+5)
.attr('height', y(1)-y(0)-barPadding)
.style('fill', d => d.colour);
svg.selectAll('text.label')
.data(yearSlice, d => d.name)
.enter()
.append('text')
.attr('class', 'label')
.attr('x', d => x(d.value)-8)
.attr('y', d => y(d.rank)+5+((y(1)-y(0))/2)+1)
.style('text-anchor', 'end')
.html(d => d.name);
   
svg.selectAll('text.valueLabel')
.data(yearSlice, d => d.name)
.enter()
.append('text')
.attr('class', 'valueLabel')
.attr('x', d => x(d.value)+5)
.attr('y', d => y(d.rank)+5+((y(1)-y(0))/2)+1)
.text(d => d3.format(',.0f')(d.lastValue));
let yearText = svg.append('text')
.attr('class', 'yearText')
.attr('x', width-margin.right)
.attr('y', height-25)
.style('text-anchor', 'end')
.html(~~year)
.call(halo, 10);
let ticker = d3.interval(e => {
yearSlice = data.filter(d => d.year == year && !isNaN(d.value))
.sort((a,b) => b.value - a.value)
.slice(0,top_n);
yearSlice.forEach((d,i) => d.rank = i);
//console.log('IntervalYear: ', yearSlice);
x.domain([0, d3.max(yearSlice, d => d.value)]);
svg.select('.xAxis')
.transition()
.duration(tickDuration)
.ease(d3.easeLinear)
.call(xAxis);
let bars = svg.selectAll('.bar').data(yearSlice, d => d.name);
bars
.enter()
.append('rect')
.attr('class', d => `bar ${d.name.replace(/\s/g,'_')}`)
.attr('x', x(0)+1)
.attr( 'width', d => x(d.value)-x(0)-1)
.attr('y', d => y(top_n+1)+5)
.attr('height', y(1)-y(0)-barPadding)
.style('fill', d => d.colour)
.transition()
.duration(tickDuration)
.ease(d3.easeLinear)
.attr('y', d => y(d.rank)+5);
bars
.transition()
.duration(tickDuration)
.ease(d3.easeLinear)
.attr('width', d => x(d.value)-x(0)-1)
.attr('y', d => y(d.rank)+5);
bars
.exit()
.transition()
.duration(tickDuration)
.ease(d3.easeLinear)
.attr('width', d => x(d.value)-x(0)-1)
.attr('y', d => y(top_n+1)+5)
.remove();
let labels = svg.selectAll('.label')
.data(yearSlice, d => d.name);
labels
.enter()
.append('text')
.attr('class', 'label')
.attr('x', d => x(d.value)-8)
.attr('y', d => y(top_n+1)+5+((y(1)-y(0))/2))
.style('text-anchor', 'end')
.html(d => d.name)
.transition()
.duration(tickDuration)
.ease(d3.easeLinear)
.attr('y', d => y(d.rank)+5+((y(1)-y(0))/2)+1);
labels
.transition()
.duration(tickDuration)
.ease(d3.easeLinear)
.attr('x', d => x(d.value)-8)
.attr('y', d => y(d.rank)+5+((y(1)-y(0))/2)+1);
labels
.exit()
.transition()
.duration(tickDuration)
.ease(d3.easeLinear)
.attr('x', d => x(d.value)-8)
.attr('y', d => y(top_n+1)+5)
.remove();
let valueLabels = svg.selectAll('.valueLabel').data(yearSlice, d => d.name);
valueLabels
.enter()
.append('text')
.attr('class', 'valueLabel')
.attr('x', d => x(d.value)+5)
.attr('y', d => y(top_n+1)+5)
.text(d => d3.format(',.0f')(d.lastValue))
.transition()
.duration(tickDuration)
.ease(d3.easeLinear)
.attr('y', d => y(d.rank)+5+((y(1)-y(0))/2)+1);
valueLabels
.transition()
.duration(tickDuration)
.ease(d3.easeLinear)
.attr('x', d => x(d.value)+5)
.attr('y', d => y(d.rank)+5+((y(1)-y(0))/2)+1)
.tween("text", function(d) {
let i = d3.interpolateRound(d.lastValue, d.value);
return function(t) {
this.textContent = d3.format(',')(i(t));
};
});
valueLabels
.exit()
.transition()
.duration(tickDuration)
.ease(d3.easeLinear)
.attr('x', d => x(d.value)+5)
.attr('y', d => y(top_n+1)+5)
.remove();
yearText.html(~~year);
if(year == 2018) ticker.stop();
year = d3.format('.1f')((+year) + 0.1);
},tickDuration);
});
const halo = function(text, strokeWidth) {
text.select(function() { return this.parentNode.insertBefore(this.cloneNode(true), this); })
.style('fill', '#ffffff')
.style( 'stroke','#ffffff')
.style('stroke-width', strokeWidth)
.style('stroke-linejoin', 'round')
.style('opacity', 1);
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment