diff --git a/treemap/main.js b/treemap/main.js
index 43ec57d..bb47325 100644
--- a/treemap/main.js
+++ b/treemap/main.js
@@ -451,16 +451,21 @@ async function fetchData() {
console.log(root.leaves());
+ // Create group ID (ocean + newGroup)
+ const groupIDs = root
+ .leaves()
+ .map((d) => d.parent.data[0].replace(/\s+/g, '-') + '_' + d.data[0]);
+
// Create a group for each node
const nodes = svg
.selectAll('g')
.data(root.leaves())
.enter()
.append('g')
- .attr('class', (d, i) => {
- return root.leaves()[i].parent.data[0]; // Assuming this returns the class name
- })
- .attr('transform', (d) => `translate(${d.x0},${d.y0})`);
+ .attr('transform', (d) => `translate(${d.x0},${d.y0})`)
+ .attr('id', (d, i) => {
+ return `${groupIDs[i]}`;
+ });
// Define colourScale
const colourScale = d3
@@ -758,35 +763,35 @@ async function fetchData() {
function getDetailedData(ocean) {
switch (ocean) {
- case 'Pacific':
+ case 'Pacific Ocean':
return {
Predator: pPredator,
Prey: pPrey,
Others: pOthers,
};
- case 'Atlantic':
+ case 'Atlantic Ocean':
return {
Predator: atPredator,
Prey: atPrey,
Others: atOthers,
};
- case 'Indian':
+ case 'Indian Ocean':
return {
Predator: iPredator,
Prey: iPrey,
Others: iOthers,
};
- case 'South':
+ case 'South Ocean':
return {
Predator: sPredator,
Others: sOthers,
};
- case 'North':
+ case 'North Sea':
return {
Predator: nPredator,
Others: nOthers,
};
- case 'Arctic':
+ case 'Arctic Ocean':
return {
Predator: arPredator,
};
@@ -831,6 +836,66 @@ async function fetchData() {
//tree map description disappear when zoom in
description.transition().duration(500).style('opacity', 0);
+ // Aggregate the data for the selected ocean and archetype
+ const selectedSeaname = d.parent.data[0];
+ const selectedNewGroup = d.data[0];
+ let rolledupData = getDetailedData(selectedSeaname)[selectedNewGroup];
+ rolledupData = Array.from(rolledupData, ([key, value]) => ({
+ name: key,
+ value,
+ }));
+ rolledupData = rolledupData.sort((a, b) => b.value - a.value);
+
+ const secondTreemapRoot = d3
+ .hierarchy({ children: rolledupData }, (d) => d.children)
+ .sum((d) => d.value);
+
+ d3.treemap().size([width, height]).padding(3).round(true)(
+ secondTreemapRoot
+ );
+
+ // Create a group for each node
+ const groupID = `${selectedSeaname.replace(
+ /\s+/g,
+ '-'
+ )}_${selectedNewGroup}`;
+ const secondTreemap = d3.select(`#${groupID}`);
+
+ if (secondTreemap.empty()) {
+ secondTreemap = svg.append('g').attr('id', groupID);
+ }
+
+ secondTreemap
+ .selectAll('rect')
+ .data(secondTreemapRoot.leaves(), (d) => d.data.name)
+ .enter()
+ .append('rect')
+ .attr('class', 'detailed-node')
+ .attr('x', (d) => d.x0)
+ .attr('y', (d) => d.y0)
+ .attr('width', (d) => d.x1 - d.x0)
+ .attr('height', (d) => d.y1 - d.y0)
+ .attr('fill-opacity', 0.9)
+ .attr('stroke', 'none')
+ .attr('id', (d, i) => {
+ return `${groupID}_${d.data.name}`;
+ })
+ .attr('fill', colourScale(selectedSeaname));
+
+ secondTreemap
+ .selectAll('text')
+ .data(secondTreemapRoot.leaves(), (d) => d.data.name)
+ .enter()
+ .append('text')
+ .text((d) => d.data.name)
+ .attr('class', 'detailed-node')
+ .attr('x', (d) => d.x0 + 10)
+ .attr('y', (d) => d.y0 + 25)
+ .style('font-family', "'Open Sans', sans-serif")
+ .style('font-weight', 'regular')
+ .style('fill', 'white')
+ .style('font-size', '14px');
+
// Secondary Legend, appears when zoomed in and hides when zoom out --------------------------------------------
// Depth
const legendDepth = {
@@ -1036,103 +1101,6 @@ async function fetchData() {
.transition()
.duration(1200)
.style('opacity', 1);
-
- // Fetch detailed data and update the treemap
- const detailedData = getDetailedData(
- 'Pacific',
- 'Atlantic',
- 'Indian',
- 'South',
- 'North',
- 'Arctic'
- );
- console.log('Detailed Data:', detailedData);
-
- if (Object.keys(detailedData).length > 0) {
- const detailedRoot = d3
- .hierarchy({
- children: Object.entries(detailedData).map(([key, value]) => ({
- name: key,
- children: Array.from(value, ([depthRange, count]) => ({
- name: getDepthRange(depthRange),
- value: count,
- })),
- })),
- })
- .sum((d) => d.value)
- .sort((a, b) => b.value - a.value);
-
- console.log('Detailed Root:', detailedRoot);
-
- treemapLayout(detailedRoot);
-
- const detailedNodes = svg.selectAll(".detailed-node")
- .data(detailedRoot.leaves())
- .enter()
- .append("g")
- .attr("class", "detailed-node")
- .attr("transform", node => `translate(${node.x0},${node.y0})`);
-
-
- detailedNodes.append("rect")
- .attr("width", node => node.x1 - node.x0)
- .attr("height", node => node.y1 - node.y0)
- .attr("fill", node => {
- const parentColor = colourScale(node.parent.data.name);
- const shade = d3.scaleLinear()
- .domain([0, (detailedRoot.children ? detailedRoot.children.length : 1) - 1])
- .range([0.3, 0.7]); // Make the shade range darker and wider
- return d3.color(parentColor).darker(shade(detailedRoot.children ? detailedRoot.children.indexOf(node) : 1));
- })
- .attr("fill-opacity", 1)
- .attr("stroke", "none");
-
- detailedNodes.append("text")
- .attr("x", 10)
- .attr("y", 25)
- .style("font-family", "'Open Sans', sans-serif")
- .style("font-weight", "regular")
- .style("fill", "white")
- .style("font-size", node => {
- const fontSize = Math.min((node.x1 - node.x0) / 5, (node.y1 - node.y0) / 5, 16);
- return fontSize < 10 ? "0px" : `${fontSize}px`;
- })
- .text(node => getDepthRange(node.data.value))
- .each(function(node) {
- const bbox = this.getBBox();
- if (bbox.width > (node.x1 - node.x0) || bbox.height > (node.y1 - node.y0)) {
- d3.select(this).remove();
- }
- });
-
- // Add fade-in and scale animation for the detailed nodes
- setTimeout(() => {
- detailedNodes.style("opacity", 0)
- .attr("transform", node => `translate(${x(node.x0)},${y(node.y0)}) scale(0.1)`)
- .transition()
- .duration(1500)
- .style("opacity", 0.9)
- .attr("transform", node => `translate(${x(node.x0)},${y(node.y0)}) scale(1)`);
- }, 2000);
-
- detailedNodes.append("text")
- .attr("x", 10)
- .attr("y", 25)
- .style("font-family", "'Open Sans', sans-serif")
- .style("font-weight", "regular")
- .style("fill", "white")
- .style("font-size", node => {
- const fontSize = Math.min((x(node.x1) - x(node.x0)) / 5, (y(node.y1) - y(node.y0)) / 5, 16);
- return fontSize < 10 ? "0px" : `${fontSize}px`;
- })
- .text(node => getDepthRange(node.data.name))
- .each(function(node) {
- const bbox = this.getBBox();
- if (bbox.width > (x(node.x1) - x(node.x0)) || bbox.height > (y(node.y1) - y(node.y0))) {
- d3.select(this).remove();
- }
- });
- }
}
nodes.on('click', function (event, d) {
@@ -1240,13 +1208,13 @@ async function fetchData() {
.html(
//find a way to make it flexible
`
-
-
-
${mergedData.common_name}
-
${mergedData.title}
-
Archetype: ${mergedData.newGroup}
-
Depth: ${mergedData.depth} m
-
+
+
+
${fishData.common_name}
+
${fishData.title}
+
Archetype: ${fishData.newGroup}
+
Depth: ${fishData.depth} m
+
`
);
})
@@ -1353,7 +1321,7 @@ async function fetchData() {
.style('text-align', 'center')
.style('padding-top', '50px')
.text(
- 'Major Studio I | Exercise 2: Qualitative Representation | Tak | Bella | Xuan'
+ 'Major Studio I | Exercise 2: Qualitative Representation | Hyeonjeong | Xuan'
);
} catch (error) {
console.error('Error fetching or processing data:', error);