/*
* Copyright (c) 2011-2015 Marat Gubaidullin.
*
* This file is part of HYBRIDBPM.
*
* 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.hybridbpm.ui.component.chart.manager;
import com.vaadin.addon.charts.model.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@SuppressWarnings("serial")
public class XYSeriesManager {
protected static class PointsGroup {
private DataSeries column;
private List<DataSeriesItem> items;
public PointsGroup(DataSeries column, List<DataSeriesItem> items) {
this.column = column;
this.items = items;
}
public DataSeries getColumn() {
return column;
}
public List<DataSeriesItem> getItems() {
return items;
}
}
private Configuration configuration;
private boolean redrawNeeded;
private Set<String> updatedItems;
private List<PointsGroup> unrenderedData;
public XYSeriesManager(Configuration configuration) {
this.configuration = configuration;
beginUpdate();
}
public void beginUpdate() {
redrawNeeded = false;
updatedItems = new HashSet<String>();
unrenderedData = new ArrayList<PointsGroup>();
}
public void addPoint(Number[] values, String pointsGroupName, AbstractPlotOptions plotOptions) {
PointsGroup pointsGroup = findPointsGroup(pointsGroupName);
if (pointsGroup != null) {
// group exists, check the values
if (pointsGroup.getItems().size() == values.length) {
// update the series options
updateOptions(plotOptions, pointsGroup);
// update the series values
for (int i = 0; i < values.length; i++) {
DataSeriesItem point = pointsGroup.getItems().get(i);
point.setY(values[i]);
}
} else {
// the number of values has changed
// create a new data series instead of adding/removing values
pointsGroup = createPointsGroup(values, pointsGroupName, plotOptions);
}
} else {
// create a new one
pointsGroup = createPointsGroup(values, pointsGroupName, plotOptions);
}
unrenderedData.add(pointsGroup);
// remember updated items
updatedItems.add(pointsGroupName);
}
public void renderPoints() {
checkStaleDate();
if (redrawNeeded) {
redrawSeries();
} else {
updateSeries();
}
}
private void checkStaleDate() {
if (!redrawNeeded) {
for (Series point : configuration.getSeries()) {
if (!updatedItems.contains(point.getName())) {
redrawNeeded = true;
return;
}
}
}
}
private void redrawSeries() {
// remove all the old items
for (Series pointsGroup : configuration.getSeries()) {
DataSeries pointGroupsImpl = (DataSeries)pointsGroup;
for (DataSeriesItem point : new ArrayList<DataSeriesItem>(pointGroupsImpl.getData())) {
pointGroupsImpl.remove(point);
}
}
// add the new series
List<Series> newSeries = new ArrayList<Series>();
for (PointsGroup pointsGroup : unrenderedData) {
newSeries.add(pointsGroup.getColumn());
}
configuration.setSeries(newSeries);
// add values to them
for (PointsGroup pointsGroup : unrenderedData) {
for (DataSeriesItem point : pointsGroup.getItems()) {
pointsGroup.getColumn().add(point);
}
}
}
/**
* Updates items values on the client side.
*/
private void updateSeries() {
for (PointsGroup pointsGroup : unrenderedData) {
for (DataSeriesItem point : pointsGroup.getItems()) {
pointsGroup.getColumn().update(point);
}
}
}
private PointsGroup createPointsGroup(Number[] values, String pointName, AbstractPlotOptions plotOptions) {
PointsGroup pointsGroup = new PointsGroup(new DataSeries(pointName), convertValues(values));
updateOptions(plotOptions, pointsGroup);
// just drop and redraw the whole chart
redrawNeeded = true;
return pointsGroup;
}
private void updateOptions(AbstractPlotOptions plotOptions, PointsGroup pointsGroup) {
if (plotOptions != null) {
pointsGroup.getColumn().setPlotOptions(plotOptions);
}
}
private List<DataSeriesItem> convertValues(Number[] values) {
List<DataSeriesItem> valuesList = new ArrayList<DataSeriesItem>();
for (int i = 0; i < values.length; i++) {
valuesList.add(new DataSeriesItem(i, values[i]));
}
return valuesList;
}
private PointsGroup findPointsGroup(String columnName) {
for (Series seriesPoint : configuration.getSeries()) {
if (seriesPoint.getName().equals(columnName)) {
DataSeries seriesPointImpl = (DataSeries) seriesPoint;
return new PointsGroup(seriesPointImpl, seriesPointImpl.getData());
}
}
return null;
}
protected Configuration getConfiguration() {
return configuration;
}
}