barChart = (dataset) => {
const width = 1000;
const height = 400;
const svg = d3.create('svg')
.attr('width', width)
.attr('height', height);
const barsMargin = {
left: 30,
right: 20,
between: 4,
top: 20,
bottom: 60
};
let yScale = d3.scaleLinear()
.domain(d3.extent(dataset, d => d.pick_rate))
.range([height - barsMargin.bottom, barsMargin.top]);
const xScale = d3.scaleBand()
.domain(dataset.map((d) => d.hero))
.range([barsMargin.left, width - barsMargin.right]);
let barWidth = (width - barsMargin.left - barsMargin.right) / 30 - barsMargin.between;
console.log(barWidth);
const updateChart = (chartType, rankLimit) => {
svg.selectAll('rect')
.data(dataset)
.join(
enter => enter.append('rect')
.filter(d => {return d.rank == "All"})
.attr('x', d => xScale(d.hero) + barsMargin.between / 2)
.attr('height', d => height - barsMargin.bottom - yScale(d.pick_rate))
.attr('width', barWidth)
.attr('y', d => yScale(d.pick_rate)),
update => {
switch(chartType){
default:
yScale = d3.scaleLinear()
.domain(d3.extent(dataset, d => d.pick_rate))
.range([height - barsMargin.bottom, barsMargin.top]);
update.transition()
.duration(2000)
.filter(d => {return d.rank == rankLimit})
.attr('y', d => yScale(d.pick_rate))
.attr('x', d => xScale(d.hero) + barsMargin.between / 2)
.attr('height', d => height - barsMargin.bottom - yScale(d.pick_rate))
.attr('width', barWidth);
break;
case 'win_rate':
yScale = d3.scaleLinear()
.domain(d3.extent(dataset, d => d.win_rate))
.range([height - barsMargin.bottom, barsMargin.top]);
update.transition()
.duration(2000)
.filter(d => {return d.rank == rankLimit})
.attr('y', d => yScale(d.win_rate))
.attr('x', d => xScale(d.hero) + barsMargin.between / 2)
.attr('height', d => height - barsMargin.bottom - yScale(d.win_rate))
.attr('width', barWidth);
break;
case 'tie_rate':
yScale = d3.scaleLinear()
.domain(d3.extent(dataset, d => d.tie_rate))
.range([height - barsMargin.bottom, barsMargin.top]);
update.transition()
.duration(2000)
.filter(d => {return d.rank == rankLimit})
.attr('y', d => yScale(d.tie_rate))
.attr('x', d => xScale(d.hero) + barsMargin.between / 2)
.attr('height', d => height - barsMargin.bottom - yScale(d.tie_rate))
.attr('width', barWidth);
break;
};
},
exit => exit.transition()
.duration(2000)
.attr('x', -50)
.attr('y', -50)
.attr('height', 0)
.attr('width', 0)
.remove());
xAxisGroup.transition().duration(2000).call(d3.axisBottom(xScale)).selectAll('text').attr('transform', 'rotate(-65)').style('text-anchor', 'end');
yAxisGroup.transition().duration(2000).call(d3.axisLeft(yScale));
}
const xAxis = d3.axisBottom(xScale);
const xAxisGroup = svg.append('g')
.attr('transform', `translate(0, ${height - barsMargin.bottom})`)
.call(xAxis);
const yAxis = d3.axisLeft(yScale);
const yAxisGroup = svg.append('g')
.attr('transform', `translate(30, 0)`)
.call(yAxis);
updateChart('pick_rate', 'All');
const typeSelector = html`
<select id='chartType'>
<option value="pick_rate">Pick Rate</option>
<option value="win_rate">Win Rate</option>
<option value="tie_rate">Tie Rate</option>
</select>
`;
const rankSelector = html`
<select id='rankLimit'>
<option value="All">All</option>
<option value="Bronze">Bronze</option>
<option value="Silver">Silver</option>
<option value="Gold">Gold</option>
<option value="Diamond">Diamond</option>
<option value="Platinum">Platinum</option>
<option value="Master">Master</option>
<option value="Grandmaster">Grandmaster</option>
</select>
`;
d3.select(typeSelector).on('change', () => {
updateChart(typeSelector.value, rankSelector.value);
});
d3.select(rankSelector).on('change', () => {
updateChart(typeSelector.value, rankSelector.value);
});
return html`
<div class='chart-div'>
<h3>Nintendo Switch Game Sales</h3>
<label>Sort By:</label>
${typeSelector}
<label>Filter by Rank:</label>
${rankSelector}
${svg.node()}
</div>
`;
}