Skip to content

Commit 80905b9

Browse files
committed
Implement multiple standards
1 parent 8c99a63 commit 80905b9

5 files changed

Lines changed: 418 additions & 94 deletions

File tree

SedimentDataExplorer.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,7 @@ <h2>Select Radar Plot for Map Popups</h2>
929929
<script src="sdeCharts.js"></script>
930930
<script src="sdeSelections.js"></script>
931931
<script src="sdeMaps.js"></script>
932+
<script src="sdeStandards.js"></script>
932933
<script src="sdeTables.js"></script>
933934

934935
<script>

SedimentDataExplorer.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
let radarPlot = "None";
33
let resuspensionSize = 0;
44
let kmlLayers = {};
5+
let chosenStandard = 'Cefas Action Levels';
56
// import {parse, stringify, toJSON, fromJSON} from 'flatted';
67
const autocolors = window['chartjs-plugin-autocolors'];
78
Chart.register(autocolors);
@@ -261,6 +262,15 @@ for (i = 1; i < dataSheetNames.length; i++) {
261262
ccontainer.appendChild(label);
262263
});
263264

265+
/*standards = {};
266+
267+
document.addEventListener('DOMContentLoaded', async () => {
268+
const dataUrl = 'https://northeastfc.uk/Supporting/quality_standards.sdes';
269+
const parsedData = await readQualityStandards(dataUrl);
270+
const outputElement = document.getElementById('output');
271+
standards = parsedData;
272+
});*/
273+
264274
importData();
265275

