Public
Edited
Feb 21
Insert cell
Insert cell
htl.html`
<style>
rect {
fill: red;
}
table {
text-align: center;
}
th, td {
border-bottom: 1px solid #ddd;
}
th {
background-color: black;
color: white;
}
tr:hover {background-color: #f5f5f5;}
tr:nth-child(even) {background-color: #f2f2f2;}
body {
font-family: "Helvetica Neue", Helvetica, sans-serif;
font-size: 12px;
color: #333;
}
text {
fill: #555;
}
.inner text {
text-anchor: middle;
}
</style>
`
Insert cell
## Population of Cities
Insert cell
{
var cities = [
{ name: 'London', population: 8674000},
{ name: 'New York', population: 8406000},
{ name: 'Sydney', population: 4293000},
{ name: 'Paris', population: 2244000},
{ name: 'Beijing', population: 11510000}
];
let div = d3.create("div")
let svg = div.append("svg")
.attr("width","500")
.attr("height","200")
var fontSize = 18;

var cityNames = cities.map(function(d) {return d.name});
var bandScale = d3.scaleBand()
.domain(cityNames)
.range([0, 160])
.paddingOuter(0.33)
.paddingInner(0.33);

var pop2width = d3.scalePow()
.domain([0, 2*1e7])
.range([0, 200]);

var texts = svg.selectAll('text')
.data(cities)
.enter().append("text")
.attr('x', 0)
.attr('y', function(d, i) {
return bandScale(d.name);
})
.attr('font-size', fontSize)
// set anchor and alignment for texts
.attr('text-anchor', 'start')
.attr('alignment-baseline', 'hanging')
.text(function(d) {
return d.name;
});

var rects = svg.selectAll("rect")
.data(cities)
.enter().append("rect")
.attr("x", 80)
.attr("y", function(d) {
return bandScale(d.name);
})
.attr("width", function(d, i) {
return pop2width(d.population);
})
.attr("height", bandScale.bandwidth())
.style("fill", "steelblue");

// Create a table
tabulate(["name", "population"], cities);

function tabulate(columnNames, data) {
var table = div.append('table');
var thead = table.append('thead');
var tbody = table.append('tbody');

// append the header row
thead.append('tr')
.selectAll('th')
.data(columnNames)
.enter()
.append('th')
.text(function (d) {
return d;
});

// create a row for each object in the data
var rows = tbody.selectAll('tr')
.data(data)
.enter()
.append('tr');

// create a cell in each row for each column
var cells = rows.selectAll('td')
.data(function (row) {
return columnNames.map(function (columnName) {
return {
key: columnName,
value: row[columnName]
};
});
})
.enter()
.append('td')
.text(function (d) {
return d.value;
});

return table;
}
return div.node()
}
Insert cell
Insert cell
{
var svg = d3.create('svg')
.attr("width","1000")
.attr("height","100")
var g = svg.append('g')
.classed('inner', true)
.attr('transform', "translate(40, 30)")

var data = [ 0, 1, 2, 3, 4, 5, 6, 7, 7.5, 8, 9, 10 ];
// var data_log = [10, 100, 1000, 10000, 100000];

// scaleLinear
var value2width = d3.scaleLinear()
.domain([0, 10])
.range([0, 600]);
// Task: Duplicate the code block and replace scaleLinear with scalePow (exp=2, exp=0.5), scaleSqrt, and scaleLog
// in the new blocks
// Use data_log for scaleLog, see the different mapping result of these functions

svg.select('.inner')
.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('r', 3)
.attr('cx', function(d) {
return value2width(d);
});

svg.select('.inner')
.selectAll('text')
.data(data)
.enter()
.append('text')
.attr('x', function(d) {
return value2width(d);
})
.attr('y', -8)
.text(function(d) {
return d;
});
return svg.node()
}
Insert cell
{
var svg = d3.create('svg')
.attr("width", "1100")
.attr("height", "400");
var g = svg.append('g')
.classed('inner', true)
.attr('transform', "translate(40, 30)");

var data = [0, 1, 2, 3, 4, 5, 6, 7, 7.5, 8, 9, 10];
var data_log = [10, 100, 1000, 10000, 100000];

// scaleLinear
var scaleLinear = d3.scaleLinear()
.domain([1, 10])
.range([1, 600]);

// scalePow with exponent 2
var scalePow2 = d3.scalePow()
.exponent(2)
.domain([1, 10])
.range([1, 600]);

// scalePow with exponent 0.5 (square root)
var scalePow05 = d3.scalePow()
.exponent(0.5)
.domain([1, 10])
.range([1, 600]);

// scaleSqrt (same as scalePow with exp 0.5)
var scaleSqrt = d3.scaleSqrt()
.domain([1, 10])
.range([1, 600]);

// scaleLog
var scaleLog = d3.scaleLog()
.domain([10, 100000])
.range([1, 600]);

function drawScale(scale, data, yOffset, label) {
g.append('text')
.attr('x', 0)
.attr('y', yOffset - 10)
.text(label)
.style('font-size', '12px')
.style('font-weight', 'bold');

var group = g.append('g')
.attr('transform', `translate(0, ${yOffset})`);

group.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('r', 3)
.attr('cx', function (d) {
return scale(d);
});

group.selectAll('text')
.data(data)
.enter()
.append('text')
.attr('x', function (d) {
return scale(d);
})
.attr('y', -8)
.text(function (d) {
return d;
});
}

drawScale(scaleLinear, data, 30, "Linear Scale");
drawScale(scalePow2, data, 80, "Power Scale (exp=2)");
drawScale(scalePow05, data, 130, "Power Scale (exp=0.5)");
drawScale(scaleSqrt, data, 180, "Sqrt Scale");
drawScale(scaleLog, data_log, 230, "Log Scale");

return svg.node();
}

