forked from enviPath/enviPy
[Feature] Timeseries Pathway view (#319)
**Warning depends on Timeseries feature to be merged** Implements a way to display OECD 301F data on the pathway view. This is mostly a PoC and needs to be improved once the pathway rendering is updated.  Co-authored-by: jebus <lorsbach@envipath.com> Co-authored-by: Tim Lorsbach <tim@lorsba.ch> Reviewed-on: enviPath/enviPy#319 Co-authored-by: Tobias O <tobias.olenyi@envipath.com> Co-committed-by: Tobias O <tobias.olenyi@envipath.com>
This commit is contained in:
@ -361,6 +361,83 @@ function draw(pathway, elem) {
|
||||
|
||||
function node_popup(n) {
|
||||
popupContent = "";
|
||||
|
||||
if (timeseriesViewEnabled && n.timeseries && n.timeseries.measurements) {
|
||||
for (var s of n.scenarios) {
|
||||
popupContent += "<a href='" + s.url + "'>" + s.name + "</a><br>";
|
||||
}
|
||||
|
||||
popupContent += '<div style="width:100%;height:120px"><canvas id="ts-popover-canvas"></canvas></div>';
|
||||
const tsMeasurements = n.timeseries.measurements;
|
||||
setTimeout(() => {
|
||||
const canvas = document.getElementById('ts-popover-canvas');
|
||||
if (canvas && window.Chart) {
|
||||
const valid = tsMeasurements
|
||||
.filter(m => m.timestamp != null && m.value != null)
|
||||
.map(m => ({ ...m, timestamp: typeof m.timestamp === 'number' ? m.timestamp : new Date(m.timestamp).getTime() }))
|
||||
.sort((a, b) => a.timestamp - b.timestamp);
|
||||
|
||||
const datasets = [];
|
||||
|
||||
// Error band (lower + upper with fill between)
|
||||
const withErrors = valid.filter(m => m.error != null && m.error > 0);
|
||||
if (withErrors.length > 0) {
|
||||
datasets.push({
|
||||
data: withErrors.map(m => ({ x: m.timestamp, y: m.value - m.error })),
|
||||
borderColor: 'rgba(59,130,246,0.3)',
|
||||
backgroundColor: 'rgba(59,130,246,0.15)',
|
||||
pointRadius: 0,
|
||||
fill: false,
|
||||
tension: 0.1,
|
||||
});
|
||||
datasets.push({
|
||||
data: withErrors.map(m => ({ x: m.timestamp, y: m.value + m.error })),
|
||||
borderColor: 'rgba(59,130,246,0.3)',
|
||||
backgroundColor: 'rgba(59,130,246,0.15)',
|
||||
pointRadius: 0,
|
||||
fill: '-1',
|
||||
tension: 0.1,
|
||||
});
|
||||
}
|
||||
|
||||
// Main value line
|
||||
datasets.push({
|
||||
data: valid.map(m => ({ x: m.timestamp, y: m.value })),
|
||||
borderColor: 'rgb(59,130,246)',
|
||||
pointRadius: 0,
|
||||
tension: 0.1,
|
||||
fill: false,
|
||||
});
|
||||
|
||||
new Chart(canvas.getContext('2d'), {
|
||||
type: 'line',
|
||||
data: { datasets },
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: { display: false },
|
||||
tooltip: { enabled: false },
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
type: 'linear',
|
||||
ticks: { font: { size: 10 } },
|
||||
title: { display: false },
|
||||
},
|
||||
y: {
|
||||
ticks: { font: { size: 10 } },
|
||||
title: { display: false },
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}, 0);
|
||||
|
||||
return popupContent;
|
||||
}
|
||||
|
||||
if (n.stereo_removed) {
|
||||
popupContent += "<span class='alert alert-warning alert-soft'>Removed stereochemistry for prediction</span>";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user