Skip to content
Snippets Groups Projects
Commit 2a40bdf9 authored by Benedikt's avatar Benedikt
Browse files

added used methodes :)

parent 5d41d1b6
No related branches found
No related tags found
No related merge requests found
import Plotly from 'plotly.js-dist'; import Plotly from 'plotly.js-dist';
import { DCCRealListQuantity, DCCConformity } from '../dccQuantity.js'; import { DCCRealListQuantity, DCCConformity } from '../dccQuantity.js';
import JSONEditor from 'jsoneditor';
import 'jsoneditor/dist/jsoneditor.css';
const palette = [ const palette = [
'#1f77b4', '#1f77b4',
...@@ -36,15 +38,17 @@ const conformityColors = { ...@@ -36,15 +38,17 @@ const conformityColors = {
nofail: '#9e9e9e' nofail: '#9e9e9e'
}; };
// Render all measurement results in a tabbed layout
export function renderMeasurementResults(measurementResults, language) { export function renderMeasurementResults(measurementResults, language) {
console.debug('renderMeasurementResults called with:', measurementResults); console.debug('renderMeasurementResults called with:', measurementResults);
const container = document.getElementById('measurementResults'); const container = document.getElementById('measurementResults');
container.innerHTML = ''; container.innerHTML = '';
if (!measurementResults) { // Create tab headers and content container
console.error('No measurementResults provided.'); const tabHeader = document.createElement('ul');
return; tabHeader.className = 'tab-header';
} const tabContent = document.createElement('div');
tabContent.className = 'tab-content';
let results = measurementResults['dcc:measurementResult']; let results = measurementResults['dcc:measurementResult'];
if (!results) { if (!results) {
...@@ -52,26 +56,131 @@ export function renderMeasurementResults(measurementResults, language) { ...@@ -52,26 +56,131 @@ export function renderMeasurementResults(measurementResults, language) {
return; return;
} }
if (!Array.isArray(results)) { results = [results]; } if (!Array.isArray(results)) { results = [results]; }
const measurementResult = results[0];
let resultObj = measurementResult['dcc:results'] && measurementResult['dcc:results']['dcc:result']; results.forEach((result, index) => {
if (!resultObj) { // Determine tab title from dcc:name
console.error("Missing 'dcc:results' or 'dcc:result' in measurementResult:", measurementResult); let resultName = 'Measurement Result ' + (index + 1);
return; if (result['dcc:name'] && result['dcc:name']['dcc:content']) {
let content = result['dcc:name']['dcc:content'];
if (Array.isArray(content)) {
const match = content.find(item => item.$ && item.$.lang === language) || content[0];
resultName = match._ || match;
} else {
resultName = content._ || content;
}
}
// Create tab header item
const tabItem = document.createElement('li');
tabItem.textContent = resultName;
if (index === 0) tabItem.classList.add('active');
// Create tab panel for this measurement result
const tabPanel = document.createElement('div');
tabPanel.className = 'tab-panel';
tabPanel.style.display = (index === 0) ? 'block' : 'none';
tabItem.addEventListener('click', () => {
document.querySelectorAll('.tab-header li').forEach(li => li.classList.remove('active'));
document.querySelectorAll('.tab-content > div').forEach(div => div.style.display = 'none');
tabItem.classList.add('active');
tabPanel.style.display = 'block';
// Force a resize event for Plotly to recalc dimensions
window.dispatchEvent(new Event('resize'));
});
tabHeader.appendChild(tabItem);
// Extract the single dcc:result from this measurement result and render it
let resultObj = result['dcc:results'] && result['dcc:results']['dcc:result'];
if (!resultObj) {
console.error("Missing 'dcc:results' or 'dcc:result' in measurementResult:", result);
} else {
let singleResult = Array.isArray(resultObj) ? resultObj[0] : resultObj;
renderSingleMeasurementResult(singleResult, language, tabPanel);
}
// Add expandable section for Used Methods using JSONEditor
const methodsDetails = document.createElement('details');
methodsDetails.open = false;
const methodsSummary = document.createElement('summary');
methodsSummary.textContent = 'Used Methods';
methodsDetails.appendChild(methodsSummary);
methodsDetails.appendChild(renderUsedMethods(result, language));
tabPanel.appendChild(methodsDetails);
// Add expandable section for Influence Conditions using JSONEditor
const influenceDetails = document.createElement('details');
influenceDetails.open = false;
const influenceSummary = document.createElement('summary');
influenceSummary.textContent = 'Influence Conditions';
influenceDetails.appendChild(influenceSummary);
influenceDetails.appendChild(renderInfluenceConditions(result, language));
tabPanel.appendChild(influenceDetails);
tabContent.appendChild(tabPanel);
});
container.appendChild(tabHeader);
container.appendChild(tabContent);
}
// Helper to render used methods as JSON tree via JSONEditor
function renderUsedMethods(measurementResult, language) {
const container = document.createElement('div');
container.style.maxHeight = '200px';
container.style.overflowY = 'auto';
const options = {
mode: 'view',
mainMenuBar: false,
navigationBar: false,
statusBar: false
};
const editor = new JSONEditor(container, options);
if (measurementResult['dcc:usedMethods']) {
editor.set(measurementResult['dcc:usedMethods']);
} else {
container.textContent = 'No used methods data available.';
}
return container;
}
// Helper to render influence conditions as JSON tree via JSONEditor
function renderInfluenceConditions(measurementResult, language) {
const container = document.createElement('div');
container.style.maxHeight = '200px';
container.style.overflowY = 'auto';
const options = {
mode: 'view',
mainMenuBar: false,
navigationBar: false,
statusBar: false
};
const editor = new JSONEditor(container, options);
if (measurementResult['dcc:influenceConditions']) {
editor.set(measurementResult['dcc:influenceConditions']);
} else {
container.textContent = 'No influence conditions data available.';
} }
if (Array.isArray(resultObj)) { resultObj = resultObj[0]; } return container;
}
// Helper to render a single measurement result (charts, tables, etc.)
export function renderSingleMeasurementResult(resultObj, language, tabPanel) {
console.debug('renderSingleMeasurementResult called with:', resultObj);
tabPanel.innerHTML = '';
let resultName = 'Measurement Result'; let resultName = 'Measurement Result';
if (measurementResult['dcc:name'] && measurementResult['dcc:name']['dcc:content']) { if (resultObj['dcc:name'] && resultObj['dcc:name']['dcc:content']) {
let content = measurementResult['dcc:name']['dcc:content']; let content = resultObj['dcc:name']['dcc:content'];
if (Array.isArray(content)) { if (Array.isArray(content)) {
const match = content.find(item => item.$ && item.$.lang === language) || content[0]; const match = content.find(item => item.$ && item.$.lang === language) || content[0];
resultName = match._ || match; resultName = match._ || match;
} else { resultName = content._ || content; } } else {
resultName = content._ || content;
}
} }
const tabTitle = document.createElement('h2'); const header = document.createElement('h2');
tabTitle.textContent = resultName; header.textContent = resultName;
container.appendChild(tabTitle); tabPanel.appendChild(header);
if (!resultObj['dcc:data'] || !resultObj['dcc:data']['dcc:list']) { if (!resultObj['dcc:data'] || !resultObj['dcc:data']['dcc:list']) {
console.error("Missing 'dcc:data' or 'dcc:list' in result object:", resultObj); console.error("Missing 'dcc:data' or 'dcc:list' in result object:", resultObj);
...@@ -99,7 +208,6 @@ export function renderMeasurementResults(measurementResults, language) { ...@@ -99,7 +208,6 @@ export function renderMeasurementResults(measurementResults, language) {
const indexQuantities = []; const indexQuantities = [];
const dataQuantities = []; const dataQuantities = [];
// extraInfo now stores { uncertainty, conformity } for each data quantity.
const extraInfo = []; const extraInfo = [];
quantityJSONs.forEach(q => { quantityJSONs.forEach(q => {
if (q.$ && q.$.refType && q.$.refType.match(/basic_tableIndex/)) { if (q.$ && q.$.refType && q.$.refType.match(/basic_tableIndex/)) {
...@@ -122,15 +230,15 @@ export function renderMeasurementResults(measurementResults, language) { ...@@ -122,15 +230,15 @@ export function renderMeasurementResults(measurementResults, language) {
}); });
const dataHeaders = dataQuantities.map((q, idx) => { const dataHeaders = dataQuantities.map((q, idx) => {
let header = q.getName(language); let headerText = q.getName(language);
let unit = q.getUnit(); let unit = q.getUnit();
if (!header.toLowerCase().includes(" in ")) { if (!headerText.toLowerCase().includes(" in ")) {
header = header + " in " + unit; headerText = headerText + " in " + unit;
} }
return header; return headerText;
}); });
// Create scaling toggles for log axes. // Create scaling toggles and X-axis selector controls
const scalingContainer = document.createElement('div'); const scalingContainer = document.createElement('div');
scalingContainer.innerHTML = '<strong>Scaling:</strong> '; scalingContainer.innerHTML = '<strong>Scaling:</strong> ';
const logXToggle = document.createElement('input'); const logXToggle = document.createElement('input');
...@@ -149,7 +257,7 @@ export function renderMeasurementResults(measurementResults, language) { ...@@ -149,7 +257,7 @@ export function renderMeasurementResults(measurementResults, language) {
logYLabel.textContent = 'Log Y'; logYLabel.textContent = 'Log Y';
scalingContainer.appendChild(logYToggle); scalingContainer.appendChild(logYToggle);
scalingContainer.appendChild(logYLabel); scalingContainer.appendChild(logYLabel);
container.appendChild(scalingContainer); tabPanel.appendChild(scalingContainer);
const xAxisContainer = document.createElement('div'); const xAxisContainer = document.createElement('div');
xAxisContainer.innerHTML = '<strong>Select X-Axis:</strong> '; xAxisContainer.innerHTML = '<strong>Select X-Axis:</strong> ';
...@@ -166,7 +274,7 @@ export function renderMeasurementResults(measurementResults, language) { ...@@ -166,7 +274,7 @@ export function renderMeasurementResults(measurementResults, language) {
xAxisContainer.appendChild(radio); xAxisContainer.appendChild(radio);
xAxisContainer.appendChild(label); xAxisContainer.appendChild(label);
}); });
container.appendChild(xAxisContainer); tabPanel.appendChild(xAxisContainer);
const toleranceToggle = document.createElement('input'); const toleranceToggle = document.createElement('input');
toleranceToggle.type = 'checkbox'; toleranceToggle.type = 'checkbox';
...@@ -177,17 +285,18 @@ export function renderMeasurementResults(measurementResults, language) { ...@@ -177,17 +285,18 @@ export function renderMeasurementResults(measurementResults, language) {
const tolContainer = document.createElement('div'); const tolContainer = document.createElement('div');
tolContainer.appendChild(toleranceToggle); tolContainer.appendChild(toleranceToggle);
tolContainer.appendChild(tolLabel); tolContainer.appendChild(tolLabel);
container.appendChild(tolContainer); tabPanel.appendChild(tolContainer);
// Create containers for plots and table.
const subplotsContainer = document.createElement('div'); const subplotsContainer = document.createElement('div');
subplotsContainer.id = 'subplotsContainer'; subplotsContainer.id = 'subplotsContainer';
container.appendChild(subplotsContainer); tabPanel.appendChild(subplotsContainer);
const tableContainer = document.createElement('div'); const tableContainer = document.createElement('div');
tableContainer.id = 'tableContainer'; tableContainer.id = 'tableContainer';
container.appendChild(tableContainer); tabPanel.appendChild(tableContainer);
function updateVisualization() { function updateVisualization() {
const selectedRadio = document.querySelector('input[name="xAxisSelect"]:checked'); const selectedRadio = tabPanel.querySelector('input[name="xAxisSelect"]:checked');
if (!selectedRadio) { console.error('No X-Axis selection found.'); return; } if (!selectedRadio) { console.error('No X-Axis selection found.'); return; }
const selectedIndex = selectedRadio.value; const selectedIndex = selectedRadio.value;
const xQuantity = indexQuantities[selectedIndex]; const xQuantity = indexQuantities[selectedIndex];
...@@ -228,7 +337,7 @@ export function renderMeasurementResults(measurementResults, language) { ...@@ -228,7 +337,7 @@ export function renderMeasurementResults(measurementResults, language) {
row.push(extraInfo.map(info => info.comment || '').filter(c => c).join(' ; ')); row.push(extraInfo.map(info => info.comment || '').filter(c => c).join(' ; '));
tableData.push(row); tableData.push(row);
} }
renderTable(tableData); renderTable(tableData, computeConformityMapping());
const unitGroups = {}; const unitGroups = {};
dataQuantities.forEach((q, idx) => { dataQuantities.forEach((q, idx) => {
...@@ -258,9 +367,7 @@ export function renderMeasurementResults(measurementResults, language) { ...@@ -258,9 +367,7 @@ export function renderMeasurementResults(measurementResults, language) {
graphDiv.style.height = '300px'; graphDiv.style.height = '300px';
subplotsContainer.appendChild(graphDiv); subplotsContainer.appendChild(graphDiv);
plotDivs.push(graphDiv); plotDivs.push(graphDiv);
const groupTraces = group.map(trace => {
// Build main traces for this unit group.
let groupTraces = group.map(trace => {
let tooltip = 'X: %{x} ' + xUnit + ' | ' + trace.name + ': %{y}'; let tooltip = 'X: %{x} ' + xUnit + ' | ' + trace.name + ': %{y}';
if (trace.conformity && trace.conformity.length > 0) { if (trace.conformity && trace.conformity.length > 0) {
tooltip += ' | Conformity: %{customdata}'; tooltip += ' | Conformity: %{customdata}';
...@@ -289,9 +396,8 @@ export function renderMeasurementResults(measurementResults, language) { ...@@ -289,9 +396,8 @@ export function renderMeasurementResults(measurementResults, language) {
}; };
}); });
// If tolerance markings are enabled and conformity data exists, add tolerance traces.
const toleranceTraces = []; const toleranceTraces = [];
if (document.getElementById('toleranceToggle').checked) { if (tabPanel.querySelector('#toleranceToggle').checked) {
group.forEach(trace => { group.forEach(trace => {
const confObj = extraInfo[trace.index].conformity; const confObj = extraInfo[trace.index].conformity;
if (confObj) { if (confObj) {
...@@ -322,7 +428,6 @@ export function renderMeasurementResults(measurementResults, language) { ...@@ -322,7 +428,6 @@ export function renderMeasurementResults(measurementResults, language) {
} }
}); });
} }
// Combine main traces with tolerance traces.
const allTraces = groupTraces.concat(toleranceTraces); const allTraces = groupTraces.concat(toleranceTraces);
let xaxisTitle = ''; let xaxisTitle = '';
...@@ -330,8 +435,8 @@ export function renderMeasurementResults(measurementResults, language) { ...@@ -330,8 +435,8 @@ export function renderMeasurementResults(measurementResults, language) {
let xLabel = 'X: ' + xQuantity.getName(language); let xLabel = 'X: ' + xQuantity.getName(language);
xaxisTitle = '<b>' + xLabel + ' in ' + xUnit + '</b>'; xaxisTitle = '<b>' + xLabel + ' in ' + xUnit + '</b>';
} }
const logX = document.getElementById('logXToggle').checked; const logX = tabPanel.querySelector('#logXToggle').checked;
const logY = document.getElementById('logYToggle').checked; const logY = tabPanel.querySelector('#logYToggle').checked;
const layout = { const layout = {
xaxis: { xaxis: {
title: { text: xaxisTitle, font: { size: 36, family: 'Arial', color: 'black' } }, title: { text: xaxisTitle, font: { size: 36, family: 'Arial', color: 'black' } },
...@@ -343,7 +448,6 @@ export function renderMeasurementResults(measurementResults, language) { ...@@ -343,7 +448,6 @@ export function renderMeasurementResults(measurementResults, language) {
tickfont: { family: 'Arial', size: 14, color: 'black' }, tickfont: { family: 'Arial', size: 14, color: 'black' },
type: logY ? 'log' : 'linear' type: logY ? 'log' : 'linear'
}, },
// Place legend on top over the plot without shifting x-axis scaling.
legend: { legend: {
orientation: 'h', orientation: 'h',
x: 0.5, x: 0.5,
...@@ -355,6 +459,8 @@ export function renderMeasurementResults(measurementResults, language) { ...@@ -355,6 +459,8 @@ export function renderMeasurementResults(measurementResults, language) {
margin: { t: 20, b: 40 } margin: { t: 20, b: 40 }
}; };
Plotly.newPlot(graphDiv, allTraces, layout).then(() => { Plotly.newPlot(graphDiv, allTraces, layout).then(() => {
// Force a resize after a short delay to ensure full width
setTimeout(() => { Plotly.Plots.resize(graphDiv); }, 100);
const caption = document.createElement('div'); const caption = document.createElement('div');
caption.innerHTML = '<b>' + group[0].name + '</b>'; caption.innerHTML = '<b>' + group[0].name + '</b>';
caption.style.textAlign = 'center'; caption.style.textAlign = 'center';
...@@ -380,8 +486,8 @@ export function renderMeasurementResults(measurementResults, language) { ...@@ -380,8 +486,8 @@ export function renderMeasurementResults(measurementResults, language) {
}); });
} }
function renderTable(tableData) { function renderTable(tableData, conformityMapping) {
const tableContainer = document.getElementById('tableContainer'); const tableContainer = tabPanel.querySelector('#tableContainer');
tableContainer.innerHTML = ''; tableContainer.innerHTML = '';
const table = document.createElement('table'); const table = document.createElement('table');
tableData.forEach((rowData, rowIndex) => { tableData.forEach((rowData, rowIndex) => {
...@@ -390,17 +496,13 @@ export function renderMeasurementResults(measurementResults, language) { ...@@ -390,17 +496,13 @@ export function renderMeasurementResults(measurementResults, language) {
const cell = document.createElement(rowIndex === 0 ? 'th' : 'td'); const cell = document.createElement(rowIndex === 0 ? 'th' : 'td');
if (rowIndex === 0) { if (rowIndex === 0) {
cell.innerHTML = cellData; cell.innerHTML = cellData;
if (cellData !== 'Comments' && cellIndex > 0) { if (cellData !== 'Comments' && cellIndex > 0 && conformityMapping[cellIndex] !== undefined) {
const qtyIndex = Math.floor((cellIndex - 1) / 2); cell.style.backgroundColor = conformityMapping[cellIndex];
cell.style.backgroundColor = lightPalette[qtyIndex % lightPalette.length];
} }
} else { } else {
cell.textContent = cellData; cell.textContent = cellData;
if (tableData[0][cellIndex] && tableData[0][cellIndex].toLowerCase().includes('conformity')) { if (tableData[0][cellIndex] && tableData[0][cellIndex].toLowerCase().includes('conformity') && conformityMapping[cellIndex] !== undefined) {
const confVal = cellData.toLowerCase(); cell.style.backgroundColor = conformityMapping[cellIndex];
if (confVal in conformityColors) {
cell.style.backgroundColor = conformityColors[confVal];
}
} }
} }
cell.style.padding = '4px'; cell.style.padding = '4px';
...@@ -414,20 +516,36 @@ export function renderMeasurementResults(measurementResults, language) { ...@@ -414,20 +516,36 @@ export function renderMeasurementResults(measurementResults, language) {
tableContainer.appendChild(table); tableContainer.appendChild(table);
} }
function computeConformityMapping() {
let mapping = {};
let col = 1; // Column 0 is X-Axis.
for (let i = 0; i < dataHeaders.length; i++) {
col++; // value column.
if (extraInfo[i] && extraInfo[i].conformity) {
mapping[col] = palette[i % palette.length];
col++;
}
}
return mapping;
}
function highlightTableRow(rowIndex) { function highlightTableRow(rowIndex) {
const rows = document.getElementById('tableContainer').querySelectorAll('tr'); const rows = tabPanel.querySelector('#tableContainer').querySelectorAll('tr');
if (rows[rowIndex]) { rows[rowIndex].style.backgroundColor = '#fee'; } if (rows[rowIndex]) { rows[rowIndex].style.backgroundColor = '#fee'; }
} }
function clearTableRowHighlights() { function clearTableRowHighlights() {
const rows = document.getElementById('tableContainer').querySelectorAll('tr'); const rows = tabPanel.querySelector('#tableContainer').querySelectorAll('tr');
rows.forEach(row => row.style.backgroundColor = ''); rows.forEach(row => row.style.backgroundColor = '');
} }
updateVisualization(); updateVisualization();
const radios = document.querySelectorAll('input[name="xAxisSelect"]'); const radios = tabPanel.querySelectorAll('input[name="xAxisSelect"]');
radios.forEach(radio => { radio.addEventListener('change', updateVisualization); }); radios.forEach(radio => { radio.addEventListener('change', updateVisualization); });
document.getElementById('logXToggle').addEventListener('change', updateVisualization); tabPanel.querySelector('#logXToggle').addEventListener('change', updateVisualization);
document.getElementById('logYToggle').addEventListener('change', updateVisualization); tabPanel.querySelector('#logYToggle').addEventListener('change', updateVisualization);
toleranceToggle.addEventListener('change', () => { console.log('Tolerance toggle:', toleranceToggle.checked); updateVisualization(); }); tabPanel.querySelector('#toleranceToggle').addEventListener('change', () => {
console.log('Tolerance toggle:', tabPanel.querySelector('#toleranceToggle').checked);
updateVisualization();
});
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment