package org.openlca.app.results;
import java.util.ArrayList;
import java.util.List;
import org.openlca.app.util.Labels;
import org.openlca.core.database.EntityCache;
import org.openlca.core.matrix.LongPair;
import org.openlca.core.model.descriptors.BaseDescriptor;
import org.openlca.core.model.descriptors.FlowDescriptor;
import org.openlca.core.model.descriptors.ImpactCategoryDescriptor;
import org.openlca.core.model.descriptors.ProcessDescriptor;
import org.openlca.core.results.UpstreamTree;
import org.openlca.core.results.UpstreamTreeNode;
/**
* The data model of the sunburst-tree view.
*/
public class SunBurstTree {
private static final double EPSILON = 1e-12;
/** The total amount of the tree. */
@SuppressWarnings("unused")
private double amount;
/** The unit of the values in the tree nodes. */
@SuppressWarnings("unused")
private String unit;
/**
* The top-level children of the sun-burst tree. This list usally contains
* only the reference process.
*/
private List<Node> children = new ArrayList<>();
public static SunBurstTree create(UpstreamTree contributionTree,
EntityCache cache) {
SunBurstTree tree = new SunBurstTree();
UpstreamTreeNode cRoot = contributionTree.getRoot();
tree.amount = cRoot.getAmount();
tree.unit = getUnit(contributionTree, cache);
Node root = createNode(cRoot, cache);
synchChilds(cRoot, root, cache);
if (root != null)
tree.children.add(root);
return tree;
}
private static String getUnit(UpstreamTree tree, EntityCache cache) {
if (tree == null || tree.getReference() == null)
return "";
BaseDescriptor ref = tree.getReference();
if (ref instanceof ImpactCategoryDescriptor)
return ((ImpactCategoryDescriptor) ref).getReferenceUnit();
if (ref instanceof FlowDescriptor)
return Labels.getRefUnit((FlowDescriptor) ref, cache);
else
return "";
}
private static Node createNode(UpstreamTreeNode cNode, EntityCache cache) {
if (cNode == null)
return null;
LongPair product = cNode.getProcessProduct();
if (product == null)
return null;
Node node = new Node();
node.setAmount(cNode.getAmount());
node.setProcessId(product.getFirst());
ProcessDescriptor descriptor = cache.get(ProcessDescriptor.class,
product.getFirst());
if (descriptor != null)
node.setProcessName(Labels.getDisplayName(descriptor));
return node;
}
private static void synchChilds(UpstreamTreeNode cNode, Node node,
EntityCache cache) {
if (cNode == null || node == null)
return;
for (UpstreamTreeNode cChild : cNode.getChildren()) {
if (Math.abs(cChild.getAmount()) < EPSILON)
continue;
Node child = createNode(cChild, cache);
if (child == null)
return;
node.getChildren().add(child);
synchChilds(cChild, child, cache);
}
}
public static class Node {
private long processId;
private String processName;
private double amount;
private List<Node> children = new ArrayList<>();
public long getProcessId() {
return processId;
}
public void setProcessId(long processId) {
this.processId = processId;
}
public String getProcessName() {
return processName;
}
public void setProcessName(String processName) {
this.processName = processName;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public List<Node> getChildren() {
return children;
}
}
}