Public
Edited
Sep 5, 2023
Insert cell
Insert cell
Insert cell
penguins_data_2
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
penguins_data_2 = penguins
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
massScale = {
const extentWeight = d3.extent(penguins_data_2, (d => d['body_mass_g'])) // min, max values
return d3.scaleLinear()
.domain(extentWeight)
.range([2, 25])
}
Insert cell
Insert cell
flipperScale =
{
const extentFlipper = d3.extent(penguins_data_2, (d => d['flipper_length_mm']))
return d3.scaleLinear()
.domain(extentFlipper)
.range([svgSetting.margin.left, svgSetting.width - svgSetting.margin.right])
}
Insert cell
culmenLength =
{
const extentCulmenLength = d3.extent(penguins_data_2, (d=> d['culmen_length_mm']))
return d3.scaleLinear()
.domain(extentCulmenLength)
.range([svgSetting.height - svgSetting.margin.bottom, svgSetting.margin.top])
}
Insert cell
Insert cell
chart1 = {
const svg = d3.create("svg")
.attr("width", svgSetting.width)
.attr("height", svgSetting.height);

svg.append("g")
.attr("transform", `translate(0,${svgSetting.height - svgSetting.margin.bottom})`)
.call(d3.axisBottom(flipperScale));

svg.append("g")
.attr("transform", `translate(${svgSetting.margin.left},0)`)
.call(d3.axisLeft(culmenLength));
svg.append('g')
.selectAll('circle')
.data(penguins_data_2)
.enter()
.append("circle")
.attr("fill", (d => (d['sex'] == 'FEMALE') ? 'blue' : "orange"))
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("opacity", 0.7)
.attr("r", (d => massScale(d['body_mass_g'])))
.attr("cx", (d => flipperScale(d['flipper_length_mm'])))
.attr("cy", (d => culmenLength(d['culmen_length_mm'])))

return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof species = Inputs.radio(["Adelie", "Chinstrap", "Gentoo"], {label: "Species"})
Insert cell
species
Insert cell
Insert cell
Insert cell
// generate the reactive bubble chart dependent on the radio buttons and using the categorical scales
reactivechart = {
// Define the SVG where to draw
const svg = d3.create("svg")
.attr("width", svgSetting.width)
.attr("height", svgSetting.height);

// Create the axis
svg.append("g")
.attr("transform", `translate(0,${svgSetting.height - svgSetting.margin.bottom})`)
.call(d3.axisBottom(flipperScale));

svg.append("g")
.attr("transform", `translate(${svgSetting.margin.left},0)`)
.call(d3.axisLeft(culmenLength));

// Important!
// Within the SVG.node that is returned at the end of this cell, define a drawData function
// Here the name could be everything (e.g.
// svg.node().theFunctionThatWillBeCalledAtTheEnd would also work)
svg.node().drawData = function(input_state) {
// Filter for the Current State of the input variable (input of the function)
const dataSelected = penguins_data_2.filter((d)=> d.species == input_state)

// Select all circles within the SVG (yes, even those that do not exist yeT)
svg.selectAll('circle')
// Input the data
.data(dataSelected)
// 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)
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.style('opacity', 0.75)
.attr("fill", (d => (d['sex'] == 'FEMALE') ? 'blue' : "orange"))
.attr("cx", (d => flipperScale(d['flipper_length_mm'])))
.attr("cy", (d => culmenLength(d['culmen_length_mm'])))
.attr("r", (d => massScale(d['body_mass_g'])))
}

function updateFunc(toUpdate) {
toUpdate.transition().duration(1000)
.attr("fill", (d => (d['sex'] == 'FEMALE') ? 'blue' : "orange"))
.attr("cx", (d => flipperScale(d['flipper_length_mm'])))
.attr("cy", (d => culmenLength(d['culmen_length_mm'])))
.attr("r", (d => massScale(d['body_mass_g'])))
}

function exitFunc(dissapearingEls){
dissapearingEls
.transition().duration(1000)
.style("opacity", 0)
.remove()
}
}
return svg.node();
}
Insert cell
reactivechart.drawData(species)
Insert cell
Insert cell
// your plot could be here
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