Introduction
Assume there are two pivottables with different pivotmodel, the two pivotmodels have the same structure but different value.
This article describe how to synchronize the open status from one pivot model to another, i.e., when open or close the node of one pivottable, the corresponding node in another pivottable will also be opened or closed.
Pre-request
Display Data in Pivottable
http://ben-bai.blogspot.tw/2012/07/zk-pivottable-display-data-in-zk.html
The Program
index.zul
Contains two pivottable, the first one use a custom pivottable that post onPivotNodeOpen event to itself, the open status of second pivottable will follow the first pivottable.
<zk>
<!-- Tested with ZK 6.0.2 EE and ZK Pivottable 2.0.0 -->
<!-- window, apply a SelectorComposer -->
<window id="win"
apply="test.TestComposer">
<vlayout>
<!-- pivottable, get model from window's composer -->
<pivottable id="pivottable" model="${win$composer.pivotModel}" use="test.ListenOpenPivottable" />
<pivottable id="pivottableTwo" model="${win$composer.pivotModelTwo}" />
</vlayout>
</window>
</zk>
TestComposer.java
Synchronize the open status from first pivot model to second pivot model when the node in first pivottable is opened/closed.
package test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.zkoss.pivot.Calculator;
import org.zkoss.pivot.PivotField;
import org.zkoss.pivot.PivotHeaderNode;
import org.zkoss.pivot.Pivottable;
import org.zkoss.pivot.impl.StandardCalculator;
import org.zkoss.pivot.impl.TabularPivotModel;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.select.annotation.Wire;
/**
* Tested with ZK 6.0.2 EE and ZK Pivottable 2.0.0
*
*/
@SuppressWarnings("rawtypes")
public class TestComposer extends SelectorComposer {
/**
* generated serial version UID
*/
private static final long serialVersionUID = -2897873399288955635L;
@Wire
private Pivottable pivottableTwo;
private TabularPivotModel _pivotModel;
private TabularPivotModel _pivotModelTwo;
public TabularPivotModel getPivotModel () throws Exception {
if (_pivotModel == null) {
_pivotModel = getPivotModel(getData(), getColumns());
}
return _pivotModel;
}
public TabularPivotModel getPivotModelTwo () throws Exception {
if (_pivotModelTwo == null) {
_pivotModelTwo = getPivotModel(getData(), getColumns());
}
return _pivotModelTwo;
}
public TabularPivotModel getPivotModel (List<List<Object>> data, List<String> columns) throws Exception {
TabularPivotModel pivotModel = new TabularPivotModel(data, columns);
// assign rows, the order matches to the level of row node field
pivotModel.setFieldType("RowOne", PivotField.Type.ROW);
pivotModel.setFieldType("RowTwo", PivotField.Type.ROW);
pivotModel.setFieldType("RowThree", PivotField.Type.ROW);
// assign columns, the order matches to the level of column node field
pivotModel.setFieldType("ColumnOne", PivotField.Type.COLUMN);
pivotModel.setFieldType("ColumnTwo", PivotField.Type.COLUMN);
// assign datas, the order matches to the order of data field
pivotModel.setFieldType("DataOne", PivotField.Type.DATA);
PivotField field = pivotModel.getField("RowOne");
pivotModel.setFieldSubtotals(field, new Calculator[] {StandardCalculator.SUM, StandardCalculator.MAX});
return pivotModel;
}
/**
* prepare the data for pivottable's model
* The order of object put into data list should match
* the order of column name's
* @return
* @throws Exception
*/
public List<List<Object>> getData() throws Exception {
List<List<Object>> result = new ArrayList<List<Object>>();
Random r = new Random();
for (int i = 0; i < 100; i++) {
List<Object> data = new ArrayList<Object>();
data.add("RowOne - " + (r.nextInt(2) + 1));
data.add("RowTwo - " + (r.nextInt(2) + 1));
data.add("RowThree - " + (r.nextInt(2) + 1));
data.add("ColumnOne - " + (r.nextInt(2) + 1));
data.add("ColumnTwo - " + (r.nextInt(2) + 1));
data.add(r.nextInt(10));
result.add(data);
}
return result;
}
/**
* prepare columns name for pivottable's model
* @return
*/
public List<String> getColumns() {
return Arrays.asList(new String[]{
"RowOne", "RowTwo", "RowThree",
"ColumnOne", "ColumnTwo",
"DataOne"
});
}
@Listen ("onPivotNodeOpen = #pivottable")
public void syncOpenStatus () {
syncOpenStatus(_pivotModel.getRowHeaderTree().getRoot(), _pivotModelTwo.getRowHeaderTree().getRoot(), false);
syncOpenStatus(_pivotModel.getColumnHeaderTree().getRoot(), _pivotModelTwo.getColumnHeaderTree().getRoot(), false);
// reset model
pivottableTwo.setModel(null);
pivottableTwo.setModel(_pivotModelTwo);
}
/**
* Synchronize the open status of two pivot header trees
*
* @param root the root of the base pivot header tree (or its sub trees)
* @param rootTwo the root of the pivot header tree to sync (or its sub trees)
* @param checkAll whether sync whole tree, <br>
* true: sync whole tree, put every node of base pivot header tree into open list to sync<br>
* false: sync only current view, only put the displayed node into open list to sync
*/
private void syncOpenStatus (PivotHeaderNode root, PivotHeaderNode rootTwo, boolean checkAll) {
Map<Object, PivotHeaderNode> originalOpenMap = new HashMap<Object, PivotHeaderNode>();
// sync displayed node only if not checkAll
// so do not need to scan whole header tree
for (PivotHeaderNode node : root.getChildren()) {
// checkAll: sync each node
// !checkAll: sync displayed node
if (checkAll
|| (node.getDepth() == 1 || node.getParent().isOpen())) {
originalOpenMap.put(node.getKey(), node);
}
}
// for each node in children of rootTwo
for (PivotHeaderNode newNode : rootTwo.getChildren()) {
PivotHeaderNode node = originalOpenMap.get(newNode.getKey());
if (node != null) {
newNode.setOpen(node.isOpen());
// recursively sync sub trees
syncOpenStatus(node, newNode, checkAll);
}
}
}
}
ListenOpenPivottable.java
Custom pivottable, will post onPivotNodeOpen event back.
package test;
import org.zkoss.pivot.Pivottable;
import org.zkoss.zk.au.AuRequest;
import org.zkoss.zk.ui.event.Events;
/**
* Tested with ZK 6.0.2 and Pivottable 2.0.0
*
*/
public class ListenOpenPivottable extends Pivottable {
private static final long serialVersionUID = 4770700380255057252L;
public void service(AuRequest request, boolean everError) {
String cmd = request.getCommand();
super.service(request, everError);
// post onPivotNodeOpen event
if ("onPivotNodeOpen".equals(cmd)) {
Events.postEvent("onPivotNodeOpen", this, request.getData());
}
}
}
The Result
View demo on line
http://screencast.com/t/HuW2n4kixiXG
Reference
The start point of a bunch of APIs
http://www.zkoss.org/javadoc/latest/zkpvt/org/zkoss/pivot/impl/TabularPivotModel.html
Download
Full project at github
https://github.com/benbai123/ZK_Practice/tree/master/Components/projects/Addon_Practice/PivottableTest/SyncPivotmodelStatus
No comments:
Post a Comment