makeChart = (dataset) => {
dataset = [...dataset];
dataset.sort((a,b) => b.downloads - a.downloads);
const width = 1000;
const height = 600;
const marginTop = 25;
const marginRight = 20;
const marginBottom = 200;
const marginLeft = 60;
let x = d3.scaleBand()
.domain(dataset.map((d) => d.title))
.range([marginLeft, width - marginRight]);
const y = d3.scaleLinear()
.domain(d3.extent(dataset, d => d.copies_sold)).nice()
.range([height - marginBottom, marginTop]);
const r = d3.scaleRadial()
.domain(d3.extent(dataset, d => d.copies_sold)).nice()
.range([0, 25]);
let c = d3.scaleLinear()
.domain(d3.extent(dataset, d => d.copies_sold)).nice()
.range(['#ff0000', '#00f0ff']);
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height])
.attr("style", "max-width: 100%; height: auto;");
// Add the axes.
let xAxisGroup = svg.append("g")
.attr("transform", `translate(0,${height - marginBottom})`)
.call(d3.axisBottom().scale(x))
let yAxisGroup = svg.append("g")
.attr("transform", `translate(${marginLeft},0)`)
.call(d3.axisLeft(y));
// Append a rect for each data point.
/*svg.append("g")
.selectAll("rect")
.data(dataset)
.join("rect")
.filter(d => d.copies_sold)
.attr("x", (d) => x(new Date(d.release_date)))
.attr("y", (d) => y(d.copies_sold))
.attr("width", (d) => x(new Date(d.release_date)) - marginRight)
.attr("height", (d) => height - y(d.copies_sold) - marginBottom)
.style("fill", (d) => c(d.copies_sold))
.style("stroke", "black"); */
const updateChartType = (newType) => {
console.log(newType);
switch(newType) {
default:
x = d3.scaleBand()
.domain(dataset.map((d) => d.title))
.range([marginLeft, width - marginRight]);
break;
case 'release_date':
x = d3.scaleTime()
.domain(d3.extent(dataset, d => new Date(d.release_date))).nice()
.range([marginLeft, width - marginRight]);
break;
case 'developer':
x = d3.scaleBand()
.domain(dataset.map((d) => d.developer))
.range([marginLeft, width - marginRight]);
break;
case 'publisher':
x = d3.scaleBand()
.domain(dataset.map((d) => d.publisher))
.range([marginLeft, width - marginRight]);
break;
};
svg
.selectAll('circle')
.data(dataset)
.join(
enter => enter.append('circle')
.filter(d => d.copies_sold)
.attr("cx", (d) => x(d.title))
.attr("cy", (d) => y(d.copies_sold))
.attr("r", (d) => r(d.copies_sold))
.style("fill", (d) => c(d.copies_sold)),
update => update.transition()
.duration(2000)
.filter(d => d.copies_sold)
.attr("cx", (d) => {
let result;
switch(newType){
default:
result = x(d.title);
break;
case 'release_date':
result = x(new Date(d.release_date));
break;
case 'developer':
result = x(d.developer);
break;
case 'publisher':
result = x(d.publisher);
break;
};
return result;
}
)
.attr("cy", (d) => y(d.copies_sold))
.attr("r", (d) => r(d.copies_sold))
.style("fill", (d) => c(d.copies_sold))
);
xAxisGroup.transition().duration(2000).call(d3.axisBottom(x)).selectAll('text').attr('transform', 'rotate(-65)').style('text-anchor', 'end');
yAxisGroup.transition().duration(2000).call(d3.axisLeft(y));
/*.join("circle")
.filter(d => d.copies_sold)
.attr("cx", (d) => x(new Date(d.release_date)))
.attr("cy", (d) => y(d.copies_sold))
.attr("r", (d) => r(d.copies_sold))
.style("fill", (d) => c(d.copies_sold)); */
};
updateChartType('downloads');
const typeSelector = html`
<select id='chartType'>
<option value="title">Title</option>
<option value="publisher">Publisher</option>
<option value="developer">Developer</option>
<option value="release_date">Release Date</option>
</select>
`;
d3.select(typeSelector).on('change', () => {
updateChartType(typeSelector.value);
});
return html`
<div class='chart-div'>
<h3>Nintendo Switch Game Sales</h3>
<label>Sort By:</label>
${typeSelector}
${svg.node()}
</div>
`;
}