Insert cell
Insert cell
{
var svg = d3.create('svg')
.attr("width","1000")
.attr("height","100")
svg.append("g")
.attr("transform", "translate(40, 30)")
.classed("inner",true)

var data = [new Date(2016, 0, 1), new Date(2016, 3, 1), new Date(2016, 6, 1), new Date(2017, 0, 1)];

var time2width = d3.scaleLog()
.domain([new Date(2016, 0, 1), new Date(2017, 0, 1)])
.range([0, 600]);

svg.select('.inner')
.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('r', 3)
.attr('cx', function(d) {
return time2width(d);
});

svg.select('.inner')
.selectAll('text')
.data(data)
.enter()
.append('text')
.attr('x', function(d) {
return time2width(d);
})
.attr('y', -8)
.text(function(d) {
return d.toDateString();
});
return svg.node()
}
Insert cell
Insert cell
{
var svg = d3.create('svg')
.attr("width","1000")
.attr("height","100")
svg.append("g")
.attr("transform", "translate(50, 30)")
.classed("inner",true)
var xScale = d3.scaleLinear()
.domain([-10, 10])
.range([0, 600]);

var value2color = d3.scaleLinear()
.domain([-10, 0, 10])
.range(['red', '#ddd', 'blue']);
// Task: map data to three segments (four split points), use split point and color of your choice

var myData = [-10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10];

svg.select('.inner')
.selectAll('circle')
.data(myData)
.enter()
.append('circle')
.attr('r', 10)
.attr('cx', function(d) {
return xScale(d);
})
.style('fill', function(d) {
return value2color(d);
});
return svg.node()
}
Insert cell
{
var svg = d3.create('svg')
.attr("width", "1000")
.attr("height", "100");
svg.append("g")
.attr("transform", "translate(50, 30)")
.classed("inner", true);
var xScale = d3.scaleLinear()
.domain([-10, 10])
.range([0, 600]);

// Updated color scale with three segments (four split points)
var value2color = d3.scaleLinear()
.domain([-10, -5, 0, 5, 10])
.range(['red', 'pink', '#ddd', 'lightgreen', 'blue']);

var myData = [-10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10];

svg.select('.inner')
.selectAll('circle')
.data(myData)
.enter()
.append('circle')
.attr('r', 10)
.attr('cx', function (d) {
return xScale(d);
})
.style('fill', function (d) {
return value2color(d);
});

return svg.node();
}

