Built with blockbuilder.org
forked from kudabux's block: fresh block
| license: mit |
Built with blockbuilder.org
forked from kudabux's block: fresh block
| <!DOCTYPE html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <style> | |
| body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
| </style> | |
| </head> | |
| <body> | |
| <script> | |
| const data = [ | |
| { | |
| step: 'Mars', | |
| complexity: 10, | |
| task: 'Task 1', | |
| }, | |
| { | |
| step: 'Jupiter', | |
| complexity: 60, | |
| task: 'Task 1', | |
| }, | |
| { | |
| step: 'Neptune', | |
| complexity: 10, | |
| task: 'Task 1', | |
| }, | |
| { | |
| step: 'Venus', | |
| complexity: 25, | |
| task: 'Task 1', | |
| }, | |
| { | |
| step: 'Mars', | |
| complexity: 30, | |
| task: 'Task 2', | |
| }, | |
| { | |
| step: 'Jupiter', | |
| complexity: 10, | |
| task: 'Task 2', | |
| }, | |
| { | |
| step: 'Neptune', | |
| complexity: 50, | |
| task: 'Task 2', | |
| }, | |
| { | |
| step: 'Mars', | |
| complexity: 20, | |
| task: 'Task 3', | |
| }, | |
| { | |
| step: 'Jupiter', | |
| complexity: 40, | |
| task: 'Task 3', | |
| }, | |
| { | |
| step: 'Mars', | |
| complexity: 45, | |
| task: 'Task 4', | |
| }, | |
| { | |
| step: 'Jupiter', | |
| complexity: 60, | |
| task: 'Task 4', | |
| }, | |
| { | |
| step: 'Mars', | |
| complexity: 35, | |
| task: 'Task 5', | |
| }, | |
| { | |
| step: 'Jupiter', | |
| complexity: 30, | |
| task: 'Task 5', | |
| }, | |
| { | |
| step: 'Neptune', | |
| complexity: 50, | |
| task: 'Task 5', | |
| }, | |
| ]; | |
| //================================================================ | |
| // Prep work | |
| //================================================================ | |
| const svg = d3 | |
| .select('body') | |
| .append('svg') | |
| .attr('width', 600) | |
| .attr('height', 180); | |
| const margin = {top: 20, right: 20, bottom: 30, left: 40}; | |
| const width = +svg.attr('width') - margin.left - margin.right; | |
| const height = +svg.attr('height') - margin.top - margin.bottom; | |
| const chartContainer = svg | |
| .append('g') | |
| .attr('transform', `translate(${margin.left}, ${margin.top})`) | |
| .attr('class', 'chart'); | |
| function getUniqueKeys(dataset, key) { | |
| return dataset | |
| .map((dataset) => dataset[key]) | |
| .filter((element, index, self) => index === self.indexOf(element)); | |
| } | |
| const groups = getUniqueKeys(data, 'task'); | |
| //================================================================ | |
| // Scales | |
| //================================================================ | |
| const xGroupScale = d3 | |
| .scaleBand() | |
| .domain(groups) | |
| .rangeRound([0, width]) | |
| .padding(0.1); | |
| const xBarScale = d3 | |
| .scaleBand() | |
| .domain(data.map((data) => data.step)) | |
| .rangeRound([0, xGroupScale.bandwidth()]) | |
| .padding(0.2); | |
| const yScale = d3 | |
| .scaleLinear() | |
| .domain([0, d3.max(data, (data) => data.complexity)]) | |
| .rangeRound([height, 0]); | |
| const colorScale = d3 | |
| .scaleOrdinal() | |
| .range([ | |
| 'rgb(32, 213, 210)', | |
| 'rgb(169, 112, 255)', | |
| 'rgb(0, 88, 161)', | |
| 'rgb(108, 202, 255)', | |
| 'rgb(238, 83, 139)', | |
| 'rgb(0, 97, 97)', | |
| 'rgb(216, 216, 216)', | |
| ]); | |
| //================================================================ | |
| // Bars | |
| //================================================================ | |
| const barGroup = chartContainer | |
| .append('g') | |
| .attr('class', 'bar-groups') | |
| .selectAll('g') | |
| .data(groups) | |
| .enter() | |
| .append('g') | |
| .attr('class', (data) => `${data}`) | |
| .attr('transform', (data) => `translate(${xGroupScale(data)}, 0)`); | |
| const bar = barGroup | |
| .selectAll('rect') | |
| .data(data) | |
| .enter() | |
| .append('rect') | |
| .attr('class', 'bar') | |
| .attr('x', (data) => xBarScale(data.step)) | |
| .attr('y', (data) => yScale(data.complexity)) | |
| .attr('width', xBarScale.bandwidth()) | |
| .attr('height', (data) => height - yScale(data.complexity)) | |
| .style('fill', (data) => colorScale(data.step)); | |
| //================================================================ | |
| // Axis | |
| //================================================================ | |
| chartContainer | |
| .append('g') | |
| .attr('class', 'axis axis--x') | |
| .attr('transform', `translate(0, ${height})`) | |
| .call(d3.axisBottom(xGroupScale)); | |
| chartContainer | |
| .append('g') | |
| .attr('class', 'axis axis--y') | |
| .call(d3.axisLeft(yScale).ticks(8)); | |
| chartContainer | |
| .selectAll('.axis') | |
| .selectAll('path') | |
| .style('stroke', 'none'); | |
| </script> | |
| </body> |