Public
Edited
Aug 29, 2024
Insert cell
Insert cell
chart = htl.html`
${titleCard1}
${legendOnly}
${chartOnly}
`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
data_ori = Object.assign(
await FileAttachment("output_deduce_2005_2022.csv").csv({
typed: false
}),
{ d: "Deforestation" }
)
Insert cell
data1 = data_ori.filter((d) => {
return year.includes(d["Year"]);
})
Insert cell
Insert cell
data2 = aggregateData(data1, select_commodity)
Insert cell
Insert cell
enhancedData = enhanceData(data2);
Insert cell
data3 = enhancedData.filter((d) => {
return (
d["cpct"] !== "" &&
d["cpct"] != null &&
!isNaN(d["cpct"]) &&
d["cpct"] <= valuePct
);
})
Insert cell
data4 = data3.map((item) => {
let qualityFlag; // Variable to hold the quality flag

// Check the Quality value and assign the appropriate flag
if (item.Quality === null || item.Quality === undefined) {
qualityFlag = "Mix spatially explicit with statistical data";
} else if (Number(item.Quality) >= 0.5) {
qualityFlag = "Only spatially explicit";
} else {
qualityFlag = "Mix spatially explicit with statistical data";
}

// Return a new object with all existing key-value pairs and the new Quality_flag
return { ...item, Quality_flag: qualityFlag };
})
Insert cell
data = {
const selectedQualities = new Set(select_quality);
return data4.filter((item) => selectedQualities.has(item.Quality_flag));
}
Insert cell
dataMap = new Map(
data.map(({ key, Deforestation }) => [String(key), Number(Deforestation)])
)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
valueCol = "Deforestation"
Insert cell
Insert cell
formatter = new Intl.NumberFormat('en-US', {
maximumFractionDigits: 0 // Ensures no decimal places
});
Insert cell
total_deforestation = data1.reduce((acc, curr) => {
return acc + parseFloat(curr.Deforestation);
}, 0)
Insert cell
formattedTotalDeforestation = formatter.format(total_deforestation)
Insert cell
slected_deforestation = data.reduce((acc, curr) => {
return acc + parseFloat(curr.Deforestation);
}, 0)
Insert cell
formattedSelectDeforestation = formatter.format(slected_deforestation)
Insert cell
proportion = total_deforestation !== 0
? `${(slected_deforestation / total_deforestation * 100).toFixed(0)}%` // Converts the proportion to a percentage string with no decimals
: "Total Deforestation is zero, cannot perform division.";
Insert cell
total_countries = data.filter(d => parseFloat(d.Deforestation) > 0).length;
Insert cell
valuePct = pct_select[Object.values(pct_select[3]).indexOf(valuePctSelect)]
Insert cell
iso = new Map(data.map((d) => [String(d.M49_code), d.key]))
Insert cell
{
const countriesGeom = world.objects.countries.geometries.map((d) => {
return {
...d,
properties: { ...d.properties, trase_name: iso.get(String(d.id)) }
};
});
return {
...world,
objects: {
...world.objects,
countries: { ...world.objects.countries, geometries: countriesGeom }
}
};
}
Insert cell
world = FileAttachment("countries-110m-minus-antarctica-1.json").json()
Insert cell
height = width * 0.6
Insert cell
margin = ({ top: 0, right: 0, bottom: 0, left: 0 })
Insert cell
projection = d3
.geoNaturalEarth1()
.fitExtent(
[[margin.left, margin.top], [width - margin.right, height - margin.bottom]],
topojson.mesh(world, world.objects.countries)
)
.rotate([-15, 0]) // keep russia together
Insert cell
path = d3.geoPath(projection);
Insert cell
ninetiethPercentile = d3.quantile(
data.map((d) => d[valueCol]),
0.99
)
Insert cell
tenthPercentile = d3.quantile(
data.map((d) => d[valueCol]),
0.40
)
Insert cell
extent = [tenthPercentile, ninetiethPercentile];
Insert cell
colourScheme = traseReds
Insert cell
colour = d3
.scaleSequential(
d3.interpolateRgbBasis([
"#f7f0ee",
"#fac3be",
"#fc978f",
"#fd7167",
"#f6665c",
"#df5d55",
"#ba4e49",
"#843833",
"#421d03"
])
)
.domain(extent)
Insert cell
colour1 = d3.scaleSequential(d3.extent(dataMap, ([,v]) => v), d3.interpolateRgbBasis(colourScheme[7]));
Insert cell
format = d3.format(",.2r")
Insert cell
numberFormat = ",.0~f"
Insert cell
annotate = g => {}
Insert cell
deforestation1 = new Map(
data.map(({ key, ["Deforestation"]: deforestationRisk }) => [
String(key),
Number(deforestationRisk)
])
)

Insert cell
formatter1 = new Intl.NumberFormat('en-US', {
style: 'percent',
minimumFractionDigits: 1,
maximumFractionDigits: 1
});
Insert cell
deforestation = new Map(
data.map(
({ key, ["Deforestation"]: deforestationRisk, ["pct"]: proportion }) => [
String(key),
{
deforestation: formatter.format(deforestationRisk),
restoration: formatter1.format(proportion)
}
]
)
)
Insert cell
function hover(g, svg) {
const tooltip = new Tooltip();
g.style("cursor", "pointer")
.on("touchstart", (event) => event.preventDefault())
.on("pointerenter", function (event, f) {
const key = iso.get(f.id);
if (!deforestation.has(key)) return;
const data = deforestation.get(key);
tooltip.position(...d3.pointer(event));
tooltip.show(
f.properties.name,
tooltipKeyValue1(tooltipKey.toUpperCase(), data, f)
);
d3.select(this).transition().attr("opacity", 0.7);
})
.on("pointermove", function (event) {
let [x, y] = tooltipOffset(tooltip, d3.pointer(event), width, height);
tooltip.position(x, y);
this.releasePointerCapture(event.pointerId);
})
.on("pointerout", function () {
tooltip.hide();
d3.select(this).transition().attr("opacity", 1);
});
svg.append(() => tooltip.node);
}
Insert cell
tooltipKey = data["Deforestation"] || "Deforestation"
Insert cell
tooltipKeyValue1 = (key, values) => svg`
<text>
<tspan font-size="10px" fill="#839095" x="0" dy="0em" style="text-transform:uppercase">${key}</tspan>
<tspan font-family="var(--trase-sans-serif)" font-size="14px" font-weight="700" fill="#31464e" x="0" dy="1.4em">Area: ${values.deforestation} ha</tspan>
<tspan font-family="var(--trase-sans-serif)" font-size="14px" font-weight="700" fill="#31464e" x="0" dy="1.4em">In relation to global: ${values.restoration}</tspan>
</text>`
Insert cell
tooltipRel = data["pct"] || "Proportion in relation to global"
Insert cell
import { swatches, getLabelLength } from "@trase/legends-2-0"
Insert cell
import { Tooltip, tooltipKeyValue, tooltipOffset } from "@trase/tooltip@440"
Insert cell
d3 = require("d3@6")
Insert cell
topojson = require("topojson-client@3")
Insert cell
simple = require("simple-statistics@7")
Insert cell
import { traseColours, traseReds, fonts } from "@trase/visual-id@1366"
Insert cell
import { titleCard } from "@trase/title-card"
Insert cell
Insert cell
import { input } from "@jashkenas/inputs"
Insert cell
import { legend as legendTemplate } from "@trase/legends@376"
Insert cell
function checkboxes(config = {}) {
return multiChoice(Object.assign({ type: 'checkbox' }, config))
}
Insert cell
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