function init() { var margin = 150; //equal margins on all sides var width = window.screen.width - 2 * margin; var height = 700 - 2 * margin; var x = d3.scaleTime().range([0, width]); var y = d3.scaleLinear().range([height, 0]); var yLog = d3.scaleLog().clamp(true).range([height, 0]); var ySqrt = d3.scaleSqrt().range([height, 0]); var timeParser = d3.timeFormat("%b %Y"); var dateParse = d3.timeParse("%Y-%m-%d"); var legends = [ "Catan", "Dominion", "Codenames", "Terraforming Mars", "Gloomhaven", "Magic: The Gathering", "Dixit", "Monopoly", ]; function lineGraphs(i) { return d3 .line() .x(function (d) { return x(dateParse(d.date)); }) .y(function (d) { return y(+d[legends[i]]); }); } function lineGraphsLog(i) { return d3 .line() .x(function (d) { return x(dateParse(d.date)); }) .y(function (d) { return yLog(+d[legends[i]]); }); } function lineGraphsSqrt(i) { return d3 .line() .x(function (d) { return x(dateParse(d.date)); }) .y(function (d) { return ySqrt(+d[legends[i]]); }); } var svg_a = d3.select("body").append("svg").attr("id", "svg-a"); var svgFig1 = svg_a .attr("class", "fig1") .attr("width", width + 2 * margin) .attr("height", height + 2 * margin) .append("g") .attr("id", "plot-a") .attr("transform", "translate(" + margin + "," + margin + ")"); var g_plot_a = svgFig1; var g_x_axis_a = g_plot_a.append("g").attr("id", "x-axis-a"); var g_y_axis_a = g_plot_a.append("g").attr("id", "y-axis-a"); var g_lines_a = g_plot_a.append("g").attr("id", "lines-a"); var text_title_a = svg_a.append("text").attr("id", "title-a"); d3.select("body").append("div").attr("class", "pagebreak"); var svg_b = d3.select("body").append("svg").attr("id", "svg-b"); var svgFig2 = svg_b .attr("class", "fig1") .attr("width", width + 2 * margin) .attr("height", height + 2 * margin) .append("g") .attr("id", "plot-b") .attr("transform", "translate(" + margin + "," + margin + ")"); var g_plot_b = svgFig2; var g_x_axis_b = g_plot_b.append("g").attr("id", "x-axis-b"); var g_y_axis_b = g_plot_b.append("g").attr("id", "y-axis-b"); var g_lines_b = g_plot_b.append("g").attr("id", "lines-b"); var g_symbols_b = g_plot_b.append("g").attr("id", "symbols-b"); var text_title_b = svg_b.append("text").attr("id", "title-b"); var g_legend_b = svg_b .append("g") .attr("id", "legend-b") .attr("transform", "translate(200,170)"); d3.select("body").append("div").attr("class", "pagebreak"); // var svg_c_1 = d3.select("body").append("svg").attr("id", "svg-c-1"); var svgFig4 = svg_c_1 .attr("class", "fig1") .attr("width", width + 2 * margin) .attr("height", height + 2 * margin) .append("g") .attr("id", "plot-c-1") .attr("transform", "translate(" + margin + "," + margin + ")"); var g_plot_c_1 = svgFig4; var g_x_axis_c_1 = g_plot_c_1.append("g").attr("id", "x-axis-c-1"); var g_y_axis_c_1 = g_plot_c_1.append("g").attr("id", "y-axis-c-1"); var g_lines_c_1 = g_plot_c_1.append("g").attr("id", "lines-c-1"); var g_symbols_c_1 = g_plot_c_1.append("g").attr("id", "symbols-c-1"); var text_title_c_1 = svg_c_1.append("text").attr("id", "title-c-1"); var g_legend_c_1 = svg_c_1 .append("g") .attr("id", "legend-c-1") .attr("transform", "translate(200,170)"); // d3.select("body").append("div").attr("class", "pagebreak"); var svg_c_2 = d3.select("body").append("svg").attr("id", "svg-c-2"); var svgFig3 = svg_c_2 .attr("class", "fig1") .attr("width", width + 2 * margin) .attr("height", height + 2 * margin) .append("g") .attr("id", "plot-c-2") .attr("transform", "translate(" + margin + "," + margin + ")"); var g_plot_c_2 = svgFig3; var g_x_axis_c_2 = g_plot_c_2.append("g").attr("id", "x-axis-c-2"); var g_y_axis_c_2 = g_plot_c_2.append("g").attr("id", "y-axis-c-2"); var g_lines_c_2 = g_plot_c_2.append("g").attr("id", "lines-c-2"); var g_symbols_c_2 = g_plot_c_2.append("g").attr("id", "symbols-c-2"); var text_title_c_2 = svg_c_2.append("text").attr("id", "title-c-2"); var g_legend_c_2 = svg_c_2 .append("g") .attr("id", "legend-c-2") .attr("transform", "translate(200,170)"); d3.select("body").append("div").attr("class", "pagebreak"); d3.select("body").append("div").attr("id", "signature").text("tlou31"); d3.dsv(",", "boardgame_ratings.csv", function (d) { var obj = { month: timeParser(new Date(d.date)), date: d.date, }; for (var i in legends) { obj[legends[i]] = +d[legends[i] + "=count"]; obj[legends[i] + "=rank"] = +d[legends[i] + "=rank"]; } return obj; }) .then(function (data) { var minMax = findMinMax(data); var min = minMax[0], max = minMax[1]; x.domain( d3.extent(data, function (d) { return dateParse(d.date); }) ); y.domain([min, max]); yLog.domain([min, max]); ySqrt.domain([min, max]); for (var i in legends) { var lg = lineGraphs(i); var lgLog = lineGraphsLog(i); var lgSqrt = lineGraphsSqrt(i); g_lines_a .append("path") .data([data]) .attr("class", "line") .attr("d", lg) .style("stroke", d3.schemeCategory10[i]) // .append("text") // .text(legends[i]); g_lines_a .append("text") .attr( "transform", "translate(" + (width + 10) + "," + y(data[data.length - 1][legends[i]]) + ")" ) .attr("text-anchor", "start") .style("fill", d3.schemeCategory10[i]) .text(legends[i]); g_lines_b .append("path") .data([data]) .attr("class", "line") .attr("d", lg) .style("stroke", d3.schemeCategory10[i]) // .append("text") // .text(legends[i]); g_lines_b .append("text") .attr( "transform", "translate(" + (width + 10) + "," + y(data[data.length - 1][legends[i]]) + ")" ) .attr("text-anchor", "start") .style("fill", d3.schemeCategory10[i]) .text(legends[i]); g_lines_c_1 .append("path") .data([data]) .attr("class", "line") .attr("d", lgSqrt) .style("stroke", d3.schemeCategory10[i]) // .append("text") // .text(legends[i]); g_lines_c_1 .append("text") .attr( "transform", "translate(" + (width + 10) + "," + ySqrt(data[data.length - 1][legends[i]]) + ")" ) .attr("text-anchor", "start") .style("fill", d3.schemeCategory10[i]) .text(legends[i]); g_lines_c_2 .append("path") .data([data]) .attr("class", "line") .attr("d", lgLog) .style("stroke", d3.schemeCategory10[i]) // .append("text") // .text(legends[i]); g_lines_c_2 .append("text") .attr( "transform", "translate(" + (width + 10) + "," + yLog(data[data.length - 1][legends[i]]) + ")" ) .attr("text-anchor", "start") .style("fill", d3.schemeCategory10[i]) .text(legends[i]); if ( ["Catan", "Codenames", "Terraforming Mars", "Gloomhaven"].includes( legends[i] ) ) { g_symbols_b .selectAll("circles") .data(data) .enter() .append("circle") .filter(function (d, iter) { return iter % 3 === 2; }) .attr("fill", d3.schemeCategory10[i]) .attr("cx", function (d) { return x(dateParse(d.date)); }) .attr("cy", function (d) { return y(d[legends[i]]); }) .attr("r", 10); g_symbols_b .selectAll("circles") .data(data) .enter() .filter(function (d, iter) { return iter % 3 === 2; }) .append("text") .attr("class", "count-font") .text(function (d) { return d[legends[i] + "=rank"]; }) .attr("x", function (d) { return x(dateParse(d.date)) - 5; }) .attr("y", function (d) { return y(d[legends[i]]) + 5; }); g_symbols_c_1 .selectAll("circles") .data(data) .enter() .filter(function (d, iter) { return iter % 3 === 2; }) .append("circle") .attr("fill", d3.schemeCategory10[i]) .attr("cx", function (d) { return x(dateParse(d.date)); }) .attr("cy", function (d) { return ySqrt(d[legends[i]]); }) .attr("r", 10); g_symbols_c_1 .selectAll("circles") .data(data) .enter() .filter(function (d, iter) { return iter % 3 === 2; }) .append("text") .attr("class", "count-font") .text(function (d) { return d[legends[i] + "=rank"]; }) .attr("x", function (d) { return x(dateParse(d.date)) - 5; }) .attr("y", function (d) { return ySqrt(d[legends[i]]) + 5; }); g_symbols_c_2 .selectAll("circles") .data(data) .enter() .filter(function (d, iter) { return iter % 3 === 2; }) .append("circle") .attr("fill", d3.schemeCategory10[i]) .attr("cx", function (d) { return x(dateParse(d.date)); }) .attr("cy", function (d) { return yLog(d[legends[i]]); }) .attr("r", 10); g_symbols_c_2 .selectAll("circles") .data(data) .enter() .filter(function (d, iter) { return iter % 3 === 2; }) .append("text") .attr("class", "count-font") .text(function (d) { return d[legends[i] + "=rank"]; }) .attr("x", function (d) { return x(dateParse(d.date)) - 5; }) .attr("y", function (d) { return yLog(d[legends[i]]) + 5; }); } } g_legend_b .append("circle") .attr("fill", "black") .attr( "transform", "translate(" + (width + 20) + "," + (height - 30) + ")" ) .attr("r", 10); g_legend_b .append("text") .attr("class", "count-font") .attr( "transform", "translate(" + (width + 10) + "," + (height - 27) + ")" ) .text("RANK"); g_legend_b .append("text") .attr( "transform", "translate(" + (width - 30) + "," + (height - 10) + ")" ) .text("BoardGameGeek Rank"); g_legend_c_1 .append("circle") .attr("fill", "black") .attr( "transform", "translate(" + (width + 20) + "," + (height - 30) + ")" ) .attr("r", 10); g_legend_c_1 .append("text") .attr("class", "count-font") .attr( "transform", "translate(" + (width + 10) + "," + (height - 27) + ")" ) .text("RANK"); g_legend_c_1 .append("text") .attr( "transform", "translate(" + (width - 30) + "," + (height - 10) + ")" ) .text("BoardGameGeek Rank"); g_legend_c_2 .append("circle") .attr("fill", "black") .attr( "transform", "translate(" + (width + 20) + "," + (height - 30) + ")" ) .attr("r", 10); g_legend_c_2 .append("text") .attr("class", "count-font") .attr( "transform", "translate(" + (width + 10) + "," + (height - 27) + ")" ) .text("RANK"); g_legend_c_2 .append("text") .attr( "transform", "translate(" + (width - 30) + "," + (height - 10) + ")" ) .text("BoardGameGeek Rank"); g_x_axis_a .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x).tickFormat(d3.timeFormat("%b %y"))); g_y_axis_a.call(d3.axisLeft(y)); g_x_axis_b .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x).tickFormat(d3.timeFormat("%b %y"))); g_y_axis_b.call(d3.axisLeft(y)); g_x_axis_c_1 .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x).tickFormat(d3.timeFormat("%b %y"))); g_y_axis_c_1.call(d3.axisLeft(ySqrt)); g_x_axis_c_2 .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x).tickFormat(d3.timeFormat("%b %y"))); g_y_axis_c_2.call(d3.axisLeft(yLog)); function findMinMax(data) { var min = Number.POSITIVE_INFINITY; var max = Number.NEGATIVE_INFINITY; for (var j in data) { var datum = data[j]; for (var i in legends) { if (datum[legends[i]] < min) min = datum[legends[i]]; if (datum[legends[i]] > max) max = datum[legends[i]]; } } return [min, max]; } g_x_axis_a .append("text") .attr( "transform", "translate(" + width / 2 + " ," + (height + 30) + ")" ) .style("text-anchor", "middle") .text("Month"); g_y_axis_a .append("text") .attr("y", -50) .attr("x", -height / 2) .attr("transform", "rotate(-90)") .style("text-anchor", "middle") .text("Number of Ratings"); text_title_a .attr("x", width / 2) .attr("y", 50) .attr("text-anchor", "middle") .style("font-size", "16px") .text("Number of Ratings 2016-2020"); g_x_axis_b .append("text") .attr( "transform", "translate(" + width / 2 + " ," + (height + 30) + ")" ) .style("text-anchor", "middle") .text("Month"); g_y_axis_b .append("text") .attr("y", -50) .attr("x", -height / 2) .attr("transform", "rotate(-90)") .style("text-anchor", "middle") .text("Number of Ratings"); text_title_b .attr("x", width / 2) .attr("y", 50) .attr("text-anchor", "middle") .style("font-size", "16px") .text("Number of Ratings 2016-2020 with Rankings"); g_x_axis_c_1 .append("text") .attr( "transform", "translate(" + width / 2 + " ," + (height + 30) + ")" ) .style("text-anchor", "middle") .text("Month"); g_y_axis_c_1 .append("text") .attr("y", -50) .attr("x", -height / 2) .attr("transform", "rotate(-90)") .style("text-anchor", "middle") .text("Number of Ratings"); text_title_c_1 .attr("x", width / 2) .attr("y", 50) .attr("text-anchor", "middle") .style("font-size", "16px") .text( "Number of Ratings 2016-2020 with Rankings (Square Root Scale) svg_c_1, svgFig4" ); g_x_axis_c_2 .append("text") .attr( "transform", "translate(" + width / 2 + " ," + (height + 30) + ")" ) .style("text-anchor", "middle") .text("Month"); g_y_axis_c_2 .append("text") .attr("y", -50) .attr("x", -height / 2) .attr("transform", "rotate(-90)") .style("text-anchor", "middle") .text("Number of Ratings"); text_title_c_2 .attr("x", width / 2) .attr("y", 50) .attr("text-anchor", "middle") .style("font-size", "16px") .text("Number of Ratings 2016-2020 with Rankings (Log Scale) svgFig3"); }) .catch(function (error) { console.log(error); }); }