diff --git a/index.html b/index.html index 9e8e298ee6d1a0d002e36c582d47a04cc3f919be..8e1aa4d858c6b417fd663dbe7eb458843ece5da9 100644 --- a/index.html +++ b/index.html @@ -10,7 +10,7 @@ <body> <div id="tree-container" class="visualization-container visible"> - <button id="back-button" class="button button-inner" disabled>Back</button> + <button id="back-button" class="button button-inner button-regular" disabled>Back</button> </div> <div id="time-series-container" class="visualization-container"> diff --git a/modules/lib.js b/modules/lib.js index 3615e598539cd2d75d6e4826b9d57d6fdfe81ec4..6c25249e672e6959be669c61c7fd7ee17a1c7055 100644 --- a/modules/lib.js +++ b/modules/lib.js @@ -79,6 +79,35 @@ export async function loadData() { } } +const views = { + tree: document.getElementById('tree-container'), + timeSeries: document.getElementById('time-series-container'), + parallel: document.getElementById('parallel-coordinates-container'), + bubble: document.getElementById('bubble-container') +}; + +const buttons = { + tree: document.getElementById('tree-view'), + timeSeries: document.getElementById('time-series-view'), + parallel: document.getElementById('parallel-view'), + bubble: document.getElementById('bubble-view') +}; + +export function navigate(viewName) { + Object.values(views).forEach(view => view.classList.remove('visible')); + Object.values(buttons).forEach(button => button.classList.remove('active')); + + views[viewName].classList.add('visible'); + buttons[viewName].classList.add('active'); +} + +export function initNavigation() { + buttons.tree.addEventListener('click', () => navigate('tree')); + buttons.timeSeries.addEventListener('click', () => navigate('timeSeries')); + buttons.parallel.addEventListener('click', () => navigate('parallel')); + buttons.bubble.addEventListener('click', () => navigate('bubble')); +} + export const margin = { top: 20, right: 30, bottom: 50, left: 50 }; export const width = window.innerWidth - margin.left - margin.right; export const height = window.innerHeight - margin.top - margin.bottom; diff --git a/modules/main.js b/modules/main.js index b828901f7461daea2b04d27f30ac68aa89a1ad51..8bc0332ad72a6dda8924a683cc0d2e2a0a139d4a 100644 --- a/modules/main.js +++ b/modules/main.js @@ -1,33 +1,8 @@ -import {getDimensions, loadData} from "./lib.js"; +import {getDimensions, initNavigation, loadData} from "./lib.js"; window.addEventListener('load', () => { // navigation - const views = { - tree: document.getElementById('tree-container'), - timeSeries: document.getElementById('time-series-container'), - parallel: document.getElementById('parallel-coordinates-container'), - bubble: document.getElementById('bubble-container') - }; - - const buttons = { - tree: document.getElementById('tree-view'), - timeSeries: document.getElementById('time-series-view'), - parallel: document.getElementById('parallel-view'), - bubble: document.getElementById('bubble-view') - }; - - function showView(viewName) { - Object.values(views).forEach(view => view.classList.remove('visible')); - Object.values(buttons).forEach(button => button.classList.remove('active')); - - views[viewName].classList.add('visible'); - buttons[viewName].classList.add('active'); - } - - buttons.tree.addEventListener('click', () => showView('tree')); - buttons.timeSeries.addEventListener('click', () => showView('timeSeries')); - buttons.parallel.addEventListener('click', () => showView('parallel')); - buttons.bubble.addEventListener('click', () => showView('bubble')); + initNavigation() //data filter buttons diff --git a/modules/parallel.js b/modules/parallel.js index 42e57104c35164be9a2d9d994987ed837511924b..a4c8b4e92f93aa9f59de38f2784bd78e333d3eee 100644 --- a/modules/parallel.js +++ b/modules/parallel.js @@ -31,7 +31,7 @@ loadData().then(([data,_]) => { const dimensions = getDimensions(data) const yScales = {}; - const epsilon = 1; // Small positive constant to avoid log(0) + const epsilon = 0.1; // Small positive constant to avoid log(0) dimensions.forEach(dim => { const extent = d3.extent(data, d => d[dim]); const adjustedExtent = [extent[0] + epsilon, extent[1] + epsilon]; @@ -67,12 +67,6 @@ loadData().then(([data,_]) => { function updatePlot(state) { const filteredData = state ? groupedData.get(state) : data; - if (!filteredData) { - console.warn(`No data available for state: ${state}`); - svg.selectAll(".data-line").remove(); - return; - } - const paths = svg.selectAll(".data-line") .data(filteredData); @@ -115,20 +109,11 @@ loadData().then(([data,_]) => { }); - // Dropdown change event dropdown.on("change", function() { const selectedState = d3.select(this).property("value"); updatePlot(selectedState); }); - // Add reset button functionality - d3.select("#reset-button") - .on("click", () => { - dropdown.property("value", ""); - updatePlot(null); - }); - - // Hide loading indicator after rendering hideLoading(); }).catch(err => { console.error("Error loading data: ", err); diff --git a/modules/tree.js b/modules/tree.js index ec51f8622c201ca7877ddf79a6f525284965b900..6c935634c71da424e8916248f0a434e689083096 100644 --- a/modules/tree.js +++ b/modules/tree.js @@ -1,4 +1,4 @@ -import {addSvg, width, height, margin, loadData} from "./lib.js"; +import {addSvg, width, height, margin, loadData, navigate} from "./lib.js"; let currentData; @@ -156,7 +156,28 @@ function updateTree(filterKey) { if (!d.children) return 0 }) .style("text-anchor", d => d.children ? "end" : "start") - .text(d => d.data.name); + .text(d => d.data.name) + + d3.selectAll(".link-to-parallel").remove() + d3.selectAll(".node").filter((d, i) => i < 2).each(function(d) { + if (d.children&&d.data.name!=="Schengen States"){ + d3.select(this) + .append('foreignObject') + .attr('width', 250) + .attr('height', 50) + .attr('transform', 'translate(-125, 0)') + .append('xhtml:button') + .attr("class", "button button-inner button-regular link-to-parallel") + .text('View as Parallel Coordinates') + .style('cursor', 'pointer') + .on('click', function() { + const stateSelector = d3.select('#state-dropdown'); + stateSelector.property('value', d.data.name); + stateSelector.node().dispatchEvent(new Event('change')); + navigate("parallel") + }); + } + }); } diff --git a/style.css b/style.css index 420f94df2a39824dd51585f578ab5a66efb3e640..0dcaa54330a9d4684202c766eb6b80f50a8e9c49 100644 --- a/style.css +++ b/style.css @@ -70,7 +70,7 @@ html, body, #tree-container, #time-series-container, #bubble-container, #paralle border-radius: 5px; } -#back-button { +.button-regular { font-size: 14px; background-color: #69b3a2; color: white;