diff --git a/src/renderers/InfluenceConditionsRenderer.js b/src/renderers/InfluenceConditionsRenderer.js new file mode 100644 index 0000000000000000000000000000000000000000..b26f7e55b505a3065a19684da4be40ff09ddbfca --- /dev/null +++ b/src/renderers/InfluenceConditionsRenderer.js @@ -0,0 +1,172 @@ +// src/renderers/InfluenceConditionsRenderer.js +export class InfluenceConditionsRenderer { + constructor(influenceConditionsData, language) { + this.data = influenceConditionsData; + this.language = language; + } + + render() { + const container = document.createElement('div'); + container.innerHTML = `<h3>Influence Conditions</h3>`; + let conditions = this.data['dcc:influenceCondition']; + if (!conditions) { + container.textContent = 'No influence conditions available.'; + return container; + } + if (!Array.isArray(conditions)) { + conditions = [conditions]; + } + conditions.forEach(condition => { + const details = document.createElement('details'); + details.style.border = '1px solid #ccc'; + details.style.padding = '8px'; + details.style.marginBottom = '10px'; + + // Summary: influence condition name (language-specific) + const summary = document.createElement('summary'); + summary.textContent = this._getText(condition['dcc:name'], this.language); + details.appendChild(summary); + + // Expanded content: description and quantities table + const contentDiv = document.createElement('div'); + contentDiv.style.marginTop = '8px'; + contentDiv.style.fontFamily = 'sans-serif'; + const descText = this._getText(condition['dcc:description'], this.language); + if (descText) { + const p = document.createElement('p'); + p.textContent = descText; + contentDiv.appendChild(p); + } + + // If data exists, render quantities table + if (condition['dcc:data'] && condition['dcc:data']['dcc:quantity']) { + let quantities = condition['dcc:data']['dcc:quantity']; + if (!Array.isArray(quantities)) { + quantities = [quantities]; + } + const table = document.createElement('table'); + table.style.width = '100%'; + table.style.borderCollapse = 'collapse'; + + // Create header row with columns: Quantity, Value, Description, Additional Info + const headerRow = document.createElement('tr'); + ['Quantity', 'Value', 'Description', 'Additional Info'].forEach(text => { + const th = document.createElement('th'); + th.textContent = text; + th.style.border = '1px solid #ccc'; + th.style.padding = '4px'; + headerRow.appendChild(th); + }); + table.appendChild(headerRow); + + // Render each quantity in its own row. + quantities.forEach(q => { + const row = document.createElement('tr'); + + // Column 1: Quantity name + const nameCell = document.createElement('td'); + nameCell.style.border = '1px solid #ccc'; + nameCell.style.padding = '4px'; + nameCell.textContent = this._getText(q['dcc:name'], this.language); + row.appendChild(nameCell); + + // Column 2: Value merged with uncertainty and unit + const valueCell = document.createElement('td'); + valueCell.style.border = '1px solid #ccc'; + valueCell.style.padding = '4px'; + valueCell.innerHTML = this._formatQuantity(q); + row.appendChild(valueCell); + + // Column 3: Description (if available) + const descCell = document.createElement('td'); + descCell.style.border = '1px solid #ccc'; + descCell.style.padding = '4px'; + descCell.textContent = this._getText(q['dcc:description'], this.language); + row.appendChild(descCell); + + // Column 4: Additional info (render any other keys as JSON string) + const additionalCell = document.createElement('td'); + additionalCell.style.border = '1px solid #ccc'; + additionalCell.style.padding = '4px'; + // Remove known keys from q and show the rest + const additional = {}; + Object.keys(q).forEach(key => { + if (!['dcc:name', 'dcc:description', 'si:real', 'si:realListXMLList'].includes(key)) { + additional[key] = q[key]; + } + }); + additionalCell.textContent = Object.keys(additional).length > 0 ? JSON.stringify(additional) : ''; + row.appendChild(additionalCell); + + table.appendChild(row); + }); + contentDiv.appendChild(table); + } + details.appendChild(contentDiv); + container.appendChild(details); + }); + return container; + } + + _getText(node, language) { + if (!node) return ''; + const content = node['dcc:content']; + if (Array.isArray(content)) { + const match = content.find(item => item.$ && item.$.lang === language) || content[0]; + return match._ || match; + } + return content._ || content; + } + + _formatQuantity(quantity) { + let result = ''; + if (quantity['si:hybrid']) { + const hybrid = quantity['si:hybrid']; + let reals = hybrid['si:real']; + if (!Array.isArray(reals)) { + reals = [reals]; + } + const formatted = reals.map(real => { + const value = real['si:value'] ? real['si:value'].trim() : ''; + const unit = real['si:unit'] ? real['si:unit'].trim() : ''; + let uncertainty = ''; + if (real['si:measurementUncertaintyUnivariate'] && + real['si:measurementUncertaintyUnivariate']['si:expandedMU']) { + uncertainty = real['si:measurementUncertaintyUnivariate']['si:expandedMU']['si:valueExpandedMU'] + ? real['si:measurementUncertaintyUnivariate']['si:expandedMU']['si:valueExpandedMU'].trim() + : ''; + } + return uncertainty ? `${value} ± ${uncertainty} ${unit}` : `${value} ${unit}`; + }); + result = formatted.join(' / '); + } else if (quantity['si:realListXMLList']) { + const realList = quantity['si:realListXMLList']; + const values = realList['si:valueXMLList'] ? realList['si:valueXMLList'].trim().split(/\s+/) : []; + const unit = realList['si:unitXMLList'] ? realList['si:unitXMLList'].trim() : ''; + let uncertainty = []; + if (realList['si:measurementUncertaintyUnivariateXMLList'] && + realList['si:measurementUncertaintyUnivariateXMLList']['si:expandedMUXMLList']) { + uncertainty = realList['si:measurementUncertaintyUnivariateXMLList']['si:expandedMUXMLList']['si:valueExpandedMUXMLList'] + ? realList['si:measurementUncertaintyUnivariateXMLList']['si:expandedMUXMLList']['si:valueExpandedMUXMLList'].trim().split(/\s+/) + : []; + } + const formatted = values.map((val, i) => { + const unc = (uncertainty[i] !== undefined) ? uncertainty[i] : ''; + return unc ? `${val} ± ${unc} ${unit}` : `${val} ${unit}`; + }); + result = formatted.join(' / '); + } else if (quantity['si:real']) { + const real = quantity['si:real']; + const value = real['si:value'] ? real['si:value'].trim() : ''; + const unit = real['si:unit'] ? real['si:unit'].trim() : ''; + let uncertainty = ''; + if (real['si:measurementUncertaintyUnivariate'] && + real['si:measurementUncertaintyUnivariate']['si:expandedMU'] && + real['si:measurementUncertaintyUnivariate']['si:expandedMU']['si:valueExpandedMU']) { + uncertainty = real['si:measurementUncertaintyUnivariate']['si:expandedMU']['si:valueExpandedMU'].trim(); + } + result = uncertainty ? `${value} ± ${uncertainty} ${unit}` : `${value} ${unit}`; + } + return result; + } +} diff --git a/src/renderers/MeasurementRenderer.js b/src/renderers/MeasurementRenderer.js index d8b271c7e135256aa7812c8913989498e718e795..4d518d9873f4509571c2cf2af4a75e2c282fdb88 100644 --- a/src/renderers/MeasurementRenderer.js +++ b/src/renderers/MeasurementRenderer.js @@ -3,6 +3,7 @@ import { DCCRealListQuantity, DCCConformity } from '../dccQuantity.js'; import JSONEditor from 'jsoneditor'; import 'jsoneditor/dist/jsoneditor.css'; import { UsedMethodsRenderer } from './UsedMethodsRenderer.js'; +import { InfluenceConditionsRenderer } from './InfluenceConditionsRenderer.js'; const palette = [ '#1f77b4', @@ -104,15 +105,14 @@ export function renderMeasurementResults(measurementResults, language) { usedMethodsContainer.appendChild(usedMethodsRenderer.render()); tabPanel.appendChild(usedMethodsContainer); - // Add expandable section for Influence Conditions using JSONEditor - const influenceDetails = document.createElement('details'); + // Render Influence Conditions using the new renderer (collapsible by default) + const influenceRenderer = new InfluenceConditionsRenderer(result['dcc:influenceConditions'], language); + const influenceDetails = document.createElement('div'); influenceDetails.open = false; const influenceSummary = document.createElement('summary'); - influenceSummary.textContent = 'Influence Conditions'; influenceDetails.appendChild(influenceSummary); - influenceDetails.appendChild(renderInfluenceConditions(result, language)); + influenceDetails.appendChild(influenceRenderer.render()); tabPanel.appendChild(influenceDetails); - tabContent.appendChild(tabPanel); });