Built with blockbuilder.org
forked from sandravizmad's block: scaled circles
forked from danielbilitewski's block: 1_grapes
forked from danielbilitewski's block: scaling_doesnt_work
forked from danielbilitewski's block: Top 10 Highest Priced Wines
| license: mit |
Built with blockbuilder.org
forked from sandravizmad's block: scaled circles
forked from danielbilitewski's block: 1_grapes
forked from danielbilitewski's block: scaling_doesnt_work
forked from danielbilitewski's block: Top 10 Highest Priced Wines
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <!-- Google fonts Second Reference--> | |
| <link href="https://fonts.googleapis.com/css?family=Open+Sans:700&display=swap" rel="stylesheet"> | |
| <!-- Connecting with D3 library--> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <!-- Creating the headlines --> | |
| <p id="h1"> Top 10 Highest Priced Wines </p> | |
| <p id="h2"> Group by Grape or Country | Size by Points of Price</p> | |
| <!-- Creating the buttons --> | |
| <!-- Switch circle radius from points to price --> | |
| <button id="start_pp" style="position: absolute; margin-left: 300px; margin-top: 0px;">PRICE</button> | |
| <!-- Switch circle radius back to points --> | |
| <button id="reset_pp" style="position: absolute; margin-left: 400px; margin-top: 0px;">POINTS</button> | |
| <!-- Switch grouping from country to grape --> | |
| <button id="start_cv" style="position: absolute; margin-left: 0px; margin-top: 0px;">GRAPE</button> | |
| <!-- Switch grouping back to country --> | |
| <button id="reset_cv" style="position: absolute; margin-left: 100px; margin-top: 0px;">COUNTRY</button> | |
| <style> | |
| /* Defining text stylings*/ | |
| #h1 { | |
| font-size: 32px; | |
| margin: 0px 0px 2px 0px; | |
| font-family: 'Open+Sans', sans-serif; | |
| font-weight: 300; | |
| font-variant: small-caps slashed-zero; | |
| color: #f20675; | |
| } | |
| #h2 { | |
| font-size: 18px; | |
| margin: 0px 0px 0px 0px; | |
| font-family: 'Open+Sans', sans-serif; | |
| font-weight: 80; | |
| font-variant: small-caps slashed-zero; | |
| color: #1ce3cd; | |
| } | |
| body { | |
| background-color:#111111; | |
| } | |
| /* Defining chart stylings */ | |
| circle { | |
| fill: #f20675; | |
| stroke: #f20675; | |
| stroke-width: 2; | |
| opacity:0.7; | |
| } | |
| text { | |
| font-family: 'Open+Sans', sans-serif; | |
| font-size: 12px; | |
| font-variant: small-caps slashed-zero; | |
| fill: #cccccc; | |
| } | |
| .tooltip { | |
| font-family: 'Open+Sans', sans-serif; | |
| font-size: 20px; | |
| font-variant: small-caps slashed-zero; | |
| color: #0000ff; | |
| } | |
| /* Defining button stylings | |
| taken from https://bl.ocks.org/sandravizmad/7e052342a7847094e541a917869e6f42 */ | |
| /* Button styling for points-price switch */ | |
| #start_pp, #reset_pp { | |
| font-family: 'Barlow', sans-serif; | |
| font-size: 20px; | |
| font-weight: 200; | |
| color: #cccccc; | |
| border: 0; | |
| line-height: 1.5; | |
| padding: 0 5px; | |
| text-align: center; | |
| border-radius: 1px; | |
| background-color: #111111; | |
| } | |
| #start_pp:hover, #reset_pp:hover { | |
| color: #111111; | |
| background-color: #f20675; | |
| } | |
| /* Button styling for country-grape switch */ | |
| #start_cv, #reset_cv { | |
| font-family: 'Barlow', sans-serif; | |
| font-size: 20px; | |
| font-weight: 200; | |
| color: #cccccc; | |
| border: 0; | |
| line-height: 1.5; | |
| padding: 0 5px; | |
| text-align: center; | |
| border-radius: 1px; | |
| background-color: #111111; | |
| } | |
| #start_cv:hover, #reset_cv:hover { | |
| color: #111111; | |
| background-color: #f20675; | |
| } | |
| </style> | |
| <script> | |
| // Margin conventions | |
| var margin = {top: 80, right: 20, bottom: 30, left: 30}, | |
| width = 1000 - margin.left - margin.right, | |
| height = 550 - margin.top - margin.bottom; | |
| // Container | |
| var svg = d3.select("body") | |
| .append("svg") | |
| .attr("width", width + margin.left + margin.right) | |
| .attr("height", height + margin.top + margin.bottom) | |
| .append("g") | |
| .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
| // Read Data | |
| d3.csv('https://gist.githubusercontent.com/linacarrillo23/10d6089d80be3628f279c39eed2cba6b/raw/6a3dd5f8cbc79af99a7f93a43da5aa04f05e9f98/top_10_wines_short', prepare, function(data){ | |
| /* Size scale for price and points using square root to make the area of the circle | |
| proportional to the number of points or the price */ | |
| var scale_price = d3.scaleSqrt() | |
| .domain([d3.min(data, d=>d.price), | |
| d3.max(data, d=>d.price)]) | |
| .range([10, 40]); | |
| var scale_points = d3.scaleSqrt() | |
| .domain([d3.min(data, d=>d.points), | |
| d3.max(data, d=>d.points)]) | |
| .range([10, 40]); | |
| /* Mapping of the categorical variables for country and grape (column called "variety") | |
| on a numerical scale */ | |
| var country = d3.scalePoint() | |
| .domain(data.map(d => d.country)) | |
| .range([0, 300]) | |
| var variety = d3.scalePoint() | |
| .domain(data.map(d => d.variety)) | |
| .range([0, 300]) | |
| //Defining the tooltip | |
| var tt = svg.append("g") | |
| .attr("class", "tooltip") | |
| .style("display", "none"); | |
| tt.append("text") | |
| .attr("x", -7) | |
| .attr("y", -20) | |
| .style("font-size","30") | |
| .style("font-weight","bold"); | |
| //Mousemove function for points | |
| function mousemove_points (d) { | |
| tt.style('visibility', 'visible') | |
| .style("display", null); | |
| var xPos = d3.mouse(this)[0]; | |
| var yPos = d3.mouse(this)[1]; | |
| tt.attr("transform", "translate("+xPos+","+yPos+")"); | |
| tt.select("text") | |
| .text("Points: " + d.points); | |
| ;} | |
| //Mousemove function for price | |
| function mousemove_price (d) { | |
| tt.style('visibility', 'visible') | |
| .style("display", null); | |
| var xPos = d3.mouse(this)[0]; | |
| var yPos = d3.mouse(this)[1]; | |
| tt.attr("transform", "translate("+xPos+","+yPos+")"); | |
| tt.select("text") | |
| .text("Price: $" + d.price); | |
| ;} | |
| /* Draw the circles | |
| x-axis is equidistant | |
| y-axis based on the groupings (default: country, transition: grape) | |
| radius based on the points or the price (default: points, transition: price) */ | |
| var circle = svg.selectAll("circle") | |
| .data(data) | |
| .enter() | |
| .append("circle") | |
| .attr("cx", (d, i) => 200+i*75) | |
| .attr("cy", d => country(d.country)) | |
| .attr("r", d => scale_points(d.points)) | |
| .on("mousemove", mousemove_points) | |
| .on("mouseout",() => tt.style("visibility", "hidden")); | |
| /* Create axis label | |
| y-axis same as the circles | |
| text shows the grouping (default: country, transition: grape) */ | |
| var axis = svg.selectAll("text") | |
| .data(data) | |
| .enter() | |
| .append("text") | |
| .text(d => d.country) | |
| .attr("x", 75) | |
| .attr("y", d => country(d.country)) | |
| .style("text-anchor", "middle") | |
| .style("font-size", 15); | |
| // Transition points -> price | |
| d3.select("#start_pp") | |
| .on("click", function() { | |
| circle | |
| .transition() | |
| .duration(1000) | |
| .attr("r", d => scale_price(d.price)) | |
| circle | |
| .on("mousemove", mousemove_price) | |
| .on("mouseout",() => tt.style("visibility", "hidden")); | |
| }); | |
| // Transition price -> points | |
| d3.select("#reset_pp") | |
| .on("click", function() { | |
| circle | |
| .transition() | |
| .duration(2000) | |
| .attr("r", d => scale_points(d.points)) | |
| circle | |
| .on("mousemove", mousemove_points) | |
| .on("mouseout",() => tt.style("visibility", "hidden")); | |
| }); | |
| // Transition country -> grape | |
| d3.select("#start_cv") | |
| .on("click", function() { | |
| circle | |
| .transition() | |
| .duration(2000) | |
| .attr("cy", d => variety(d.variety)) | |
| axis | |
| .transition() | |
| .duration(2000) | |
| .text(d => d.variety) | |
| .attr("y", d => variety(d.variety)) | |
| }); | |
| // Transition grape -> country | |
| d3.select("#reset_cv") | |
| .on("click", function() { | |
| circle | |
| .transition() | |
| .duration(2000) | |
| .attr("cy", d => country(d.country)) | |
| axis | |
| .transition() | |
| .duration(2000) | |
| .text(d => d.country) | |
| .attr("y", d => country(d.country)) | |
| }); | |
| }) | |
| // Make sure all variables are numbers | |
| function prepare (d) { | |
| d.price = +d.price; | |
| d.points = +d.points; | |
| return d; | |
| } | |
| </script> | |