Insert cell
Insert cell
{
var svg = d3.create('svg')
.attr("width","1000")
.attr("height","100")
svg.append("g")
.attr("transform", "translate(50, 30)")
.classed("inner",true)
var xScale = d3.scaleLinear()
.domain([-10, 10])
.range([0, 600]);

var value2color = d3.scaleSequential()
.domain([-10, 10])
.interpolator(d3.interpolateRainbow);

var myData = [-10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10];

svg.select('.inner')
.selectAll('circle')
.data(myData)
.enter()
.append('circle')
.attr('r', 10)
.attr('cx', function(d) {
return xScale(d);
})
.style('fill', function(d) {
return value2color(d);
});
return svg.node()
}
Insert cell
Insert cell
{
var svg = d3.create('svg')
.attr("width","1000")
.attr("height","100")
svg.append("g")
.attr("transform", "translate(50, 30)")
.classed("inner",true)
var linearScale = d3.scaleLinear()
.domain([0, 100])
.range([0, 600]);

var value2color = d3.scaleQuantize()
.domain([0, 100])
.range(['lightblue', 'orange', 'lightgreen', 'pink']);

var myData = d3.range(0, 100, 1);

svg.select('.inner')
.selectAll('rect')
.data(myData)
.enter()
.append('rect')
.attr('x', function(d) {
return linearScale(d);
})
.attr('width', 5)
.attr('height', 30)
.style('fill', function(d) {
return value2color(d);
});
return svg.node()
}
Insert cell
Insert cell
{
var svg = d3.create('svg')
.attr("width","1000")
.attr("height","100")
svg.append("g")
.attr("transform", "translate(50, 30)")
.classed("inner",true)
var linearScale = d3.scaleLinear()
.domain([0, 100])
.range([0, 600]);

var myData = [0, 1, 2, 3, 4, 10, 20, 30, 35, 40, 60, 62, 65, 70, 80, 90, 100];

var value2color = d3.scaleQuantile()
.domain(myData)
.range(['lightblue', 'orange', 'lightgreen']);

// Task: Run the following code that change to Quantize scale,
// consider why there is a difference
// var value2color = d3.scaleQuantize()
// .domain([0,100])
// .range(['lightblue', 'orange', 'lightgreen']);

svg.select('.inner')
.selectAll('rect')
.data(myData)
.enter()
.append('rect')
.attr('x', function(d) {
return linearScale(d);
})
.attr('width', 5)
.attr('height', 30)
.style('fill', function(d) {
return value2color(d);
});
return svg.node()
}
Insert cell
Insert cell
Insert cell
{
var svg = d3.create('svg')
.attr("width","1000")
.attr("height","100")
svg.append("g")
.attr("transform", "translate(50, 30)")
.classed("inner",true)

let data = d3.range(-10, 110, 1)
var linearScale = d3.scaleLinear()
.domain([0, 100])
.range([0, 600]);

var value2color = d3.scaleThreshold()
.domain([0, 50, 100])
.range(['lightblue', 'orange', 'lightgreen', 'pink']);

svg.select('.inner')
.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('x', function(d) {
return linearScale(d);
})
.attr('width', 5)
.attr('height', 30)
.style('fill', function(d) {
return value2color(d);
});
return svg.node()
}
Insert cell
Insert cell
{
var svg = d3.create('svg')
.attr("width","1000")
.attr("height","100")
svg.append("g")
.attr("transform", "translate(50, 30)")
.classed("inner",true)
var data = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

var linearScale = d3.scaleLinear()
.domain([0, 11])
.range([0, 600]);

var month2color = d3.scaleOrdinal()
.domain(data)
.range(['black', 'grey', 'lightgrey']);

svg.select('.inner')
.selectAll('text')
.data(data)
.enter()
.append('text')
.attr('x', function(d, i) {
return linearScale(i);
})
.text(function(d) {
return d;
})
.style('fill', function(d) {
return month2color(d);
});
return svg.node()
}
Insert cell
Insert cell
{
var svg = d3.create('svg')
.attr("width","1000")
.attr("height","100")
svg.append("g")
.attr("transform", "translate(50, 30)")
.classed("inner",true)
var xScale = d3.scaleLinear()
.domain([0, 9])
.range([0, 600]);

var value2color = d3.scaleOrdinal(d3.schemeCategory10);

var myData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

svg.select('.inner')
.selectAll('circle')
.data(myData)
.enter()
.append('circle')
.attr('r', 10)
.attr('cx', function(d) {
return xScale(d);
})
.style('fill', function(d) {
return value2color(d);
});
return svg.node()
}
Insert cell
Insert cell
{
var svg = d3.create('svg')
.attr("width","1000")
.attr("height","300")
svg.append("g")
.attr("transform", "translate(40, 40)")
.attr("id","wrapper")
var data = [
{day : 'Mon', value: 120},
{day : 'Tue', value: 60},
{day : 'Wed', value: 100},
{day : 'Thu', value: 80},
{day : 'Fri', value: 120}
];

var pointScale = d3.scalePoint()
.domain(['Mon', 'Tue', 'Wed', 'Thu', 'Fri'])
.range([0, 600])
.padding(0.1);

var value2height = d3.scaleLinear()
.domain([0, d3.max(data, function(d) {return d.value;})])
.range([200, 0]);

var circles = svg.select('#wrapper')
.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('cx', function(d) {
return pointScale(d.day);
})
.attr('cy', function(d) {
return value2height(d.value);
})
.attr('r', 4)
.style('fill','orange');

var texts = svg.select('#wrapper')
.selectAll('text')
.data(data)
.enter().append('text')
.attr('x', function(d) {
return pointScale(d.day);
})
.attr('y', 210)
.attr('text-anchor', 'middle')
.text(function(d) {
return d.day;
});
return svg.node()
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more