Week5: Coding Challenge | kenbunroku | Observable
•ojs
•ojs
•ojs
Comments (1)
Zach Pino
Oct 2, 2020
{ const width = 800; const height = 800; const margin = 100; // create SVG artboard, background const svg = d3 .create('svg') .attr('viewBox', [0, 0, width, height]) .attr('width', width) .attr('heigth', height); const bg = svg .append('rect') .attr('x', 0) .attr('y', 0) .attr('width', width) .attr('height', height); // draw axis svg .append('polyline') .attr("points", [ [margin, margin], [margin, height - margin], [width - margin, height - margin] ]) .attr('stroke-width', 3) .attr('stroke', 'white'); //scales for converting data to pixels let xScale = d3 .scaleLinear() .domain(d3.extent(cereals, d => parseFloat(d.calories))) .range([margin, width - margin]); let yScale = d3 .scaleLinear() .domain(d3.extent(cereals, d => parseFloat(d.potass))) .range([height - margin, margin]); // scales for converting data to colormaps let colorScale = d3 .scaleLinear() .domain(d3.extent(cereals, d => parseFloat(d.rating))) .range([0, 1]); // use a data join to create the circles and place an color them with data svg .selectAll('.cerealCircle') .data(cereals) .enter() .append('circle') .attr('cx', d => xScale(d.calories)) .attr('cy', d => yScale(d.potass)) .attr('fill', d => d3.interpolatePlasma(colorScale(d.rating))) .attr('r', 10) .attr('class', 'cerealCircle') // update the text area, add a stroke to themselves when a circle is hovered .on('mouseover', function(d) { d3.select(this) .raise() .transition() .duration(1) .attr('stroke', 'white') .attr('stroke-width', 3); d3.select('#infoBlock') .transition() .duration(1) .text(
d.name
+ ' : Rating ' + (parseFloat(d.rating).toFixed(2))); }) // go back to the original text, remove a stroke when a circle is hovered off .on('mouseout', function(d) { d3.select(this) .transition() .duration(300) .attr('stroke-width', 0); d3.select('#infoBlock') .transition() .duration(300) .text('Hover over a circle!'); }); // Create a text area to show which cereal circle is hovered const infoText = svg .append('text') .attr('x', width / 2) .attr('y', height - margin / 2) .attr('fill', 'white') .attr('text-anchor', 'middle') .attr('font-size', 20) .attr('font-family', 'helvetica') .attr('id', 'infoBlock') .text('Hover over a circle!'); svg .append('text') .attr('x', margin) .attr('y', margin / 2) .attr('fill', 'white') .attr('font-size', 15) .attr('font-family', 'helvetica') .text('X-Axis:'); svg .append('text') .attr('x', width / 2 + margin) .attr('y', margin / 2) .attr('fill', 'white') .attr('font-size', 15) .attr('font-family', 'helvetica') .text('Y-Axis:'); let xChoices = [{name:"Sugar",value:"sugars"},{name:"Calories",value:"calories"},{name:"Fat", value:"fat"}]; // create all x buttons svg .selectAll('.xChoice') .data(xChoices) .enter() .append('text') .attr('x', margin + 60) .attr('y', (d,i) => ((i+1)/4 * margin)) .attr('fill', 'white') .attr('font-size', 15) .attr('font-family', 'helvetica') .text(d =>
d.name
) .on('click', function(xC) { xScale = d3 .scaleLinear() //.domain(d3.extent(cereals, d => parseFloat(d[xC.value]))) .domain([0,d3.max(cereals, d => parseFloat(d[xC.value]))]) .range([margin, width - margin]); d3.selectAll('.cerealCircle') .data(cereals) .transition() .duration(1000) .ease(d3.easeCubicInOut) .attr('cx', d => xScale(parseFloat(d[xC.value]))); }); // create vitamins button svg .append('text') .attr('x', width / 2 + margin + 60) .attr('y', 20) .attr('fill', 'white') .attr('font-size', 15) .attr('font-family', 'helvetica') .text('Vitamins') .on('click', function(d) { yScale = d3 .scaleLinear() .domain(d3.extent(cereals, d => parseFloat(d.vitamins))) .range([height - margin, margin]); d3.selectAll('.cerealCircle') .data(cereals) .transition() .duration(1000) .ease(d3.easeCubicInOut) .attr('cy', d => yScale(d.vitamins)); }); // create potassium button svg .append('text') .attr('x', width / 2 + margin + 60) .attr('y', 20 + 30) .attr('fill', 'white') .attr('font-size', 15) .attr('font-family', 'helvetica') .text('Potassium') .on('click', function(d) { yScale = d3 .scaleLinear() .domain(d3.extent(cereals, d => parseFloat(d.potass))) .range([height - margin, margin]); d3.selectAll('.cerealCircle') .data(cereals) .transition() .duration(1000) .ease(d3.easeCubicInOut) .attr('cy', d => yScale(d.potass)); }); // create protein button svg .append('text') .attr('x', width / 2 + margin + 60) .attr('y', 20 + 60) .attr('fill', 'white') .attr('font-size', 15) .attr('font-family', 'helvetica') .text('Protein') .on('click', function(d) { yScale = d3 .scaleLinear() .domain(d3.extent(cereals, d => parseFloat(d.protein))) .range([height - margin, margin]); d3.selectAll('.cerealCircle') .data(cereals) .transition() .duration(1000) .ease(d3.easeCubicInOut) .attr('cy', d => yScale(d.protein)); }); return svg.node(); }
Reply
Add comment
Subscribe to notifications
Observable
Sign in
kenbunroku
0
Reply
Add comment
Subscribe to notifications
0
Week5: Coding Challenge | kenbunroku | Observable