/*
* Copyright 2014 TWO SIGMA OPEN SOURCE, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.twosigma.beaker.chart.xychart.plotitem;
import java.util.*;
public class XYStacker {
public static List<BasedXYGraphics> stack(List<BasedXYGraphics> graphicsList) {
return transformGraphicsList(graphicsList);
}
private static List<BasedXYGraphics> transformGraphicsList(List<BasedXYGraphics> graphicsList) {
if (graphicsList.isEmpty() || graphicsList.size() == 1){
return graphicsList;
} else {
BasedXYGraphics graphicsWithMaxElements = Collections.max(graphicsList, new Comparator<BasedXYGraphics>() {
@Override
public int compare(BasedXYGraphics o1, BasedXYGraphics o2) {
return o1.getY().size() - o2.getY().size();
}
});
List<BasedXYGraphics> stackedList = new ArrayList<BasedXYGraphics>(graphicsList.size());
padYs(graphicsList.get(0), graphicsWithMaxElements);
stackedList.add(graphicsList.get(0));
for (int gIndex = 1; gIndex < graphicsList.size(); gIndex++) {
BasedXYGraphics current = graphicsList.get(gIndex);
padYs(current, graphicsWithMaxElements);
BasedXYGraphics previous = graphicsList.get(gIndex - 1);
List<Number> currentYs = current.getY();
List<Number> previousYs = previous.getY();
for (int yIndex = 0; yIndex < currentYs.size(); yIndex++) {
currentYs.set(yIndex, currentYs.get(yIndex).doubleValue() + previousYs.get(yIndex).doubleValue());
}
current.setBase(previousYs);
stackedList.add(current);
}
return stackedList;
}
}
private static void padYs(BasedXYGraphics graphics, BasedXYGraphics graphicsWithMaxElements) {
int maxSize = graphicsWithMaxElements.getY().size();
int currentSize = graphics.getY().size();
int diff = maxSize - currentSize;
if (diff > 0) {
Number[] ys = new Number[diff];
Arrays.fill(ys, graphics.getY().get(currentSize - 1));
graphics.getY().addAll(Arrays.asList(ys));
List<Number> xs = graphics.getX();
if (xs != null && xs.size() != maxSize) {
if (graphicsWithMaxElements.getX() != null) {
xs.addAll(graphicsWithMaxElements.getX().subList(currentSize, maxSize));
} else {
Number lastX = xs.get(currentSize - 1);
for (int i = 0; i < diff; ++i) {
xs.add(lastX.doubleValue() + i);
}
}
}
}
}
}