266276
function parseDates(dateString) {
@@ -1360,10 +1370,10 @@ let missingTotalSolids = true;
13601370
const applicant = df[14][4];
13611371
const applicationNumber = df[15][4];
13621372
const applicationTitle = df[16][4];*/
1363-
for (i = 16; 19; i++) {
1373+
for (i = 16; i<19; i++) {
13641374
dateRow = i;
1365-
//console.log('df[dateRow][2]',dateRow,df[dateRow][2]);
1366-
if (df[dateRow][2].includes('Date sampled:')) {
1375+
//console.log('df[dateRow][2]',sheetName,i,dateRow,df[dateRow][2],df);
1376+
if (df[dateRow][2]?.includes('Date sampled:')) {
13671377
break;
13681378
}
13691379
dateRow = 0;

sdeMaps.js

Lines changed: 70 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,73 @@ const highlightStyle = {
2020
radius: 10, fillColor: '#FFFF00', color: '#000000', weight: 2, opacity: 1, fillOpacity: 1
2121
};
2222

23+
function applyDynamicStyling(chemicalName) {
24+
const stats = contaminantStats[chemicalName];
25+
if (!stats) return;
26+
//if ((chemicalName === 'LMW PAH Sum') || (chemicalName === 'Anthracene')) {
27+
// console.log(chemicalName, stats);
28+
//}
29+
const { valueMin, valueMax, depthMin, depthMax } = stats;
30+
const { breaks, colors } = getColorScale(valueMin * stats.rescale, valueMax * stats.rescale, chemicalName);
31+
contaminantLayers[chemicalName].eachLayer(marker => {
32+
const value = parseFloat(marker.options._chemValue);
33+
const depth = marker.options._depth;
34+
let color = colors[0];
35+
for (let i = breaks.length; i > 0; i--) {
36+
console.log(i,breaks[i-1],colors[i],value);
37+
if (value > breaks[i-1]) { color = colors[i]; break; }
38+
}
39+
40+
41+
42+
/* if (colors.length > 3) {
43+
color = colors[0];
44+
if (value > breaks[2]) color = colors[3];
45+
else if (value > breaks[1]) color = colors[2];
46+
else if (value > breaks[0]) color = colors[1];
47+
} else {
48+
color = colors[0];
49+
if (value > breaks[1]) color = colors[2];
50+
else if (value > breaks[0]) color = colors[1];
51+
}*/
52+
const radius = getLogDepthRadius3Levels(depth, depthMin, depthMax);
53+
marker.setStyle({ fillColor: color, radius });
54+
});
55+
}
56+
57+
function getColorScale(min, max, chemicalName) {
58+
/* const breaks = [min, min + (max - min) * 0.33, min + (max - min) * 0.66, max];
59+
const colors = ["#1a9850", "#fee08b", "#fc8d59", "#d73027"];*/
60+
// const breaks = [5.700, 9.600];
61+
let breaks = [];
62+
let colors = [];
63+
let levels = [];
64+
console.log('getColorScale',chemicalName,min,max);
65+
if (standards[chosenStandard]?.chemicals?.[chemicalName]) {
66+
if(!standards[chosenStandard].chemicals[chemicalName]?.definition) {
67+
levels = standards[chosenStandard].chemicals[chemicalName];
68+
} else {
69+
levels = standards[chosenStandard].chemicals[chemicalName].levels;
70+
}
71+
console.log('Using standard levels',levels);
72+
breaks = levels;
73+
colors = ["#1a9850", "#fee08b", "#d73027"];
74+
} else {
75+
console.log('Using dynamic levels');
76+
breaks = [min, min + (max - min) * 0.33, min + (max - min) * 0.66, max];
77+
colors = ["#1a9850", "#fee08b", "#fc8d59", "#d73027"];
78+
}
79+
return { breaks, colors };
80+
}
81+
82+
/* ERL: 552,
83+
ERM: 3160
84+
};
85+
const HMW = {
86+
ERL: 1700,
87+
ERM: 9600
88+
*/
89+
2390
function getHeatmapColor(intensity) {
2491
if (intensity <= 0.2) return '#1a9850';
2592
if (intensity <= 0.4) return '#fee08b';
@@ -271,32 +338,6 @@ function computeIndividualStats(statsByChem, unit, values, datasetName, chemical
271338
return statsByChem;
272339
}
273340

274-
function applyDynamicStyling(chemicalName) {
275-
const stats = contaminantStats[chemicalName];
276-
if (!stats) return;
277-
/*if ((chemicalName === 'LMW PAH Sum') || (chemicalName === 'Anthracene')) {
278-
console.log(chemicalName, stats);
279-
}*/
280-
const { valueMin, valueMax, depthMin, depthMax } = stats;
281-
const { breaks, colors } = getColorScale(valueMin*stats.rescale, valueMax*stats.rescale);
282-
contaminantLayers[chemicalName].eachLayer(marker => {
283-
const value = marker.options._chemValue;
284-
const depth = marker.options._depth;
285-
let color = colors[0];
286-
if (value > breaks[2]) color = colors[3];
287-
else if (value > breaks[1]) color = colors[2];
288-
else if (value > breaks[0]) color = colors[1];
289-
const radius = getLogDepthRadius3Levels(depth, depthMin, depthMax);
290-
marker.setStyle({ fillColor: color, radius });
291-
});
292-
}
293-
294-
function getColorScale(min, max) {
295-
const breaks = [min, min + (max - min) * 0.33, min + (max - min) * 0.66, max];
296-
const colors = ["#1a9850", "#fee08b", "#fc8d59", "#d73027"];
297-
return { breaks, colors };
298-
}
299-
300341
const depthSortedSampleIds = Object.keys(sampleDepths).sort((a, b) => {
301342
return sampleDepths[b] - sampleDepths[a];
302343
});
@@ -736,7 +777,8 @@ function createStaticContaminantMap(containerId, contaminantName, visualizationT
736777
const stats = contaminantStats[contaminantName];
737778
const unit = stats.unit ? ` ${stats.unit}` : "";
738779
const min = stats.valueMin*stats.rescale, max = stats.valueMax*stats.rescale;
739-
const colors = ["#1a9850", "#fee08b", "#fc8d59", "#d73027"];
780+
// const colors = ["#1a9850", "#fee08b", "#fc8d59", "#d73027"];
781+
const colors = ["#d73027", "#d73027", "#d73027", "#d73027"];
740782
div.innerHTML = `
741783
<h4>${contaminantName}</h4>
742784
<strong>Value</strong>
@@ -818,46 +860,7 @@ function sampleMap(meas) {
818860
}
819861
// let highlighted = Array(noSamples).fill(false);
820862
const hoverStyle = { radius: 10, weight: 3, opacity: 1, fillOpacity: 1 };
821-
/* const highlightStyle = {
822-
radius: 10, fillColor: '#FFFF00', color: '#000000', weight: 2, opacity: 1, fillOpacity: 1
823-
};*/
824863

825-
/* let depthStatsGlobal = { min: Infinity, max: -Infinity };
826-
let sampleDepths = {};
827-
datesSampled.forEach(dateSampled => {
828-
const dsSamples = Object.keys(selectedSampleInfo[dateSampled].position);
829-
dsSamples.forEach(sample => {
830-
const depthInfo = selectedSampleInfo[dateSampled].position[sample]['Sampling depth (m)'];
831-
if (depthInfo) {
832-
const maxDepth = depthInfo['maxDepth'];
833-
if (!isNaN(maxDepth)) {
834-
const key = `${dateSampled}: ${sample}`;
835-
sampleDepths[key] = maxDepth;
836-
if (maxDepth < depthStatsGlobal.min) depthStatsGlobal.min = maxDepth;
837-
if (maxDepth > depthStatsGlobal.max) depthStatsGlobal.max = maxDepth;
838-
}
839-
}
840-
});
841-
});*/
842-
843-
/* function getDepthRadius(depth, min, max) {
844-
const minRadius = 4, maxRadius = 20;
845-
if (depth == null || isNaN(depth)) return minRadius;
846-
const logMin = Math.log((min ?? 0) + 1);
847-
const logMax = Math.log((max ?? 0) + 1);
848-
const logVal = Math.log(depth + 1);
849-
if (logMax === logMin) return minRadius;
850-
const t = (logVal - logMin) / (logMax - logMin);
851-
return minRadius + t * (maxRadius - minRadius);
852-
}*/
853-
854-
function getColorScale(min, max) {
855-
// returns gradient endpoints & discrete breaks for 4-step color pick
856-
const breaks = [min, min + (max - min) * 0.33, min + (max - min) * 0.66, max];
857-
const colors = ["#1a9850", "#fee08b", "#fc8d59", "#d73027"];
858-
return { breaks, colors };
859-
}
860-
861864
map = L.map('map', {
862865
center: [54.596, -1.177],
863866
zoom: 13,
@@ -903,27 +906,6 @@ let nwCorner = L.latLng(maxLat, maxLon);
903906

904907
console.log("Map created", noLocations, noSamples);
905908

906-
//DUPLICATE from sampleMap
907-
function applyDynamicStyling(chemicalName) {
908-
const stats = contaminantStats[chemicalName];
909-
if (!stats) return;
910-
//if ((chemicalName === 'LMW PAH Sum') || (chemicalName === 'Anthracene')) {
911-
// console.log(chemicalName, stats);
912-
//}
913-
const { valueMin, valueMax, depthMin, depthMax } = stats;
914-
const { breaks, colors } = getColorScale(valueMin * stats.rescale, valueMax * stats.rescale);
915-
contaminantLayers[chemicalName].eachLayer(marker => {
916-
const value = marker.options._chemValue;
917-
const depth = marker.options._depth;
918-
let color = colors[0];
919-
if (value > breaks[2]) color = colors[3];
920-
else if (value > breaks[1]) color = colors[2];
921-
else if (value > breaks[0]) color = colors[1];
922-
const radius = getLogDepthRadius3Levels(depth, depthMin, depthMax);
923-
marker.setStyle({ fillColor: color, radius });
924-
});
925-
}
926-
927909
function toggleVisualizationMode() {
928910
if (!activeContaminant) return;
929911
let currentContaminant = activeContaminant;
@@ -993,7 +975,7 @@ fill="grey" fill-opacity="0.6" />
993975
//console.log(chemicalName,stats.valueMin,stats.valueMax,stats.rescale);
994976
const min = stats.valueMin*stats.rescale, max = stats.valueMax*stats.rescale;
995977
//console.log(chemicalName,min,max,stats.rescale);
996-
const { colors } = getColorScale(min, max);
978+
const { colors } = getColorScale(min, max, chemicalName);
997979
const toggleButton = `<button onclick="window.toggleVisualizationMode()" style="background: #007cba; color: white; border: none;padding: 8px 12px; border-radius: 4px; cursor: pointer; margin-bottom: 10px; width: 100%; font-size: 12px;">Switch to ${isHeatmapMode ? 'Points' : 'Heatmap'}</button>`;
998980
const legendType = isHeatmapMode ? 'Heat Intensity' : 'Point Colours';
999981
const legendContent = isHeatmapMode ? `

sdeSelections.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -733,14 +733,15 @@ function selectSamples() {
733733
.filter(checkbox => checkbox.checked)
734734
.map(checkbox => checkbox.value);
735735
//console.log(selectedSamples);
736-
selectedSampleMeasurements = getselectedSampleMeasurements(selectedSamples);
736+
selectedSampleMeasurements = getSelectedSampleMeasurements(selectedSamples);
737737
selectedSampleInfo = getSelectedSamples(selectedSamples);
738738
console.log(selectedSampleInfo);
739739
updateChart();
740740
}
741741

742742

743-
function getselectedSampleMeasurements(selectedSamples) {
743+
function getSelectedSampleMeasurements(selectedSamples) {
744+
//console.log('getSelectedSampleMeasurements',selectedSamples,selectedSamples.length);
744745
selectedMeas = {};
745746
for (let i=0; i < selectedSamples.length; i++) {
746747
let parts = selectedSamples[i].split(": ");
@@ -759,6 +760,7 @@ function getselectedSampleMeasurements(selectedSamples) {
759760
//console.log('Create ', dateSampled);
760761
selectedMeas[dateSampled][chemicalType] = {};
761762
}
763+
//console.log(dateSampled,sample,chemicalType);
762764
if (chemicalType === 'Physical Data') {
763765
if (!selectedMeas[dateSampled][chemicalType].samples) {
764766
selectedMeas[dateSampled][chemicalType].samples = {};
@@ -771,8 +773,12 @@ function getselectedSampleMeasurements(selectedSamples) {
771773
selectedMeas[dateSampled][chemicalType].samples[sample] = sampleMeasurements[dateSampled][chemicalType].samples[sample];
772774
} else {
773775
// for (const chemicalType in sampleMeasurements[dateSampled]) {
774-
// let newData = selectedMeas[dateSampled][chemicalType];
775776
let newData = {};
777+
if (selectedMeas[dateSampled]?.[chemicalType]) {
778+
newData = selectedMeas[dateSampled][chemicalType];
779+
} else {
780+
newData = {};
781+
}
776782
//console.log(chemicalType, dataset, newData);
777783
for (const key in dataset[chemicalType]) {
778784
let currentData = dataset[chemicalType][key];

0 commit comments

Comments
 (0)