@Override
public List<AjtColumnInfo<MulticastDemand>> getNonBasicUserDefinedColumnsVisibleOrNot()
{
final List<AjtColumnInfo<MulticastDemand>> res = new LinkedList<> ();
res.add(new AjtColumnInfo<MulticastDemand>(this , Node.class, null , "A", "Ingress node", null , d->d.getIngressNode() , AGTYPE.NOAGGREGATION , null));
res.add(new AjtColumnInfo<MulticastDemand>(this , String.class, null , "Bs", "Egress nodes", null , d->d.getEgressNodes().stream().map(n->n.getName().equals("")? "Node " + n.getIndex() : n.getName()).collect(Collectors.joining(",")) , AGTYPE.NOAGGREGATION , null));
res.add(new AjtColumnInfo<MulticastDemand>(this , Collection.class, null , "Coupled links", "The links that this demand is coupled to, if any", null , d->d.isCoupled()? d.getCoupledLinks() : "-" , AGTYPE.NOAGGREGATION , null));
res.add(new AjtColumnInfo<MulticastDemand>(this , Double.class, null , "Offered traffic (" + getTableNetworkLayer().getLinkCapacityUnits() + ")", "Offered traffic by the demand", (d,val)->d.setOfferedTraffic((Double) val), d->d.getOfferedTraffic() , AGTYPE.SUMDOUBLE , null));
res.add(new AjtColumnInfo<MulticastDemand>(this , Double.class, null , "Carried traffic (" + getTableNetworkLayer().getLinkCapacityUnits() + ")", "Carried traffic by the demand", null , d->d.getCarriedTraffic() , AGTYPE.SUMDOUBLE , null));
res.add(new AjtColumnInfo<MulticastDemand>(this , Double.class, null , "% Lost traffic", "Percentage of the lost traffic by the demand", null, d->d.getOfferedTraffic() == 0? 0 : d.getBlockedTraffic() / d.getOfferedTraffic() , AGTYPE.NOAGGREGATION , d->d.getBlockedTraffic() > 0? Color.RED : Color.GREEN));
res.add(new AjtColumnInfo<MulticastDemand>(this , String.class, null , "QoS type", "A used-defined string identifying the type of traffic of the demand", (d,val)-> d.setQoSType((String)val) , d->d.getQosType(), AGTYPE.NOAGGREGATION , null));
res.add(new AjtColumnInfo<MulticastDemand>(this , Boolean.class, null , "All nodes reached?", "True if all the multicast trees of the demand reach all the demand egress nodes", null, d->d.isAllTreesReachingAllEgressNodes() , AGTYPE.COUNTTRUE , d->d.isAllTreesReachingAllEgressNodes()? Color.GREEN : Color.RED));
res.add(new AjtColumnInfo<MulticastDemand>(this , String.class, null , "Bifurcated?", "Indicates whether the demand is satisfied by more than one multicast tree", null, d->d.isBifurcated() , AGTYPE.COUNTTRUE , null));
res.add(new AjtColumnInfo<MulticastDemand>(this , Integer.class, null , "# trees", "Number of associated multicast trees", null, d->d.getMulticastTrees().size() , AGTYPE.SUMINT , null));
res.add(new AjtColumnInfo<MulticastDemand>(this , Double.class, null , "Worst e2e lat (ms)", "Current worst case end-to-end propagation time in miliseconds (accumulating any lower layer propagation times if any), from the origin node, to destination nodes reached", null, d->d.getWorseCasePropagationTimeInMs() , AGTYPE.NOAGGREGATION , d->{ final double maxMs = d.getMaximumAcceptableE2EWorstCaseLatencyInMs(); return maxMs <= 0? null : (d.getWorseCasePropagationTimeInMs() > maxMs? Color.RED : null); }));
res.add(new AjtColumnInfo<MulticastDemand>(this , Double.class, null , "Worst e2e length (km)", "Current worst case end-to-end propagation length in km (accumulating any lower layer propagation lengths if any)", null, d->d.getWorstCaseLengthInKm() , AGTYPE.NOAGGREGATION , null));
res.add(new AjtColumnInfo<MulticastDemand>(this , Double.class, null , "Limit e2e lat (ms)", "Maximum end-to-end propagation time in miliseconds (accumulating any lower layer propagation times if any)", (d,val)-> d.setMaximumAcceptableE2EWorstCaseLatencyInMs((Double)val) , d->d.getMaximumAcceptableE2EWorstCaseLatencyInMs() , AGTYPE.NOAGGREGATION , null));
res.add(new AjtColumnInfo<MulticastDemand>(this , Double.class, null , "CAGR(%)" , "Compound annual growth factor for this demand", (d,val)->d.setOfferedTrafficPerPeriodGrowthFactor((Double) val), d->d.getOfferedTrafficPerPeriodGrowthFactor() , AGTYPE.NOAGGREGATION , null));
res.add(new AjtColumnInfo<MulticastDemand>(this , Integer.class, null , "#Monit points" , "Number of samples of the offered traffic stored, coming from a monitoring or forecasting traffic process", null , d->d.getMonitoredOrForecastedOfferedTraffic().getSize() , AGTYPE.NOAGGREGATION , null));
return res;
}