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

improved influence condition renderer

parent 4c34c86d
No related branches found
No related tags found
No related merge requests found
// src/renderers/InfluenceConditionsRenderer.js // src/renderers/InfluenceConditionsRenderer.js
import { DSIUnit } from "dsiunits-js";
export class InfluenceConditionsRenderer { export class InfluenceConditionsRenderer {
constructor(influenceConditionsData, language) { constructor(influenceConditionsData, language) {
this.data = influenceConditionsData; this.data = influenceConditionsData;
...@@ -17,40 +19,44 @@ export class InfluenceConditionsRenderer { ...@@ -17,40 +19,44 @@ export class InfluenceConditionsRenderer {
conditions = [conditions]; conditions = [conditions];
} }
conditions.forEach(condition => { conditions.forEach(condition => {
// Create collapsible section for each influence condition
const details = document.createElement('details'); const details = document.createElement('details');
details.style.border = '1px solid #ccc'; details.style.border = '1px solid #ccc';
details.style.padding = '8px'; details.style.padding = '8px';
details.style.marginBottom = '10px'; details.style.marginBottom = '10px';
// Summary: influence condition name (language-specific) // Summary always shows condition name and (if only one quantity) its value/unit
const summary = document.createElement('summary'); const summary = document.createElement('summary');
summary.textContent = this._getText(condition['dcc:name'], this.language); const condName = this._getText(condition['dcc:name']);
let summaryText = condName;
const quantities = this._getQuantities(condition);
if (quantities.length === 1) {
// If only one quantity, append its value and unit
const qty = quantities[0];
const valueStr = this._formatQuantity(qty);
summaryText += `: ${valueStr}`;
}
summary.textContent = summaryText;
details.appendChild(summary); details.appendChild(summary);
// Expanded content: description and quantities table // Expanded content: description and quantities table
const contentDiv = document.createElement('div'); const contentDiv = document.createElement('div');
contentDiv.style.marginTop = '8px'; contentDiv.style.marginTop = '8px';
contentDiv.style.fontFamily = 'sans-serif'; contentDiv.style.fontFamily = 'sans-serif';
const descText = this._getText(condition['dcc:description'], this.language); const descText = this._getText(condition['dcc:description']);
if (descText) { if (descText) {
const p = document.createElement('p'); const p = document.createElement('p');
p.textContent = descText; p.textContent = descText;
contentDiv.appendChild(p); contentDiv.appendChild(p);
} }
// Render quantities table (if any)
// If data exists, render quantities table
if (condition['dcc:data'] && condition['dcc:data']['dcc:quantity']) { 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'); const table = document.createElement('table');
table.style.width = '100%'; table.style.width = '100%';
table.style.borderCollapse = 'collapse'; table.style.borderCollapse = 'collapse';
// Header row
// Create header row with columns: Quantity, Value, Description, Additional Info
const headerRow = document.createElement('tr'); const headerRow = document.createElement('tr');
['Quantity', 'Value', 'Description', 'Additional Info'].forEach(text => { ['Quantity', 'Value', 'Description'].forEach(text => {
const th = document.createElement('th'); const th = document.createElement('th');
th.textContent = text; th.textContent = text;
th.style.border = '1px solid #ccc'; th.style.border = '1px solid #ccc';
...@@ -58,46 +64,39 @@ export class InfluenceConditionsRenderer { ...@@ -58,46 +64,39 @@ export class InfluenceConditionsRenderer {
headerRow.appendChild(th); headerRow.appendChild(th);
}); });
table.appendChild(headerRow); table.appendChild(headerRow);
// Data rows for each quantity
// Render each quantity in its own row. this._getQuantities(condition).forEach(q => {
quantities.forEach(q => {
const row = document.createElement('tr'); const row = document.createElement('tr');
// Quantity name cell
// Column 1: Quantity name
const nameCell = document.createElement('td'); const nameCell = document.createElement('td');
nameCell.style.border = '1px solid #ccc'; nameCell.style.border = '1px solid #ccc';
nameCell.style.padding = '4px'; nameCell.style.padding = '4px';
nameCell.textContent = this._getText(q['dcc:name'], this.language); nameCell.textContent = this._getText(q['dcc:name']);
row.appendChild(nameCell); row.appendChild(nameCell);
// Value cell with merged unit and uncertainty, plus tooltip for additional info
// Column 2: Value merged with uncertainty and unit
const valueCell = document.createElement('td'); const valueCell = document.createElement('td');
valueCell.style.border = '1px solid #ccc'; valueCell.style.border = '1px solid #ccc';
valueCell.style.padding = '4px'; valueCell.style.padding = '4px';
valueCell.innerHTML = this._formatQuantity(q); const formattedValue = this._formatQuantity(q);
valueCell.innerHTML = formattedValue;
// If there is additional (non-standard) data, add a tooltip
const additional = this._getAdditionalData(q);
if (Object.keys(additional).length > 0) {
const infoSpan = document.createElement('span');
infoSpan.textContent = '';
infoSpan.style.cursor = 'pointer';
infoSpan.style.color = '#888';
// Use the title attribute for a basic tooltip (or later replace with a dynamic tree)
infoSpan.title = JSON.stringify(additional, null, 2);
valueCell.appendChild(infoSpan);
}
row.appendChild(valueCell); row.appendChild(valueCell);
// Description cell
// Column 3: Description (if available)
const descCell = document.createElement('td'); const descCell = document.createElement('td');
descCell.style.border = '1px solid #ccc'; descCell.style.border = '1px solid #ccc';
descCell.style.padding = '4px'; descCell.style.padding = '4px';
descCell.textContent = this._getText(q['dcc:description'], this.language); descCell.textContent = this._getText(q['dcc:description']);
row.appendChild(descCell); 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); table.appendChild(row);
}); });
contentDiv.appendChild(table); contentDiv.appendChild(table);
...@@ -108,65 +107,118 @@ export class InfluenceConditionsRenderer { ...@@ -108,65 +107,118 @@ export class InfluenceConditionsRenderer {
return container; return container;
} }
_getText(node, language) { // Helper: return language-specific text from a node
_getText(node) {
if (!node) return ''; if (!node) return '';
const content = node['dcc:content']; const content = node['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 === this.language) || content[0];
return match._ || match; return match._ || match;
} }
return content._ || content; return content._ || content;
} }
// Helper: extract quantities array from an influence condition
_getQuantities(condition) {
let quantities = [];
if (condition['dcc:data'] && condition['dcc:data']['dcc:quantity']) {
quantities = Array.isArray(condition['dcc:data']['dcc:quantity'])
? condition['dcc:data']['dcc:quantity']
: [condition['dcc:data']['dcc:quantity']];
}
return quantities;
}
// Helper: format a quantity’s value (supporting si:hybrid, si:realListXMLList, si:real, and dcc:noQuantity)
_formatQuantity(quantity) { _formatQuantity(quantity) {
let result = ''; // Handle noQuantity (categorical data)
if (quantity['dcc:noQuantity']) {
return this._getText(quantity['dcc:noQuantity']);
}
// Handle si:hybrid: if there are two si:real elements, render first normally and second in light gray.
if (quantity['si:hybrid']) { if (quantity['si:hybrid']) {
const hybrid = quantity['si:hybrid']; const hybrid = quantity['si:hybrid'];
let reals = hybrid['si:real']; let reals = hybrid['si:real'];
if (!Array.isArray(reals)) { if (!Array.isArray(reals)) {
reals = [reals]; reals = [reals];
} }
const formatted = reals.map(real => { const formatted = reals.map((real, index) => {
const value = real['si:value'] ? real['si:value'].trim() : ''; const value = real['si:value'] ? real['si:value'].trim() : '';
const unit = real['si:unit'] ? real['si:unit'].trim() : ''; let unit = '';
if (real['si:unit']) {
const rawUnit = real['si:unit'].trim();
const unitObj = new DSIUnit(rawUnit);
unit = unitObj.toHTML({ oneLine: true });
}
let uncertainty = ''; let uncertainty = '';
if (real['si:measurementUncertaintyUnivariate'] && if (real['si:measurementUncertaintyUnivariate'] &&
real['si:measurementUncertaintyUnivariate']['si:expandedMU']) { real['si:measurementUncertaintyUnivariate']['si:expandedMU'] &&
uncertainty = real['si:measurementUncertaintyUnivariate']['si:expandedMU']['si:valueExpandedMU'] real['si:measurementUncertaintyUnivariate']['si:expandedMU']['si:valueExpandedMU']) {
? real['si:measurementUncertaintyUnivariate']['si:expandedMU']['si:valueExpandedMU'].trim() uncertainty = real['si:measurementUncertaintyUnivariate']['si:expandedMU']['si:valueExpandedMU'].trim();
: '';
} }
return uncertainty ? `${value} ± ${uncertainty} ${unit}` : `${value} ${unit}`; let result = uncertainty
? `${value} ± ${uncertainty} ${unit}`
: `${value} ${unit}`;
if (index > 0) {
// For subsequent representations, wrap in a light gray span.
result = `<span style="color:lightgray;">${result}</span>`;
}
return result;
}); });
result = formatted.join(' / '); return formatted.join(' / ');
} else if (quantity['si:realListXMLList']) { }
const realList = quantity['si:realListXMLList']; // Handle si:realListXMLList
const values = realList['si:valueXMLList'] ? realList['si:valueXMLList'].trim().split(/\s+/) : []; if (quantity['si:realListXMLList']) {
const unit = realList['si:unitXMLList'] ? realList['si:unitXMLList'].trim() : ''; const rl = quantity['si:realListXMLList'];
const values = rl['si:valueXMLList'] ? rl['si:valueXMLList'].trim().split(/\s+/) : [];
let unit = '';
if (rl['si:unitXMLList']) {
const rawUnit = rl['si:unitXMLList'].trim();
const unitObj = new DSIUnit(rawUnit);
unit = unitObj.toHTML({ oneLine: true });
}
let uncertainty = []; let uncertainty = [];
if (realList['si:measurementUncertaintyUnivariateXMLList'] && if (rl['si:measurementUncertaintyUnivariateXMLList'] &&
realList['si:measurementUncertaintyUnivariateXMLList']['si:expandedMUXMLList']) { rl['si:measurementUncertaintyUnivariateXMLList']['si:expandedMUXMLList'] &&
uncertainty = realList['si:measurementUncertaintyUnivariateXMLList']['si:expandedMUXMLList']['si:valueExpandedMUXMLList'] rl['si:measurementUncertaintyUnivariateXMLList']['si:expandedMUXMLList']['si:valueExpandedMUXMLList']) {
? realList['si:measurementUncertaintyUnivariateXMLList']['si:expandedMUXMLList']['si:valueExpandedMUXMLList'].trim().split(/\s+/) uncertainty = rl['si:measurementUncertaintyUnivariateXMLList']['si:expandedMUXMLList']['si:valueExpandedMUXMLList'].trim().split(/\s+/);
: [];
} }
const formatted = values.map((val, i) => { const formatted = values.map((val, i) => {
const unc = (uncertainty[i] !== undefined) ? uncertainty[i] : ''; const unc = (uncertainty[i] !== undefined) ? uncertainty[i] : '';
return unc ? `${val} ± ${unc} ${unit}` : `${val} ${unit}`; return unc ? `${val} ± ${unc} ${unit}` : `${val} ${unit}`;
}); });
result = formatted.join(' / '); return formatted.join(' / ');
} else if (quantity['si:real']) { }
// Handle si:real
if (quantity['si:real']) {
const real = quantity['si:real']; const real = quantity['si:real'];
const value = real['si:value'] ? real['si:value'].trim() : ''; const value = real['si:value'] ? real['si:value'].trim() : '';
const unit = real['si:unit'] ? real['si:unit'].trim() : ''; let unit = '';
if (real['si:unit']) {
const rawUnit = real['si:unit'].trim();
const unitObj = new DSIUnit(rawUnit);
unit = unitObj.toHTML({ oneLine: true });
}
let uncertainty = ''; let uncertainty = '';
if (real['si:measurementUncertaintyUnivariate'] && if (real['si:measurementUncertaintyUnivariate'] &&
real['si:measurementUncertaintyUnivariate']['si:expandedMU'] && real['si:measurementUncertaintyUnivariate']['si:expandedMU'] &&
real['si:measurementUncertaintyUnivariate']['si:expandedMU']['si:valueExpandedMU']) { real['si:measurementUncertaintyUnivariate']['si:expandedMU']['si:valueExpandedMU']) {
uncertainty = real['si:measurementUncertaintyUnivariate']['si:expandedMU']['si:valueExpandedMU'].trim(); uncertainty = real['si:measurementUncertaintyUnivariate']['si:expandedMU']['si:valueExpandedMU'].trim();
} }
result = uncertainty ? `${value} ± ${uncertainty} ${unit}` : `${value} ${unit}`; return uncertainty ? `${value} ± ${uncertainty} ${unit}` : `${value} ${unit}`;
} }
return result; return '';
}
// Helper: extract additional data (all keys except the common ones)
_getAdditionalData(quantity) {
const exclude = ['dcc:name', 'dcc:description', 'si:real', 'si:realListXMLList', 'dcc:noQuantity'];
const additional = {};
Object.keys(quantity).forEach(key => {
if (!exclude.includes(key)) {
additional[key] = quantity[key];
}
});
return additional;
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment