diff --git a/dashboard_website/index.html b/dashboard_website/index.html index bcea719..61765a6 100644 --- a/dashboard_website/index.html +++ b/dashboard_website/index.html @@ -40,12 +40,21 @@

IVIM MRI Algorithm Fitting Dashboard

- Range: + Upper Range: + 0 - + - 2x + 2
+
+ Lower Range: + 0 + + + + 2 +
@@ -72,12 +81,20 @@

IVIM MRI Algorithm Fitting Dashboard

- Range: + Upper Range: - 2x + 2
+
+ Lower Range: + 0 + + + + 2 +
diff --git a/dashboard_website/index.js b/dashboard_website/index.js index 86e25a9..9810dc7 100644 --- a/dashboard_website/index.js +++ b/dashboard_website/index.js @@ -3,11 +3,18 @@ document.addEventListener('DOMContentLoaded', function() { let selectedAlgorithm = 'ETP_SRI_LinearFitting'; let selectedSNR = '10'; let selectedType = 'D_fitted'; - let selectedRange = 2; + let selectedRange = 10; + let selectedRangeLower = 2; let selectedRegion = 'Liver'; let selectedSNRRegion = '10'; let selectedTypeRegion = 'D_fitted'; - let selectedRangeRegion = 2; + let selectedRangeRegion = 10; + let selectedRangeLowerRegion = 2; + const type = { + "D_fitted": "Diffusion", + "Dp_fitted": "Perfusion", + "f_fitted": "Perfusion Fraction" + }; const loadingOverlay = document.getElementById('loadingOverlay'); const mainContent = document.getElementsByTagName('main')[0]; @@ -25,24 +32,27 @@ document.addEventListener('DOMContentLoaded', function() { const algorithmSelect = document.getElementById('algorithm-select'); algorithmSelect.addEventListener('change', function(event) { selectedAlgorithm = event.target.value; - updateRange('2') - drawBoxPlot(data, selectedAlgorithm, selectedSNR, selectedType, selectedRange); + updateRange('10') + updateRangeLower('2') + drawBoxPlot(); }); // Add event listener to SNR select const snrSelect = document.getElementById('snr-select'); snrSelect.addEventListener('change', function(event) { selectedSNR = event.target.value; - updateRange('2') - drawBoxPlot(data, selectedAlgorithm, selectedSNR, selectedType, selectedRange); + updateRange('10') + updateRangeLower('2') + drawBoxPlot(); }); // Add event listener to type select const typeSelect = document.getElementById('type-select'); typeSelect.addEventListener('change', function(event) { selectedType = event.target.value; - updateRange('2') - drawBoxPlot(data, selectedAlgorithm, selectedSNR, selectedType, selectedRange); + updateRange('10') + updateRangeLower('2') + drawBoxPlot(); }); // Add event listeners to range slider and buttons @@ -52,9 +62,9 @@ document.addEventListener('DOMContentLoaded', function() { const incrementRange = document.getElementById('increment-range'); function updateRange(value) { selectedRange = value; - rangeValue.textContent = value; + //rangeValue.textContent = value; rangeSlider.value = value - drawBoxPlot(data, selectedAlgorithm, selectedSNR, selectedType, selectedRange); + drawBoxPlot(); } rangeSlider.addEventListener('input', function(event) { @@ -77,28 +87,63 @@ document.addEventListener('DOMContentLoaded', function() { } }); + // Add event listeners to range slider and buttons + const rangeSliderLower = document.getElementById('lower-range-slider'); + const rangeValueLower = document.getElementById('lower-range-value'); + const decrementRangeLower = document.getElementById('decrement-lower-range'); + const incrementRangeLower = document.getElementById('increment-lower-range'); + function updateRangeLower(value) { + selectedRangeLower = value; + //rangeValue.textContent = value; + rangeSliderLower.value = value + drawBoxPlot(); + } + + rangeSliderLower.addEventListener('input', function(event) { + updateRangeLower(event.target.value); + }); + + decrementRangeLower.addEventListener('click', function() { + let newValue = parseInt(rangeSlider.value) - 2; + if (newValue >= 2) { + rangeSliderLower.value = newValue; + updateRangeLower(newValue); + } + }); + + incrementRangeLower.addEventListener('click', function() { + let newValue = parseInt(rangeSliderLower.value) + 2; + if (newValue <= rangeSliderLower.max) { + rangeSliderLower.value = newValue; + updateRangeLower(newValue); + } + }); + // Add event listener to region select const regionSelect = document.getElementById('region-select'); regionSelect.addEventListener('change', function(event) { selectedRegion = event.target.value; - updateRangeRegion('2') - drawRegionBoxPlot(data, selectedRegion, selectedSNRRegion, selectedTypeRegion, selectedRangeRegion); + updateRangeRegion('10') + updateRangeLowerRegion('2') + drawRegionBoxPlot(); }); // Add event listener to SNR select const snrRegionSelect = document.getElementById('snr-region-select'); snrRegionSelect.addEventListener('change', function(event) { selectedSNRRegion = event.target.value; - updateRangeRegion('2') - drawRegionBoxPlot(data, selectedRegion, selectedSNRRegion, selectedTypeRegion, selectedRangeRegion); + updateRangeRegion('10') + updateRangeLowerRegion('2') + drawRegionBoxPlot(); }); // Add event listener to type select const typeRegionSelect = document.getElementById('type-region-select'); typeRegionSelect.addEventListener('change', function(event) { selectedTypeRegion = event.target.value; - updateRangeRegion('2') - drawRegionBoxPlot(data, selectedRegion, selectedSNRRegion, selectedTypeRegion, selectedRangeRegion); + updateRangeRegion('10') + updateRangeLowerRegion('2') + drawRegionBoxPlot(); }); // Add event listeners to range region slider and buttons @@ -109,9 +154,9 @@ document.addEventListener('DOMContentLoaded', function() { function updateRangeRegion(value) { selectedRangeRegion = value; - rangeValueRegion.textContent = value; + //rangeValueRegion.textContent = value; rangeSliderRegion.value = value - drawRegionBoxPlot(data, selectedRegion, selectedSNRRegion, selectedTypeRegion, selectedRangeRegion); + drawRegionBoxPlot(); } rangeSliderRegion.addEventListener('input', function(event) { @@ -134,6 +179,38 @@ document.addEventListener('DOMContentLoaded', function() { } }); + // Add event listeners to range slider and buttons for region + const rangeSliderLowerRegion = document.getElementById('lower-range-slider-region'); + const rangeValueLowerRegion = document.getElementById('lower-range-value-region'); + const decrementRangeLowerRegion = document.getElementById('decrement-lower-range-region'); + const incrementRangeLowerRegion = document.getElementById('increment-lower-range-region'); + function updateRangeLowerRegion(value) { + selectedRangeLowerRegion = value; + //rangeValue.textContent = value; + rangeSliderLowerRegion.value = value + drawRegionBoxPlot(); + } + + rangeSliderLowerRegion.addEventListener('input', function(event) { + updateRangeLowerRegion(event.target.value); + }); + + decrementRangeLowerRegion.addEventListener('click', function() { + let newValue = parseInt(rangeSliderRegion.value) - 2; + if (newValue >= 2) { + rangeSliderLowerRegion.value = newValue; + updateRangeLowerRegion(newValue); + } + }); + + incrementRangeLowerRegion.addEventListener('click', function() { + let newValue = parseInt(rangeSliderLowerRegion.value) + 2; + if (newValue <= rangeSliderLowerRegion.max) { + rangeSliderLowerRegion.value = newValue; + updateRangeLowerRegion(newValue); + } + }); + showLoading(); Papa.parse('test_output.csv', { @@ -143,8 +220,8 @@ document.addEventListener('DOMContentLoaded', function() { data = results; hideLoading(); populateOptions(data); - drawBoxPlot(data, selectedAlgorithm, selectedSNR, selectedType, selectedRange); - drawRegionBoxPlot(data, selectedRegion, selectedSNRRegion, selectedTypeRegion, selectedRangeRegion); + drawBoxPlot(); + drawRegionBoxPlot(); } }); @@ -194,24 +271,30 @@ document.addEventListener('DOMContentLoaded', function() { } - function drawBoxPlot(data, selectedAlgorithm, selectedSNR, selectedType, selectedRange) { + function drawBoxPlot() { let jsonData = data.data.filter(obj => obj.Algorithm === selectedAlgorithm); - const type = { - "D_fitted": "Diffusion", - "Dp_fitted": "Perfusion", - "f_fitted": "Perfusion Fraction" - }; const allD_fittedValues = jsonData .filter(obj => obj.SNR === selectedSNR) .map(obj => obj[selectedType]); - const maxValue = Math.max(...allD_fittedValues.map(Math.abs)); + const maxValue = Math.max(...allD_fittedValues); + const minValue = Math.min(...allD_fittedValues); const groundTruthList = jsonData - .filter(obj => obj.SNR === selectedSNR) - .map(obj => obj[selectedType.slice(0, -7)]); + .filter(obj => obj.SNR === selectedSNR) + .map(obj => obj[selectedType.slice(0, -7)]); let estimatedRange = Math.abs(maxValue) / Math.min(...groundTruthList) - rangeSlider.max = Math.round(estimatedRange / 2) * 2 + let estimatedRangeLower = Math.abs(minValue) / Math.min(...groundTruthList) + if (minValue < 0) { + rangeValueLower.textContent = minValue.toFixed(4) + } + else { + rangeValueLower.textContent = '0.0000' + selectedRangeLower = 0; + } + rangeValue.textContent = maxValue.toFixed(4) + rangeSlider.max = Math.round(estimatedRange / 2) * 2 + rangeSliderLower.max = Math.round(estimatedRangeLower / 2) * 2 let plots = []; const regions = new Set(jsonData.map(obj => obj.Region)); const uniqueRegionsArray = Array.from(regions); @@ -219,7 +302,6 @@ document.addEventListener('DOMContentLoaded', function() { const D_fittedValues = jsonData .filter(obj => obj.Region === region) .filter(obj => obj.SNR === selectedSNR) - .filter(obj => Math.abs(obj[selectedType]) < (Math.abs(obj[selectedType.slice(0, -7)]) * selectedRange)) .map(obj => obj[selectedType]); var plot = { y: D_fittedValues, @@ -250,30 +332,42 @@ document.addEventListener('DOMContentLoaded', function() { }); var layout = { - title: `${type[selectedType]} Box Plots for ${selectedAlgorithm} algorithm with ${selectedSNR} SNR` + title: `${type[selectedType]} Box Plots for ${selectedAlgorithm} algorithm with ${selectedSNR} SNR`, + yaxis: { + autorange: false, + range: [-Math.min(...groundTruthList) * selectedRangeLower, Math.min(...groundTruthList) * selectedRange], + type: 'linear' + } }; Plotly.newPlot('myDiv', plots, layout); } - function drawRegionBoxPlot(data, selectedRegion, selectedSNR, selectedType, selectedRange) { + function drawRegionBoxPlot() { let jsonData = data.data.filter(obj => obj.Region === selectedRegion); - const type = { - "D_fitted": "Diffusion", - "Dp_fitted": "Perfusion", - "f_fitted": "Perfusion Fraction" - }; const allD_fittedValues = jsonData - .filter(obj => obj.SNR === selectedSNR) - .map(obj => obj[selectedType]); + .filter(obj => obj.SNR === selectedSNRRegion) + .map(obj => obj[selectedTypeRegion]); + + const maxValue = Math.max(...allD_fittedValues); + const minValue = Math.min(...allD_fittedValues); - const maxValue = Math.max(...allD_fittedValues.map(Math.abs)); const groundTruthList = jsonData - .filter(obj => obj.SNR === selectedSNR) - .map(obj => obj[selectedType.slice(0, -7)]); + .filter(obj => obj.SNR === selectedSNRRegion) + .map(obj => obj[selectedTypeRegion.slice(0, -7)]); let estimatedRange = Math.abs(maxValue) / Math.min(...groundTruthList) - rangeSliderRegion.max = Math.round(estimatedRange / 2) * 2 + let estimatedRangeLower = Math.abs(minValue) / Math.min(...groundTruthList) + if (minValue < 0) { + rangeValueLowerRegion.textContent = minValue.toFixed(4) + } + else { + rangeValueLowerRegion.textContent = '0.0000' + selectedRangeLowerRegion = 0; + } + rangeValueRegion.textContent = maxValue.toFixed(4) + rangeSliderRegion.max = Math.round(estimatedRange / 2) * 2 + rangeSliderLowerRegion.max = Math.round(estimatedRangeLower / 2) * 2 let plots = []; const algorithms = new Set(jsonData.map(obj => obj.Algorithm)); @@ -281,23 +375,22 @@ document.addEventListener('DOMContentLoaded', function() { uniqueAlgorithmsArray.forEach(algorithm => { const D_fittedValues = jsonData .filter(obj => obj.Algorithm === algorithm) - .filter(obj => obj.SNR === selectedSNR) - .filter(obj => Math.abs(obj[selectedType]) < (Math.abs(obj[selectedType.slice(0, -7)]) * selectedRange)) - .map(obj => obj[selectedType]); + .filter(obj => obj.SNR === selectedSNRRegion) + .map(obj => obj[selectedTypeRegion]); var plot = { y: D_fittedValues, type: 'box', name: algorithm, marker: { - outliercolor: 'white)', + outliercolor: 'white', }, boxpoints: 'Outliers' }; plots.push(plot); const groundTruth = jsonData .filter(obj => obj.Algorithm === algorithm) - .filter(obj => obj.SNR === selectedSNR) - .map(obj => obj[selectedType.slice(0, -7)]); + .filter(obj => obj.SNR === selectedSNRRegion) + .map(obj => obj[selectedTypeRegion.slice(0, -7)]); var constantPoint = { x: [algorithm], y: groundTruth, @@ -313,7 +406,12 @@ document.addEventListener('DOMContentLoaded', function() { }); var layout = { - title: `${type[selectedType]} Box Plots for ${selectedRegion} region with ${selectedSNR} SNR` + title: `${type[selectedTypeRegion]} Box Plots for ${selectedRegion} region with ${selectedSNR} SNR`, + yaxis: { + autorange: false, + range: [-Math.min(...groundTruthList) * selectedRangeLowerRegion, Math.min(...groundTruthList) * selectedRangeRegion], + type: 'linear' + } }; Plotly.newPlot('regionDiv', plots, layout);