Published
Edited
Oct 21, 2020
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
data = [
{
x: 50,
y: 50
},
{
x: 100,
y: 100
}
]
Insert cell
lineGenerator = d3
.line()
.x(d => d.x) // .x -> x values to use for line
.y(d => d.y) // .y -> y values to use for line
Insert cell
dString = lineGenerator(data)
Insert cell
Insert cell
html`<svg width=200 height=200>
<path d="${dString}" stroke="black"></path>
</svg>`
Insert cell
Insert cell
Insert cell
stockData = d3.csv(
"https://raw.githubusercontent.com/vega/datalib/master/test/data/stocks.csv"
)
Insert cell
measurements = {
return {
width: 800,
height: 400,
marginLeft: 50,
marginRight: 50,
marginTop: 50,
marginBottom: 50
};
}
Insert cell
formatTime = d3.timeParse("%B %d, %Y")
Insert cell
formatTime("June 30, 2015")
Insert cell
formattedData = stockData.map(d => {
const formatTime = d3.timeParse("%b %d %Y");

return {
symbol: d.symbol,
price: d.price,
date: formatTime(d.date)
};
})
Insert cell
md`formattedData is the same as \`stockData\` in the template. Sorry I forgot to change it here~!`
Insert cell
chart = {
const svg = d3
.create('svg')
.attr('viewBox', [0, 0, measurements.width, measurements.height]);

svg.node().update = symbol => {
svg.selectAll('*').remove();

const filteredData = formattedData.filter(d => d.symbol == symbol);

const priceLimits = d3.extent(filteredData, d => +d.price);
const yScale = d3
.scaleLinear()
.domain(priceLimits)
.range([
measurements.height - measurements.marginBottom,
measurements.marginTop
]);

const timeLimits = d3.extent(filteredData, d => d.date);
const xScale = d3
.scaleTime()
.domain(timeLimits)
.range([
measurements.marginLeft,
measurements.width - measurements.marginRight
]);

const xAxis = d3.axisBottom().scale(xScale);

svg
.append('g')
.attr(
'transform',
'translate(0,' + (measurements.height - measurements.marginBottom) + ')'
)
.call(xAxis);

const yAxis = d3.axisLeft().scale(yScale);

const stockTrendLineGen = d3
.line()
.x(d => xScale(d.date))
.y(d => yScale(+d.price));

svg
.append('g')
.attr('transform', 'translate(' + measurements.marginLeft + ',0)')
.call(yAxis);

svg
.append('path')
.datum(filteredData)
.attr('d', d => stockTrendLineGen(d))
.attr('stroke', 'orange')
.attr('fill', 'none');
};

return svg.node();
}
Insert cell
chart.update(symbol)
Insert cell
viewof symbol = DOM.select([...new Set(formattedData.map(d => d.symbol))])
Insert cell
challenge2 = {
const svg = d3
.create('svg')
.attr('viewBox', [0, 0, measurements.width, measurements.height]);

// Create an (empty) axis -- we'll draw it on update
const xAxis = svg
.append('g')
.attr('class', 'x-axis')
.attr(
'transform',
'translate(0,' + (measurements.height - measurements.marginBottom) + ')'
);

const yAxis = svg
.append('g')
.attr('class', 'y-axis')
.attr('transform', 'translate(' + measurements.marginLeft + ',0)');

// Write the update function
svg.node().update = symbol => {
// Filter down data to desired company
const filteredData = formattedData.filter(d => d.symbol == symbol);

// Reset the scales (based on the updated data)
const priceLimits = d3.extent(filteredData, d => +d.price);
const timeLimits = d3.extent(filteredData, d => d.date);

const xScale = d3
.scaleTime()
.domain(timeLimits)
.range([
measurements.marginLeft,
measurements.width - measurements.marginRight
]);

const yScale = d3
.scaleLinear()
.domain(priceLimits)
.range([
measurements.height - measurements.marginBottom,
measurements.marginTop
]);

// Update the scales
xAxis.call(d3.axisBottom().scale(xScale));
yAxis.call(d3.axisLeft().scale(yScale));

// Create a function to draw a path
const stockTrendLineGen = d3
.line()
.x(d => xScale(d.date))
.y(d => yScale(+d.price));

// Perform a data join to draw the line: note! we pass in an array with one object in it
// (because we want one line)
svg
.selectAll(".trend-line")
.data([{ data: filteredData }])
.join('path')
.attr('class', 'trend-line')
.attr('fill', 'none')
.attr('stroke', 'orange')
.transition()
.attr('d', d => stockTrendLineGen(d.data));
};

return svg.node();
}
Insert cell
challenge2.update(symbol)
Insert cell
// challenge.update(symbol)
Insert cell
Insert cell
html`<style>
p code, li > code {color: #c30771;}
</style>`
Insert cell
d3 = require('d3@6')
Insert cell
import {
render_data_table,
table_styles,
displayImage,
displayCaution
} from '@info474/utilities'
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