Re: Implementing a pivot table / cross table
Re: Implementing a pivot table / cross table
- Subject: Re: Implementing a pivot table / cross table
- From: Jean-François Veillette <email@hidden>
- Date: Fri, 17 Mar 2006 12:48:44 -0500
Le 06-03-17, à 11:45, Rico Landefeld a écrit :
In your case, I do not know you model enough to indicate if a
key-path can be found from 'Failure' that will be used to segment it
from one bucket from the other. I guess 'Failure' to
'FailureAttribute' is a to-many relationship. If you want to segment
'Failures' based on some sort of elements inside that relationship,
either add a method in 'Failure'
no, there are to-one relationships to the four "failure attribute"
entities. i can't use keypaths because the entities "origin",
"outcome", "occurence" and "cause" are hierarchical (recursive to-n
relations, 4 levels). a possible questions is "how many failures
occured with outcome site->splices->wu-splices->leaky and origin
extern->subcontractors->companyxy".
In this situation, the 2 dimensions would be :
1- "site.splices.wu-splices"
2- "extern.subcontractors"
you would get a matrix based on those 2 dimensions. You then ask the
coordinate for {"site.splices.wu-splices":"leaky",
"extern.subcontractors":"companyxy"} and you would get the population
for that bucket. From there you just get the 'count'.
the "->" marks the level to sublevel step.
I'm not sure I understand your model.
Are you talking about class hierarchies (class superclass kind of
things) or object graph (object-A --toOne--> objectB --toOne--> objectC
).
i need only one or two dimensional crosstables. but the dimensions
should be free configurable (which failure attribute and level). the
problem is that for an "origin" subcontractor at level 2, i have to
count the failures which are directly linked with subcontractor and
all failures which are linked with elements in the subcontractor
subtree.
Whatever it is. You need to define the dimension / segmentation path.
From what I understand, it seem that it's hard to define the dimension
due to the deept of the object graph and the fact that requests are
add-hoc from end-users.
thank you four your class. but its hard to read for me, i don't speak
any french ;-). but i hope i'll figure out the basic ideas.
Here is a quick/dirty translation (not tested): package org.champlain.tamia;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Enumeration;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSMutableArray;
import com.webobjects.foundation.NSKeyValueCodingAdditions;
/**
* The <code>Grouper</code> class take care of grouping a population of objects based on one or multiples attributes.
*
* @version $Revision$, $Date$
* <br>© 2005 Jean-Franois Veillette.
*/
public class Grouper {
static GroupDelegate basisDelegate = new GroupDefaultDelegate();
public Grouper() {
super();
}
/** Utility method to get groups based on one key. */
public HashMap groupPopulationOnKeyPath(NSArray a, String kp, GroupDelegate delegue) {
return groupObjectFromPopulationKeyPath(a, new String[]{kp}, delegue);
}
/** Utility method to get groups based on multiple keys. */
public HashMap groupObjectFromPopulationKeyPath(NSArray a, String[] clefs, Delegue delegue) {
HashSet clefSet = (HashSet)new HashSet(java.util.Arrays.asList(clefs));
return groupPopulation(a, clefs, delegue);
}
/** Method to regroup based on 'n' keys. ('n' dimension matrix) */
public HashMap groupPopulation(NSArray population, String[] keys, GroupDelegate delegue) {
if(delegue == null) {
delegue = delegueDeBase;
}
HashMap synthese = new HashMap();
Enumeration enu = population.objectEnumerator();
while(enu.hasMoreElements()) {
NSKeyValueCodingAdditions item = (NSKeyValueCodingAdditions)enu.nextElement();
// gnre la cl d'identification de la cellule
HashSet clefSet = new HashSet();
NSMutableArray l = new NSMutableArray();
for(int i = 0 ; i < clefs.length ; i++ ) {
String cl = clefs[i];
Object model = delegue.groupValueForKey(item, cl);
KeyValue cv = new KeyValue(cl, model);
l.addObject(cv);
// ajoute a la liste des clefs possible par groupements
HashSet listeParGroupe = (HashSet)synthese.get(cl);
if(listeParGroupe == null) {
listeParGroupe = new HashSet();
synthese.put(cl, listeParGroupe);
}
listeParGroupe.add(cv);
}
addToBuckets(synthese, l, item);
}
return synthese;
}
/** Ajoute l'objet 'obj' dans tout les 'bucket' cr par chacune des combinaisons de clef possible dans 'attributs' */
void addToBuckets(HashMap synthese, NSArray attributs, Object obj) {
// pour chacune des combinaisons de clef, on prend le 'bucket' et on ajoute sa population
Enumeration attEnum = attributs.objectEnumerator();
NSMutableArray clefGenere = new NSMutableArray();
while(attEnum.hasMoreElements()) {
// on gnre les combinaisons
KeyValue cv = (KeyValue)attEnum.nextElement();
Enumeration clefEnum = clefGenere.objectEnumerator();
while(clefEnum.hasMoreElements()) {
HashSet clefs = (HashSet)clefEnum.nextElement();
HashSet nc = (HashSet)clefs.clone();
nc.add(cv);
addToBucket(synthese, nc, obj);
}
HashSet b = new HashSet();
b.add(cv);
addToBucket(synthese, b, obj);
clefGenere.addObject(b);
}
}
/** Ajoute l'objet 'obj' dans la liste associ au 'bucket'. */
void addToBucket(HashMap synthese, HashSet bucket, Object obj) {
NSMutableArray b = (NSMutableArray)synthese.get(bucket);
if(b == null) {
b = new NSMutableArray();
synthese.put(bucket, b);
}
b.addObject(obj);
}
/** Object used to represent a key element on the group result set. */
public static class KeyValue {
public String clef;
public Object valeur;
public KeyValue(String c, Object v) {
super();
clef = c;
valeur = v;
}
public int hashCode() {
int vh = valeur == null ? 0 : valeur.hashCode();
int ch = clef == null ? 0 : clef.hashCode();
return ch + vh;
}
public boolean equals(Object b) {
if (b instanceof KeyValue) {
KeyValue bb = (KeyValue)b;
return ((clef == null) || (bb == null) || (valeur == null) ) || clef.equals(bb.clef) && valeur.equals(bb.valeur);
}
return false;
}
public String toString() {
return "<KeyValue clef="+clef+" valeur="+valeur+" hashCode="+hashCode()+" />";
}
}
/** A delegate can be used to get different group values from a fiven key. The default implementation just use NSKeyValueCoding protocol. For example, to customize values returnes from an object to group together some values (age group like [0-6], [7-13], [14-18], [29-35], ...), the delegate could return the corresponding group value (let's say a string like "[7-13]") when asked for a given key. */
static public interface GroupDelegate {
public Object groupValueForKey(Object objet, String clef);
}
static public class GroupDefaultDelegate implements Delegue {
public Object groupValueForKey(Object objet, String clef) {
return NSKeyValueCodingAdditions.DefaultImplementation.valueForKeyPath(objet, clef);
}
}
}
- jfv
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden