Public
Edited
May 2, 2024
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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>
`;
}
Insert cell
html`<style>


.chart-div {
text-align: center;
margin:auto;
padding:10px;
}

.chart-div svg {
display: block;
margin: auto;
padding: 20px;
}

.axis-left1 line,
.axis-left1 path {
stroke: none;
}

.axis-left1 text {
font-weight: bold;
font-size: 7pt;
text-transform: uppercase;
}

.dot-label {
font-size: 8pt;
}

</style>`
Insert cell
Insert cell
Insert cell
overwatch-openrefine.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
dataFile = await FileAttachment("overwatch-openrefine.csv").text();
Insert cell
d3 = require("d3@7")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more