Skip to content
Snippets Groups Projects
Commit c5de9daf authored by Hayley Corson-Dosch's avatar Hayley Corson-Dosch
Browse files

Drop findex bump chart

parent a6dbaade
No related branches found
No related tags found
1 merge request!74Drop viz
Habitat,ThreatCode,AverageThreatMetric,Threat,ThreatCategory,Rank
Large lakes,Dams,1.7949111801459146,Dams,Habitat,15
Large lakes,Defor,1.9737570299751332,Deforestation and associated runoff,Habitat,14
Large lakes,Drght,2.445412074956739,Drought,Climate and weather,10
Large lakes,Eff,2.41503962627927,Effluents,Pollution,11
Large lakes,FldChg,4.163457947856302,Change in flooding,Climate and weather,3
Large lakes,IceChg,5.353536906883928,Change in ice cover,Climate and weather,1
Large lakes,Invasv,4.570230231794904,Invasive non-native species,Invasive species,2
Large lakes,Mining,2.8217341594034147,Mining,Pollution,7
Large lakes,OilGas,2.8109911788668467,Oil or gas exploration,Pollution,8
Large lakes,OvrFsh,2.0734340826379127,Overfishing,Exploitation,13
Large lakes,Pharma,3.0972582788553105,Pharmaceuticals,Pollution,6
Large lakes,Plastic,1.4815621548359093,Plastics,Pollution,16
Large lakes,RipDeg,2.149973141524384,Riparian degradation,Habitat,12
Large lakes,TmpChg,3.3464759811751614,Change in water temperature,Climate and weather,5
Large lakes,Use,2.7968973356733664,Water use,Habitat,9
Large lakes,WetLoss,3.429206843249385,Wetland drainage,Habitat,4
Large river deltas,Dams,0.3689273597554484,Dams,Habitat,15
Large river deltas,Defor,5.330165730661932,Deforestation and associated runoff,Habitat,2
Large river deltas,Drght,3.757366897443977,Drought,Climate and weather,5
Large river deltas,Eff,3.7165925984345742,Effluents,Pollution,6
Large river deltas,FldChg,3.122638800856216,Change in flooding,Climate and weather,9
Large river deltas,IceChg,0,Change in ice cover,Climate and weather,16
Large river deltas,Invasv,1.2774541146742235,Invasive non-native species,Invasive species,14
Large river deltas,Mining,3.484878226135668,Mining,Pollution,7
Large river deltas,OilGas,2.4549619786305588,Oil or gas exploration,Pollution,12
Large river deltas,OvrFsh,6.2787582644623665,Overfishing,Exploitation,1
Large river deltas,Pharma,2.5384614860310215,Pharmaceuticals,Pollution,11
Large river deltas,Plastic,4.543131375433414,Plastics,Pollution,4
Large river deltas,RipDeg,3.2756889789172496,Riparian degradation,Habitat,8
Large river deltas,TmpChg,4.903678902181309,Change in water temperature,Climate and weather,3
Large river deltas,Use,1.9337348164193617,Water use,Habitat,13
Large river deltas,WetLoss,3.1126877927788974,Wetland drainage,Habitat,10
Montane freshwaters,Dams,1.9563387518549218,Dams,Habitat,8
Montane freshwaters,Defor,1.2328801638433262,Deforestation and associated runoff,Habitat,14
Montane freshwaters,Drght,4.149483437832635,Drought,Climate and weather,2
Montane freshwaters,Eff,1.4335342881157658,Effluents,Pollution,11
Montane freshwaters,FldChg,4.043208781859135,Change in flooding,Climate and weather,3
Montane freshwaters,IceChg,4.593056591017697,Change in ice cover,Climate and weather,1
Montane freshwaters,Invasv,2.140897845917023,Invasive non-native species,Invasive species,7
Montane freshwaters,Mining,1.234453164457141,Mining,Pollution,13
Montane freshwaters,OilGas,1.909945066010751,Oil or gas exploration,Pollution,9
Montane freshwaters,OvrFsh,2.270724588128579,Overfishing,Exploitation,6
Montane freshwaters,Pharma,2.998437522412737,Pharmaceuticals,Pollution,4
Montane freshwaters,Plastic,2.307813729605036,Plastics,Pollution,5
Montane freshwaters,RipDeg,1.1453432828660073,Riparian degradation,Habitat,15
Montane freshwaters,TmpChg,1.444238811827908,Change in water temperature,Climate and weather,10
Montane freshwaters,Use,1.2445991214159609,Water use,Habitat,12
Montane freshwaters,WetLoss,0.7881073630275929,Wetland drainage,Habitat,16
Oceanic islands,Dams,0,Dams,Habitat,15
Oceanic islands,Defor,0.7156679406645173,Deforestation and associated runoff,Habitat,10
Oceanic islands,Drght,0.24315179945983642,Drought,Climate and weather,12
Oceanic islands,Eff,0.9152916280983501,Effluents,Pollution,5
Oceanic islands,FldChg,0.9065482718479798,Change in flooding,Climate and weather,6
Oceanic islands,IceChg,0,Change in ice cover,Climate and weather,16
Oceanic islands,Invasv,2.975255964543224,Invasive non-native species,Invasive species,1
Oceanic islands,Mining,0.743502245675825,Mining,Pollution,9
Oceanic islands,OilGas,0.6247709755273585,Oil or gas exploration,Pollution,11
Oceanic islands,OvrFsh,1.9572238091230074,Overfishing,Exploitation,2
Oceanic islands,Pharma,0.014472771160354815,Pharmaceuticals,Pollution,14
Oceanic islands,Plastic,0.8315117820082809,Plastics,Pollution,7
Oceanic islands,RipDeg,1.7051454193089808,Riparian degradation,Habitat,3
Oceanic islands,TmpChg,0.20261396088677627,Change in water temperature,Climate and weather,13
Oceanic islands,Use,0.7543378689423663,Water use,Habitat,8
Oceanic islands,WetLoss,1.256939549195122,Wetland drainage,Habitat,4
Polar freshwaters,Dams,0.6321143917710346,Dams,Habitat,9
Polar freshwaters,Defor,2.7294978698177883,Deforestation and associated runoff,Habitat,2
Polar freshwaters,Drght,0.3624394208016193,Drought,Climate and weather,12
Polar freshwaters,Eff,0.4428895701860987,Effluents,Pollution,11
Polar freshwaters,FldChg,0.6833596891086707,Change in flooding,Climate and weather,7
Polar freshwaters,IceChg,2.8428100386517645,Change in ice cover,Climate and weather,1
Polar freshwaters,Invasv,2.085522063403857,Invasive non-native species,Invasive species,4
Polar freshwaters,Mining,2.580386747099546,Mining,Pollution,3
Polar freshwaters,OilGas,1.453464860629557,Oil or gas exploration,Pollution,6
Polar freshwaters,OvrFsh,0.6406946206254458,Overfishing,Exploitation,8
Polar freshwaters,Pharma,0.14602464144957308,Pharmaceuticals,Pollution,15
Polar freshwaters,Plastic,0.03822161524959517,Plastics,Pollution,16
Polar freshwaters,RipDeg,0.3449377483977404,Riparian degradation,Habitat,13
Polar freshwaters,TmpChg,0.5221662197147193,Change in water temperature,Climate and weather,10
Polar freshwaters,Use,0.3179710943290474,Water use,Habitat,14
Polar freshwaters,WetLoss,1.4928949037414856,Wetland drainage,Habitat,5
Temperate rivers,Dams,4.161171183186617,Dams,Habitat,4
Temperate rivers,Defor,2.8725489668449673,Deforestation and associated runoff,Habitat,12
Temperate rivers,Drght,3.392178560191139,Drought,Climate and weather,6
Temperate rivers,Eff,4.490384713268548,Effluents,Pollution,2
Temperate rivers,FldChg,3.1201808052118443,Change in flooding,Climate and weather,9
Temperate rivers,IceChg,2.2291533600298976,Change in ice cover,Climate and weather,14
Temperate rivers,Invasv,6.0682790206887205,Invasive non-native species,Invasive species,1
Temperate rivers,Mining,3.0606303093706395,Mining,Pollution,11
Temperate rivers,OilGas,3.331526821618613,Oil or gas exploration,Pollution,7
Temperate rivers,OvrFsh,2.1089097216915063,Overfishing,Exploitation,16
Temperate rivers,Pharma,3.2685797703086,Pharmaceuticals,Pollution,8
Temperate rivers,Plastic,2.2162958939481,Plastics,Pollution,15
Temperate rivers,RipDeg,4.049273898887935,Riparian degradation,Habitat,5
Temperate rivers,TmpChg,2.466713742294166,Change in water temperature,Climate and weather,13
Temperate rivers,Use,3.1070436893174924,Water use,Habitat,10
Temperate rivers,WetLoss,4.411611182505047,Wetland drainage,Habitat,3
Tropical rivers,Dams,3.066230274521025,Dams,Habitat,9
Tropical rivers,Defor,4.403167569330243,Deforestation and associated runoff,Habitat,1
Tropical rivers,Drght,3.2681666549360515,Drought,Climate and weather,5
Tropical rivers,Eff,3.5362345008163323,Effluents,Pollution,4
Tropical rivers,FldChg,2.6026569651658056,Change in flooding,Climate and weather,12
Tropical rivers,IceChg,0.6172957829815905,Change in ice cover,Climate and weather,16
Tropical rivers,Invasv,2.560876018238972,Invasive non-native species,Invasive species,14
Tropical rivers,Mining,2.586281602040581,Mining,Pollution,13
Tropical rivers,OilGas,2.6372215114893947,Oil or gas exploration,Pollution,11
Tropical rivers,OvrFsh,4.317052900744602,Overfishing,Exploitation,2
Tropical rivers,Pharma,3.2657462160191844,Pharmaceuticals,Pollution,6
Tropical rivers,Plastic,3.58094915165575,Plastics,Pollution,3
Tropical rivers,RipDeg,3.237039300200712,Riparian degradation,Habitat,7
Tropical rivers,TmpChg,2.9329783099156295,Change in water temperature,Climate and weather,10
Tropical rivers,Use,1.8854766250645492,Water use,Habitat,15
Tropical rivers,WetLoss,3.161565763232946,Wetland drainage,Habitat,8
......@@ -2,16 +2,6 @@ export default {
chartGridItems: [
//we'll be replacing these img_src with paths to location on s3
//vizRoutes will direct to appropriate subpage
{
title: 'Inland fisheries are threatened',
project: 'Findex',
vizKey: 'ThreatBumpChart',
vizRoute: 'inland-fish-threats',
img_src: 'ThreatBumpChart_thumbnail.png',
alt: '',
chartOrder: 1,
description: 'Inland fisheries are threatened.'
},
{
title: 'Inland fisheries are threatened',
project: 'Findex',
......
......@@ -50,13 +50,6 @@ export default {
profile_link: 'https://www.usgs.gov/staff-profiles/jeffrey-kwang'
},
],
ThreatBumpChart: [
{
fullName: 'Cee Nell',
initials: 'CN',
profile_link: 'https://www.usgs.gov/staff-profiles/cee-nell'
}
],
BeaufortSeaSpecies: [
{
fullName: 'Althea A. Archer',
......
......@@ -104,9 +104,6 @@ export default {
paragraph1: "From analysis of <a href='/visualizations/earth-in-flux/#/fire-in-ice/glacier-scan' target='_blank'>glacial ice cores</a>, we know that <a href='/visualizations/earth-in-flux/#/fire-in-ice/wildfire-aerosols' target='_blank'>wildfires burning softwoods have deposited aerosols</a> on the Juneau Ice Field. We also know that Alaska has many softwood forests, and that some have burned. But how can we tell which regional fires deposited aerosols on the glacier?",
paragraph2: "Researchers use an <a href='https://www.ready.noaa.gov/HYSPLIT.php' target='_blank'>atmospheric model</a> to trace the potential path of smoke particles generated by known wildfires, identifying 'candidate' fires that could be the source for aerosols deposited on the ice field during the sampled period."
},
ThreatBumpChart: {
heading: "Inland fisheries are threatened."
},
BeaufortSeaCore: {
heading1: "Why collect ocean sediment cores?",
intro1: "Ocean sediments are one of the best archives of past ocean conditions and changes to the climate throughout Earth's history.",
......
<template>
<!---VizSection-->
<VizSection
:figures="true"
:fig-caption="false"
>
<!-- HEADING -->
<template #heading>
<h2>
{{ text.heading }}
</h2>
</template>
<!-- FIGURES -->
<template #aboveExplanation>
</template>
<template #figures>
<div class="chart-container" ref="chart">
<div class="toggles">
<span v-for="category in threatCategories" :key="category">
<input type="checkbox" :id="category" v-model="activeCategories[category]" />
<label :for="category">{{ category }}</label>
</span>
</div>
</div>
</template>
<!-- FIGURE CAPTION -->
<template #figureCaption>
</template>
<!-- EXPLANATION -->
<template #belowExplanation>
</template>
</VizSection>
</template>
<script setup>
import { onMounted, ref, reactive, watch } from 'vue';
import * as d3 from 'd3';
import VizSection from '@/components/VizSection.vue';
// define props
defineProps({
text: { type: Object }
})
// global variables
const publicPath = import.meta.env.BASE_URL;
const chart = ref(null);
const threatCategories = ref([]);
const defaultOpacity = 0.8;
const dimOpacity = 0.15;
// Create a reactive object to track active categories
const activeCategories = reactive({});
// Define custom colors
const customColors = [
'#0075A2', '#FAB13C', '#6D435A', '#7FD1B9', '#EF626C'
];
// Behavior on mounted - functions called here
onMounted(() => {
createBumpChart();
});
const createBumpChart = async () => {
// Load the CSV data
const data = await d3.csv(publicPath + 'findex_ranked_threats.csv');
// Process the data
const nestedData = d3.group(data, d => d.Habitat, d => d.ThreatCode);
const habitats = Array.from(nestedData.keys());
const threatCodes = Array.from(new Set(data.map(d => d.ThreatCode)));
threatCategories.value = Array.from(new Set(data.map(d => d.ThreatCategory)));
// Initialize the activeCategories object
threatCategories.value.forEach(category => {
activeCategories[category] = true;
});
// Watch for changes in active categories and update the chart
watch(activeCategories, () => {
updateCategoryStyles();
}, { deep: true });
// Set up the SVG canvas dimensions
const margin = { top: 20, right: 20, bottom: 80, left: 200 },
width = 1200 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
const svg = d3.select(chart.value)
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
// Set up scales
const x = d3.scalePoint()
.domain(habitats)
.range([0, width])
.padding(0.5);
const y = d3.scaleLinear()
.domain([1, threatCodes.length])
.range([0, height]);
const widthScale = d3.scaleLinear()
.domain([0, d3.max(data, d => +d.AverageThreatMetric)])
.range([10, height / threatCodes.length]);
const colorScale = d3.scaleOrdinal()
.domain(threatCategories.value)
.range(customColors);
const area = d3.area()
.x(d => x(d.habitat))
.y0(d => y(d.rank) - widthScale(d.AverageThreatMetric) / 2)
.y1(d => y(d.rank) + widthScale(d.AverageThreatMetric) / 2)
.curve(d3.curveMonotoneX);
const rankData = threatCodes.map(threatCode => {
const ranks = habitats.map(habitat => {
const habitatData = nestedData.get(habitat);
const threatData = habitatData.get(threatCode)[0];
return {
habitat: habitat,
rank: +threatData.Rank,
category: threatData.ThreatCategory,
AverageThreatMetric: +threatData.AverageThreatMetric,
ThreatCode: threatCode,
threat: threatData.Threat
};
});
return {
threatCode: threatCode,
values: ranks,
category: ranks[0].category
};
});
const bumpAreasPoints = svg.append("g")
.attr("id", "areas-points")
bumpAreasPoints
.selectAll('.area')
.data(rankData)
.enter().append('path')
.attr('class', d => `area ${sanitizeClass(d.threatCode)} ${sanitizeClass(d.category)}`)
.attr('d', d => area(d.values))
.attr('fill', d => colorScale(d.category))
.style("opacity", defaultOpacity)
.style('stroke', 'none');
bumpAreasPoints
.selectAll('.point')
.data(rankData.flatMap(d => d.values))
.enter().append('circle')
.attr('class', d => `point ${sanitizeClass(d.ThreatCode)} ${sanitizeClass(d.habitat)} ${sanitizeClass(d.category)}`)
.attr('cx', d => x(d.habitat))
.attr('cy', d => y(d.rank))
.attr('r', d => widthScale(d.AverageThreatMetric) / 2)
.attr('fill', 'white')
.attr('stroke', d => colorScale(d.category))
.style('stroke-width', 2)
.on('mouseover', function (event, d) {
mouseoverThreat(d.ThreatCode, d.category)
})
.on('mouseout', mouseoutThreat);
svg.append("g")
.attr("id", "overlays")
.selectAll('.overlay')
.data(rankData)
.enter().append('path')
.attr('class', d => `overlay ${sanitizeClass(d.threatCode)} ${sanitizeClass(d.category)}`)
.attr('d', d => area(d.values))
.attr('fill', 'transparent')
.on('mouseover', function (event, d) {
mouseoverThreat(d.threatCode, d.category)
})
.on('mouseout', mouseoutThreat);
svg.append("g")
.attr("id", "labels")
.selectAll('.label')
.data(rankData)
.enter().append('text')
.attr('class', d => `label ${sanitizeClass(d.threatCode)} ${sanitizeClass(d.category)}`)
.attr('x', 50)
.attr('y', d => y(d.values[0].rank))
.attr('dy', '.35em')
.attr('text-anchor', 'end')
.attr('id', d => `label-${sanitizeClass(d.threatCode)}`)
.text(d => d.values[0].threat)
.style('font-size', '12px')
.style('fill', d => colorScale(d.category))
.on("mouseover", function (event, d) {
mouseoverThreat(d.threatCode, d.category)
})
.on('mouseout', mouseoutThreat);
const xAxis = svg.append('g')
.attr('class', 'x-axis')
.attr('transform', `translate(0,${height + 15})`)
.call(d3.axisBottom(x))
.attr("stroke-width", 0)
.attr("font-size", 16)
.attr('font-weight', 700)
xAxis.selectAll('text')
.attr('text-anchor', 'middle') //'end')
// .attr('dy', '-0.5rem')
// .attr('transform', 'rotate(270)');
// Wrap x-axis labels on mobile
.call(d => wrapHorizontalLabels(d, 20));
const updateCategoryStyles = () => {
threatCategories.value.forEach(category => {
if (activeCategories[category]) {
d3.selectAll(`.overlay.${sanitizeClass(category)}`)
.raise()
d3.selectAll(`.area.${sanitizeClass(category)}`)
.style('opacity', defaultOpacity)
.style('fill', colorScale(category));
d3.selectAll(`.point.${sanitizeClass(category)}`)
.style('opacity', 1)
.style('stroke', colorScale(category));
d3.selectAll(`.label.${sanitizeClass(category)}`)
.style('opacity', 1)
.style('fill', colorScale(category));
} else {
d3.selectAll(`.overlay.${sanitizeClass(category)}`)
.lower()
d3.selectAll(`.area.${sanitizeClass(category)}`)
.style('opacity', dimOpacity)
.style('fill', '#949494');
d3.selectAll(`.point.${sanitizeClass(category)}`)
.style('opacity', dimOpacity)
.style('stroke', '#949494');
d3.selectAll(`.label.${sanitizeClass(category)}`)
.style('opacity', 1)
.style('fill', '#6E6E6E');
}
});
};
};
function sanitizeClass(name) {
return name ? name.replace(/[^a-zA-Z0-9]/g, '_') : 'unknown';
}
function mouseoverThreat(threatCode, category) {
if (activeCategories[category]) {
d3.selectAll('.area')
.transition(getUpdateTransition())
.style('opacity', dimOpacity);
d3.selectAll('.point')
.transition(getUpdateTransition())
.style('stroke-opacity', dimOpacity);
d3.selectAll('.label')
.transition(getUpdateTransition())
.style('opacity', dimOpacity);
d3.selectAll(`.${sanitizeClass(threatCode)}`)
.transition(getUpdateTransition())
.style('opacity', 1)
.style('stroke-opacity', 1)
.style('font-weight', 'bold');
d3.selectAll(`.area.${sanitizeClass(threatCode)}`)
.raise();
d3.selectAll(`.point.${sanitizeClass(threatCode)}`)
.raise();
}
}
function mouseoutThreat() {
threatCategories.value.forEach(category => {
if (activeCategories[category]) {
d3.selectAll(`.area.${sanitizeClass(category)}`)
.transition(getUpdateTransition())
.style('opacity', defaultOpacity);
d3.selectAll(`.point.${sanitizeClass(category)}`)
.transition(getUpdateTransition())
.style('stroke-opacity', 1);
d3.selectAll(`.label.${sanitizeClass(category)}`)
.transition(getUpdateTransition())
.style('opacity', 1)
.style('font-weight', 'normal');
}
});
d3.selectAll('.point')
.raise();
}
function getUpdateTransition() {
return d3.transition()
.duration(200)
.ease(d3.easeCubicInOut)
}
// function to wrap text added with d3 modified from
// https://stackoverflow.com/questions/24784302/wrapping-text-in-d3
// which is adapted from https://bl.ocks.org/mbostock/7555321
function wrapHorizontalLabels(text, width) {
text.each(function () {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 0.6,
x = 0,
y = text.attr("x"), // Use x b/c wrapping horizontal labels
dy = 0, //parseFloat(text.attr("dy")),
tspan = text.text(null)
.append("tspan")
.attr("x", x)
.attr("y", y)
.attr("dy", dy + "rem");
while ((word = words.pop())) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan")
.attr("x", x)
.attr("y", y)
.attr("dy", ++lineNumber > 3 ? ++lineNumber * 0.3 * lineHeight + dy + "em" : ++lineNumber * 0.5 * lineHeight + dy + "em")
.text(word);
}
}
});
}
</script>
<style scoped>
.chart-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
max-width: 900px;
height: auto;
margin: auto;
margin-top: 50px;
}
.toggles {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 20px;
}
.toggles span {
margin-right: 10px;
}
.toggles label {
margin-left: 5px;
}
</style>
<style lang="scss">
.label {
cursor: pointer;
}
</style>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment