Public
Edited
Sep 12, 2023
2 forks
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
FileAttachment("untitled.svg").image()
Insert cell
Insert cell
FileAttachment("diamondsChart.svg").image()
Insert cell
irisURL = 'https://raw.githubusercontent.com/plotly/datasets/master/iris-id.csv'
Insert cell
irisData = d3.csv(irisURL)
Insert cell
Insert cell
Insert cell
scatter
Insert cell
Insert cell
Insert cell
viewof types = Inputs.radio(["Sepal", "Petal"], {label: "Type"})
Insert cell
scatter4 = {
const margin = {top: 40, right: 40, bottom: 40, left: 90};

const visWidth = 700;
const visHeight = 400;
const svg = d3.create('svg')
.attr('width', visWidth + margin.left + margin.right)
.attr('height', visHeight + margin.top + margin.bottom);

const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`)
.attr('font-family', 'sans-serif');

svg.node().drawData = function(input_state) {
// set the x and y values
const x = (d => (input_state == 'Sepal') ? d.sepal_length : d.petal_length)
const y = (d => (input_state == 'Sepal') ? d.sepal_width : d.petal_width)

// scales
const xs = d3.scaleLinear()
.domain(d3.extent(irisData, d => x(d)))
.range([0, visWidth]);

const ys = d3.scaleLinear()
.domain(d3.extent(irisData, d => y(d)))
.range([visHeight, 0]);

// axis generators
const xAxis = d3.axisBottom(xs);
const yAxis = d3.axisLeft(ys);

// draw axes and grid
// x-axis and vertical grid lines
g.append('g')
.attr("class", "xAxis")
.attr('transform', `translate(0,${visHeight})`)
// y-axis and horizontal grid lines
g.append('g')
.attr("class", "yAxis")
// Select all circles within the SVG (yes, even those that do not exist yeT)
g.selectAll('circle')
// Input the data
.data(irisData)
// Join the data
// Each function here is important for one step
// Enter: For new circles that were not shown before
.join(enter => enterFunc(enter),
// Update: For the amount of circles that were already there an can be reused.
update => updateFunc(update),
// Exit: For those circle that are not needed anymore
exit => exitFunc(exit))


function enterFunc(enterSel){
enterSel.append('circle')
.transition().duration(1000)
.style('opacity', 0.75)
.attr("fill", function(d) {
if (d.species == 'setosa') {return '#1b9e77'}
else if (d.species == 'virginica') {return '#d95f02'}
else {return '#7570b3'}
})
.attr('cx', (d) => xs(x(d)))
.attr('cy', (d) => ys(y(d)))
.attr("r", 15)
}

function updateFunc(toUpdate) {
g.select(".xAxis")
.call(xAxis)
.call(
// add grid lines
g => g.selectAll('.tick line').clone()
.attr('y1', 0)
.attr('y2', -visHeight)
.attr('stroke', 'grey')
.attr('stroke-width', 1)
)
.call(g => g.select('.domain').remove())
.append('text')
.attr('x', visWidth / 2)
.attr('y', 30)
.attr('fill', 'black')
.attr('text-anchor', 'center')
.text('length');

g.select('.yAxis')
.call(yAxis)
.call(
// add grid lines
g => g.selectAll('.tick line').clone()
.attr('x1', 0)
.attr('x2', visWidth)
.attr('stroke', 'grey')
.attr('stroke-width', 1)
)
.call(g => g.select('.domain').remove())
.append('text')
.attr('x', -35)
.attr('y', visHeight / 2)
.attr('fill', 'black')
.attr('dominant-baseline', 'center')
.attr('text-anchor', 'end')
.text('width');

toUpdate.transition().duration(1000)
.attr("fill", function(d) {
if (d.species == 'setosa') {return '#1b9e77'}
else if (d.species == 'virginica') {return '#d95f02'}
else {return '#7570b3'}
})
.attr('cx', (d) => xs(x(d)))
.attr('cy', (d) => ys(y(d)))
.attr("r", 15)
}

function exitFunc(dissapearingEls){
dissapearingEls
.transition().duration(1000)
.style("opacity", 0)
.remove()
}
}

return svg.node();
}
Insert cell
scatter4.drawData(types)
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