Last active
November 7, 2016 23:41
-
-
Save nobitagit/6606b93f38d555e148827e6f46bb4f79 to your computer and use it in GitHub Desktop.
ordinal vs quantize in D3.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://jsfiddle.net/q6xk2hqv/ | |
const data = [{ | |
val: 4, | |
month: 1, | |
voters: 22, | |
name: 'A' | |
},{ | |
val: 10, | |
month: 2, | |
voters: 12, | |
name: 'B' | |
},{ | |
val: 21, | |
month: 3, | |
voters: 55, | |
name: 'C' | |
},{ | |
val: 12, | |
month: 4, | |
voters: 33, | |
name: 'D' | |
},{ | |
val: 22, | |
month: 5, | |
voters: 11, | |
name: 'E' | |
},{ | |
val: 15, | |
month: 6, | |
voters: 29, | |
name: 'F' | |
},{ | |
val: 19, | |
month: 7, | |
voters: 43, | |
name: 'G' | |
},{ | |
val: 22, | |
month: 7, | |
voters: 3, | |
name: 'G' | |
},{ | |
val: 12, | |
month: 8, | |
voters: 51, | |
name: 'G' | |
},{ | |
val: 21, | |
month: 9, | |
voters: 21, | |
name: 'G' | |
},{ | |
val: 33, | |
month: 10, | |
voters: 3, | |
name: 'G' | |
}]; | |
const sel = d3.select('#chart') | |
var margin = {top: 40, right: 10, bottom: 20, left: 10}; | |
var width = 460 - margin.left - margin.right; | |
var height = 500 - margin.top - margin.bottom; | |
const fullWidth = width + margin.left + margin.right; | |
const fullHeight = height + margin.top + margin.bottom; | |
var svg = sel | |
.attr("width", fullWidth) | |
.attr("height", fullHeight) | |
//.attr('viewBox', `0 0 ${fullWidth} ${fullHeight}`) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
const xScale = | |
d3.scaleLinear() | |
.domain([0,d3.max(data, d => d.month)]) | |
.range([0, width]); | |
const yScale = d3.scaleLinear() | |
.domain([0, d3.max(data, d => d.val)]) | |
.range([height, 0]); | |
const rScale = d3.scaleSqrt() // NB: => scale Square root to have the right scale of radius of bubbles | |
.domain([0, d3.max(data, d => d.voters)]) | |
.range([0, 40]); // => how big we want our circles | |
var sequentialScale = d3.scaleSequential() | |
.domain([0, 55]) | |
.interpolator(d3.interpolateViridis); | |
const bubbles = svg | |
.selectAll('.bubbles') | |
.data(data) | |
.enter() | |
.append('g') | |
.classed('bubbles', 1) | |
.attr('transform', d => | |
`translate(${xScale(d.month)}, ${yScale(d.val)})` | |
) | |
bubbles | |
.append('circle') | |
.attr('cx', 0) | |
.attr('cy', 0) | |
.attr('r', d => rScale(d.voters)) | |
.style('fill-opacity', 0.8) | |
.style('fill', d => sequentialScale(d.voters)) | |
.exit() | |
const areaScale = | |
d3.area() | |
.x(d => xScale(d.month)) | |
.y0(yScale(yScale.domain()[0])) // the lowest bound of the area is the bottom of our graph, or the min value of the domain (in this case it will be 0) | |
.y1(d => yScale(d.val)) // upper bound, the normal point where the data would be plotted | |
.curve(d3.curveCatmullRom.alpha(0.5)) | |
svg | |
.append('path') | |
.classed('.areaG', 1) | |
.attr('d', areaScale(data)) | |
.style('fill', 'rgb(34, 168, 132)') | |
.style('fill-opacity', 0.7) | |
.attr('stroke', 'steelblue') | |
.attr('stroke-width', 4) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//https://jsfiddle.net/kg8jfyn0/ | |
// bar chart with rangeBand | |
const data = [{ | |
val: 4, | |
name: 'A' | |
},{ | |
val: 10, | |
name: 'B' | |
},{ | |
val: 21, | |
name: 'C' | |
},{ | |
val: 12, | |
name: 'D' | |
},{ | |
val: 22, | |
name: 'E' | |
},{ | |
val: 15, | |
name: 'F' | |
},{ | |
val: 19, | |
name: 'G' | |
}]; | |
const sel = d3.select('#chart') | |
var margin = {top: 40, right: 10, bottom: 20, left: 10}; | |
var width = 460 - margin.left - margin.right; | |
var height = 500 - margin.top - margin.bottom; | |
const fullWidth = width + margin.left + margin.right; | |
const fullHeight = height + margin.top + margin.bottom; | |
var svg = sel | |
.attr("width", fullWidth) | |
.attr("height", fullHeight) | |
//.attr('viewBox', `0 0 ${fullWidth} ${fullHeight}`) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
const scaleB = | |
d3.scaleBand() | |
.padding(0.2) | |
.align(0) // 0 is left aligned | |
.domain(data.map(o => o.name)) // notice: not an array of min + max as usual, but an array of all the plotted values | |
.range([0, width]); | |
const yScale = d3.scaleLinear() | |
.domain([0, d3.max(data, d => d.val)]) | |
.range([height, 0]); | |
var sequentialScale = d3.scaleSequential() | |
.domain([0, 10]) | |
.interpolator(d3.interpolateMagma); | |
const gr = svg | |
.append('g') | |
.attr('transform', (d, i) => `translate(0, ${i * 33})`) | |
gr | |
.selectAll('rect') | |
.data(data) | |
.enter() | |
.append('rect') | |
.attr('x', d => scaleB(d.name)) | |
.attr('y', d => yScale(d.val)) | |
.attr('width', d => scaleB.bandwidth()) | |
.attr('height', d => height - yScale(d.val)) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// From the above code we can start plotting a bar chart | |
// that gets a discrete range of colors (in this case 5) | |
// see https://jsfiddle.net/gleezer/0hc0k4p4/ | |
const data = [1,2,3,4,5,6,7,8,9]; | |
const sel = d3.select('#chart') | |
const scaleOrd = | |
d3.scaleQuantize() | |
.domain([0,10]) | |
.range(['#ff0000', '#ff6300', '#ffd900', '#a3ff00', '#00ff01']); | |
const gr = sel | |
.selectAll('g') | |
.data(data) | |
.enter() | |
.append('g') | |
// note, instead of incrementally translating each bar | |
// we translate each <g> group of bars | |
.attr('transform', (d, i) => `translate(0, ${i * 33})`) | |
gr | |
.append('rect') | |
.attr('width', d => d * 10) | |
.attr('height', 30) | |
.attr('fill', d => scaleOrd(d)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// d3 quantize scale | |
// From an ordinal domain maps to a discrete range according to its cardinality | |
// (so, "poor" is 1, "below average" is 2 ecc. forming a succession of values | |
// from low to high) | |
const scaleQ = | |
d3.scaleQuantize() | |
.domain([0,10]) | |
.range(['poor', 'below average', 'average', 'good', 'excellent']); | |
[1,3,5,7,8,10].forEach(i => console.log(scaleQ(i))); | |
console.log(scaleQ.invertExtent('average')); | |
const scaleO = | |
d3.scaleOrdinal() | |
.domain(['poor', 'below average', 'average', 'good', 'excellent']) | |
.range(['#ff0000', '#ff6300', '#ffd900', '#a3ff00', '#00ff01']); | |
['poor', 'below average', 'average'].forEach(i => console.log(scaleQ(i))); | |
console.log(scaleQ.invertExtent('average')); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//https://jsfiddle.net/r5wv5nod/ | |
const data = [{ | |
val: 4, | |
month: 1, | |
voters: 22, | |
name: 'A' | |
},{ | |
val: 10, | |
month: 2, | |
voters: 12, | |
name: 'B' | |
},{ | |
val: 21, | |
month: 3, | |
voters: 55, | |
name: 'C' | |
},{ | |
val: 12, | |
month: 4, | |
voters: 33, | |
name: 'D' | |
},{ | |
val: 22, | |
month: 5, | |
voters: 11, | |
name: 'E' | |
},{ | |
val: 15, | |
month: 6, | |
voters: 29, | |
name: 'F' | |
},{ | |
val: 19, | |
month: 7, | |
voters: 43, | |
name: 'G' | |
},{ | |
val: 22, | |
month: 7, | |
voters: 3, | |
name: 'G' | |
},{ | |
val: 12, | |
month: 8, | |
voters: 51, | |
name: 'G' | |
},{ | |
val: 21, | |
month: 9, | |
voters: 21, | |
name: 'G' | |
},{ | |
val: 33, | |
month: 10, | |
voters: 3, | |
name: 'G' | |
}]; | |
const sel = d3.select('#chart') | |
var margin = {top: 40, right: 10, bottom: 20, left: 10}; | |
var width = 460 - margin.left - margin.right; | |
var height = 500 - margin.top - margin.bottom; | |
const fullWidth = width + margin.left + margin.right; | |
const fullHeight = height + margin.top + margin.bottom; | |
var svg = sel | |
.attr("width", fullWidth) | |
.attr("height", fullHeight) | |
//.attr('viewBox', `0 0 ${fullWidth} ${fullHeight}`) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
const xScale = | |
d3.scaleLinear() | |
.domain([0,d3.max(data, d => d.month)]) | |
.range([0, width]); | |
const yScale = d3.scaleLinear() | |
.domain([0, d3.max(data, d => d.val)]) | |
.range([height, 0]); | |
const rScale = d3.scaleSqrt() // NB: => scale Square root to have the right scale of radius of bubbles | |
.domain([0, d3.max(data, d => d.voters)]) | |
.range([0, 40]); // => how big we want our circles | |
var sequentialScale = d3.scaleSequential() | |
.domain([0, 55]) | |
.interpolator(d3.interpolateViridis); | |
const bubbles = svg | |
.selectAll('.bubbles') | |
.data(data) | |
.enter() | |
.append('g') | |
.classed('bubbles', 1) | |
.attr('transform', d => | |
`translate(${xScale(d.month)}, ${yScale(d.val)})` | |
) | |
bubbles | |
.append('circle') | |
.attr('cx', 0) | |
.attr('cy', 0) | |
.attr('r', d => rScale(d.voters)) | |
.style('fill-opacity', 0.8) | |
.style('fill', d => sequentialScale(d.voters)) | |
.exit() | |
var line = d3.line() | |
.x(d => xScale(d.month)) | |
.y(d => yScale(d.val)) | |
.curve(d3.curveCatmullRom.alpha(0.5)) | |
svg | |
.append('g') | |
.selectAll('.line') | |
.data(data) | |
.enter() | |
.append('path') | |
.attr('class', 'line') | |
.attr('d', d => { | |
return line(data)}) | |
.style('stroke', 'steelblue') | |
.style('stroke-width', 2) | |
.style('fill', 'none') | |
.style('opacity', 0.3) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// see: http://jsfiddle.net/ramnathv/qpg286nh/ | |
// and http://brendansudol.com/writing/responsive-d3 | |
// see also: https://jsfiddle.net/ccnjowa2/ | |
function responsivefy(svg) { | |
var container = d3.select(svg.node().parentNode), | |
width = parseInt(svg.style("width")), | |
height = parseInt(svg.style("height")), | |
aspect = width / height; | |
svg.attr("viewBox", "0 0 " + width + " " + height) | |
.attr("perserveAspectRatio", "xMinYMid") | |
.call(resize); | |
d3.select(window).on("resize." + container.attr("id"), resize); | |
function resize() { | |
var targetWidth = parseInt(container.style("width")); | |
svg.attr("width", targetWidth); | |
svg.attr("height", Math.round(targetWidth / aspect)); | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//https://jsfiddle.net/9ex4jz0c/1/ | |
//========== VERSION 1 ================== // | |
const data = [{ | |
val: 4, | |
month: 1, | |
voters: 22, | |
name: 'A' | |
},{ | |
val: 10, | |
month: 2, | |
voters: 12, | |
name: 'B' | |
},{ | |
val: 21, | |
month: 3, | |
voters: 55, | |
name: 'C' | |
},{ | |
val: 12, | |
month: 4, | |
voters: 33, | |
name: 'D' | |
},{ | |
val: 22, | |
month: 5, | |
voters: 11, | |
name: 'E' | |
},{ | |
val: 15, | |
month: 6, | |
voters: 29, | |
name: 'F' | |
},{ | |
val: 19, | |
month: 7, | |
voters: 43, | |
name: 'G' | |
},{ | |
val: 22, | |
month: 7, | |
voters: 3, | |
name: 'G' | |
},{ | |
val: 12, | |
month: 8, | |
voters: 51, | |
name: 'G' | |
},{ | |
val: 21, | |
month: 9, | |
voters: 21, | |
name: 'G' | |
},{ | |
val: 33, | |
month: 10, | |
voters: 3, | |
name: 'G' | |
}]; | |
const sel = d3.select('#chart') | |
var margin = {top: 40, right: 10, bottom: 20, left: 10}; | |
var width = 460 - margin.left - margin.right; | |
var height = 500 - margin.top - margin.bottom; | |
const fullWidth = width + margin.left + margin.right; | |
const fullHeight = height + margin.top + margin.bottom; | |
var svg = sel | |
.attr("width", fullWidth) | |
.attr("height", fullHeight) | |
//.attr('viewBox', `0 0 ${fullWidth} ${fullHeight}`) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
const xScale = | |
d3.scaleLinear() | |
.domain([0,d3.max(data, d => d.month)]) | |
.range([0, width]); | |
const yScale = d3.scaleLinear() | |
.domain([0, d3.max(data, d => d.val)]) | |
.range([height, 0]); | |
const rScale = d3.scaleSqrt() // NB: => scale Square root to have the right scale of radius of bubbles | |
.domain([0, d3.max(data, d => d.voters)]) | |
.range([0, 40]); // => how big we want our circles | |
var sequentialScale = d3.scaleSequential() | |
.domain([0, 55]) | |
.interpolator(d3.interpolateViridis); | |
const gr = svg | |
.append('g') | |
.attr('transform', (d, i) => `translate(0, ${i * 33})`) | |
gr | |
.selectAll('circle') | |
.data(data) | |
.enter() | |
.append('circle') | |
.attr('cx', d => xScale(d.month)) | |
.attr('cy', d => yScale(d.val)) | |
.attr('r', d => rScale(d.voters)) | |
.style('fill-opacity', 0.8) | |
.style('fill', d => sequentialScale(d.voters)) | |
// https://jsfiddle.net/xk49vx2w/ | |
//========== VERSION 2 ================== // | |
// Same output as https://jsfiddle.net/9ex4jz0c/1/ | |
// But the bubbles are within a graphics container each | |
const data = [{ | |
val: 4, | |
month: 1, | |
voters: 22, | |
name: 'A' | |
},{ | |
val: 10, | |
month: 2, | |
voters: 12, | |
name: 'B' | |
},{ | |
val: 21, | |
month: 3, | |
voters: 55, | |
name: 'C' | |
},{ | |
val: 12, | |
month: 4, | |
voters: 33, | |
name: 'D' | |
},{ | |
val: 22, | |
month: 5, | |
voters: 11, | |
name: 'E' | |
},{ | |
val: 15, | |
month: 6, | |
voters: 29, | |
name: 'F' | |
},{ | |
val: 19, | |
month: 7, | |
voters: 43, | |
name: 'G' | |
},{ | |
val: 22, | |
month: 7, | |
voters: 3, | |
name: 'G' | |
},{ | |
val: 12, | |
month: 8, | |
voters: 51, | |
name: 'G' | |
},{ | |
val: 21, | |
month: 9, | |
voters: 21, | |
name: 'G' | |
},{ | |
val: 33, | |
month: 10, | |
voters: 3, | |
name: 'G' | |
}]; | |
const sel = d3.select('#chart') | |
var margin = {top: 40, right: 10, bottom: 20, left: 10}; | |
var width = 460 - margin.left - margin.right; | |
var height = 500 - margin.top - margin.bottom; | |
const fullWidth = width + margin.left + margin.right; | |
const fullHeight = height + margin.top + margin.bottom; | |
var svg = sel | |
.attr("width", fullWidth) | |
.attr("height", fullHeight) | |
//.attr('viewBox', `0 0 ${fullWidth} ${fullHeight}`) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
const xScale = | |
d3.scaleLinear() | |
.domain([0,d3.max(data, d => d.month)]) | |
.range([0, width]); | |
const yScale = d3.scaleLinear() | |
.domain([0, d3.max(data, d => d.val)]) | |
.range([height, 0]); | |
const rScale = d3.scaleSqrt() // NB: => scale Square root to have the right scale of radius of bubbles | |
.domain([0, d3.max(data, d => d.voters)]) | |
.range([0, 40]); // => how big we want our circles | |
var sequentialScale = d3.scaleSequential() | |
.domain([0, 55]) | |
.interpolator(d3.interpolateViridis); | |
const bubbles = svg | |
.selectAll('.bubbles') | |
.data(data) | |
.enter() | |
.append('g') | |
.classed('bubbles', 1) | |
.attr('transform', d => | |
`translate(${xScale(d.month)}, ${yScale(d.val)})` | |
) | |
bubbles | |
.append('circle') | |
.attr('cx', 0) | |
.attr('cy', 0) | |
.attr('r', d => rScale(d.voters)) | |
.style('fill-opacity', 0.8) | |
.style('fill', d => sequentialScale(d.voters)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment