D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
AlexDaGr8
Full window
Github gist
Linking scatter plots and bar charts
Data from http://roycekimmons.com/tools/generated_data/exams
<!DOCTYPE html> <body> <script src="https://d3js.org/d3.v5.min.js"></script> <script src="histoChart.js"></script> <script src="scatterChart.js"></script> <script> var m = [40, 30, 40, 40], w = 960 - m[1] - m[3], h = 500 - m[0] - m[2], wTrip = w/3 - m[1], hTrip = h/2 - m[0]; var x = d3.scaleLinear() .range([0,wTrip]) .domain([0,100]), y = d3.scaleLinear() .range([hTrip,0]) .domain([0,100]), z = d3.scaleLinear() .range([5,20]) .domain([0,100]), color = d3.scaleOrdinal(d3.schemeDark2); var svg = d3.select("body").append("svg") .attr("width", w + m[1] + m[3]) .attr("height", h + m[0] + m[2]) .append("g") .attr("transform", "translate(" + m[3] + "," + m[0] + ")"); //d3.csv('exams.csv') // .then(data => render(data)) d3.csv('examsLess.csv') .then(data => render(data)) function render(data) { data.forEach(d => { d.math = +d.math; d.reading = +d.reading; d.writing = +d.writing; }); console.log(data) var scatterRadius = 1.5, colorScheme = d3.schemeDark2, type = 'ethnicity'; var scatMathReading = d3.scatter() .width(wTrip) .height(hTrip) .scheme(colorScheme) .xVal('math') .yVal('reading') .colorVal(type) .radius(scatterRadius) var scatMathWriting = d3.scatter() .width(wTrip) .height(hTrip) .scheme(colorScheme) .xVal('math') .yVal('writing') .colorVal(type) .radius(scatterRadius) var scatReadingWriting = d3.scatter() .width(wTrip) .height(hTrip) .scheme(colorScheme) .xVal('reading') .yVal('writing') .colorVal(type) .radius(scatterRadius) var mathHisto = d3.histoChart() .width(wTrip) .height(hTrip) .colorScheme(colorScheme) .binVal(d => d.math) .colorVal(type); var readingHisto = d3.histoChart() .width(wTrip) .height(hTrip) .colorScheme(colorScheme) .binVal(d => d.reading) .colorVal(type); var writingHisto = d3.histoChart() .width(wTrip) .height(hTrip) .colorScheme(colorScheme) .binVal(d => d.writing) .colorVal(type); scatMathReading.update([ {chart: scatMathWriting, type: 'data'}, {chart: scatReadingWriting, type: 'data'}, {chart: mathHisto, type: 'data'}, {chart: readingHisto, type: 'data'}, {chart: writingHisto, type: 'data'} ]); scatMathWriting.update([ {chart: scatMathReading, type: 'data'}, {chart: scatReadingWriting, type: 'data'}, {chart: mathHisto, type: 'data'}, {chart: readingHisto, type: 'data'}, {chart: writingHisto, type: 'data'} ]) scatReadingWriting.update([ {chart: scatMathReading, type: 'data'}, {chart: scatMathWriting, type: 'data'}, {chart: mathHisto, type: 'data'}, {chart: readingHisto, type: 'data'}, {chart: writingHisto, type: 'data'} ]) var nest = d3.nest() .key(d => d[type]) .entries(data); var colors = d3.scaleOrdinal(colorScheme) .domain(nest.map(d => d.key)); var legend = svg.append('g') .selectAll('g.legendItem') .data(nest) .enter().append('g') .attr('class', d => d.key.replace(/\s|\//, '')) .on('click', function(a,b,c) { console.log('a', a) console.log('b', b) console.log('c', c) var g = d3.select(c[b]) if (g.select('rect').attr('fill') === '#bbb') { g.select('rect') .attr('fill', d => colors(d.key)) scatMathReading.updateData(data) scatMathWriting.updateData(data) scatReadingWriting.updateData(data) mathHisto.updateData(data) readingHisto.updateData(data) writingHisto.updateData(data) } else { g.select('rect') .attr('fill', '#bbb') scatMathReading.updateData(a.values) scatMathWriting.updateData(a.values) scatReadingWriting.updateData(a.values) mathHisto.updateData(a.values) readingHisto.updateData(a.values) writingHisto.updateData(a.values) } }) legend.append('rect') .attr('x', 0) .attr('y', 0) .attr('width', 10) .attr('height', 10) .attr('stroke', function (d) { return colors(d.key); }) .attr('stroke-width', 2) .attr('fill', function (d) { return colors(d.key); }); legend.append('text') .text(function (d) { return d.key.replace(/^\w/, c => c.toUpperCase()); }) .attr('x', 15) .attr('y', 10); var moveLegend = 0; legend.each(function (g) { var gDiv = svg.select('g.' + g.key.replace(/\s|\//, '')); var gWidth = gDiv.node().getBoundingClientRect().width + 10; moveLegend += gWidth; gDiv.attr('transform', 'translate(' + [(moveLegend - gWidth) + 40, 0] + ')'); }); svg.append("g") .attr('transform', 'translate(' + 0 + ',' + m[0] + ')' ) .datum(data) .call(scatMathReading) svg.append("g") .attr('transform', 'translate(' + (wTrip + m[1]) + ',' + m[0] + ')' ) .datum(data) .call(scatMathWriting) svg.append("g") .attr('transform', 'translate(' + (wTrip + m[1])*2 + ',' + m[0] + ')' ) .datum(data) .call(scatReadingWriting) svg.append("g") .attr('transform', 'translate(' + 0 + ',' + (hTrip + m[0]*2) + ')' ) .datum(data) .call(mathHisto) svg.append("g") .attr('transform', 'translate(' + (wTrip + m[1]) + ',' + (hTrip + m[0]*2) + ')' ) .datum(data) .call(readingHisto) svg.append("g") .attr('transform', 'translate(' + (wTrip + m[1])*2 + ',' + (hTrip + m[0]*2) + ')' ) .datum(data) .call(writingHisto) function renderWithType(str) { } } </script> </body> </html>
https://d3js.org/d3.v5.min.js