[JAVA] Créer des fonctions avancées pour Yellowfin

Objectif

En plus des fonctions fournies à l'origine dans Yellowfin (outil BI), il existe des «fonctions avancées» que vous pouvez créer et étendre vous-même. Je ne l'ai jamais utilisé auparavant, et je n'y ai pas touché car je dois écrire un programme, mais il y avait une demande pour trouver la moyenne géométrique, et j'ai écrit un article sur la façon dont je l'ai fait. Personnellement, honnêtement, c'était difficile à comprendre simplement en utilisant le [Wiki] officiel (https://wiki.yellowfin.co.jp/pages/viewpage.action?pageId=2294172), alors suivez cela. J'espère que je peux le faire.

introduction

La manière de base de démarrer le développement est d'utiliser Eclipse, mais Bases des fonctions avancées Si vous la définissez tout en la regardant, la méthode requise sera automatiquement remplacée par AnalyticalFunction et ajoutée, afin que vous puissiez y définir les paramètres et décrire le traitement requis dans la méthode applyAnalyticFunction.

Si c'est une fonction qui calcule la somme d'une colonne (somme cumulée), vous pouvez la trouver en regardant Créer une fonction avancée. Je pense. Dans cet exemple, vous n'ajoutez qu'un seul enregistrement à la fois à partir de la colonne sélectionnée. Par conséquent, la valeur de retour de applyAnalyticFunction est renvoyée au rapport.

Extrait du wiki officiel ↓

simpleAdvancedFunction.java


import com.hof.mi.interfaces.AnalyticalFunction;
   
public class AccumulativeTotal
    extends AnalyticalFunction{
   
    private Double total = 0.0;
    public String getName()
    {
        return "Accumulative Total";
    }
    public String getDescription()
    {
        return "Calculates the accumulative total for the selected field";
    }
   
    public String getCategory()
    {
        return "Analysis";
    }
    public String getColumnHeading(String colName)
    {
        return "Accumulative Total of " + colName;
    }
    public int getReturnType()
    {
            return TYPE_NUMERIC;
    }
    public boolean acceptsNativeType(int type)
    {
        return type == TYPE_NUMERIC;
    }
    public Object applyAnalyticFunction(int index, Object value) throws Exception
    {
            if (value == null) return null;
            this.total += Double.valueOf(value.toString());
            return this.total;
    }
}

Pour les constantes telles que TYPE_NUMERIC, voir Annexe des fonctions avancées. Une valeur entière ou une constante convient.

Traitement des valeurs numériques pour toute la colonne (par exemple moyenne géométrique)

image.png

Cela n'a pas été mentionné en détail, alors je l'ai essayé en tâtonnant, mais dans Création de fonctions avancées Utilisez la méthode preAnalyticFunction bien écrite. Utilisé pour effectuer des opérations sur l'ensemble de données. C'est écrit, mais c'est difficile à imaginer car l'échantillon n'est pas écrit. Seule la partie du code ajoutée / modifiée précédemment est décrite.

Comme explication, puisque le tableau d'objets des valeurs de colonne est stocké pour l'enregistrement dans l'argument selectedCol de preAnalyticFunction, affectez-le à this.total uniquement au début puis multipliez en incrémentant avec cnt le nombre de fois que le processus a été répété. Je vais. En fin de compte, le nombre de processus répétés dans Math.pow est simplement retourné (affiché) par applyAnalyticFunction.

geometricMean.java


    private int cnt = 0;//add
	public Object applyAnalyticFunction(int index, Object value) throws Exception {//modify method
		// TODO Auto-generated method stub
		if (value == null) return null;
        return this.total;
	}

	public void preAnalyticFunction(Object[] selectedCol){//add method
	    this.total=0.0;
	    for (Object value : selectedCol) {
	        if (value!=null) {
	    		if(this.total==0.0){
	    			this.total = Double.valueOf(value.toString());
	    		} else {
	    			this.total= this.total * Double.valueOf(value.toString());
	    		}
	    		cnt++;
	    	}
	    }
	    this.total = Math.pow( this.total, (double)1/cnt);
	}

	public Object applyAnalyticFunction(int index, Object value) throws Exception {//modify
		// TODO Auto-generated method stub
		if (value == null) return null;
        return this.total;
	}

Si vous souhaitez comparer d'autres colonnes avec la colonne sélectionnée, ou si vous souhaitez traiter en incluant d'autres colonnes (par exemple la co-distribution)

image.png

En plus des colonnes qui utilisent des fonctions avancées, il semble qu'il soit également possible de laisser l'utilisateur spécifier une colonne et exécuter la fonction lorsque vous souhaitez influencer et comparer n'importe quelle colonne. C'était également difficile à comprendre sur le wiki, mais getParameterValue en l'ajoutant aux paramètres via la méthode addParameter de setupParameters dans Parameter setup. Vous pouvez obtenir le paramètre défini avec ("Clé unique"). À ce stade, vous pouvez sélectionner n'importe quelle colonne en définissant le paramètre setDataType sur TYPE_FIELD (100). image.png

Ceci est une description du code, mais cela décrit également uniquement les changements par rapport au code du premier wiki. Obtenez le tableau d'objets de la valeur (selectedCol) à laquelle la fonction avancée est appliquée avec preAnalyticFunction et le tableau d'objets de la valeur de colonne (inputColumn) de la clé unique "FIELD_SELECTION" expliquée précédemment avec getParameterValue (élément 1 dans l'image ci-dessus). Cast chacun en type Double et ajoutez-le au tableau. Par conséquent, ces deux séquences sont passées à la covariance pour obtenir la valeur de la covariance. En ce qui concerne les méthodes de covariance et de somme, nous omettons l'explication car elles ne calculent que la covariance et la somme.

covariance.java


import java.util.ArrayList;//add
import java.util.List;//add

	private List<Double> items1 = new ArrayList<>();//add
	private List<Double> items2 = new ArrayList<>();//add

	protected void setupParameters() {//add
	   Parameter p = new Parameter();
	   p.setUniqueKey("FIELD_SELECTION");
	   p.setDisplayName("Column");
	   p.setDescription("Compare this numeric field to the selected field");
	   p.setDataType(TYPE_FIELD);//100
	   p.setAcceptsFieldType(TYPE_NUMERIC, true);
	   p.setDisplayType(DISPLAY_SELECT);//6
	   addParameter(p);
	}

	public void preAnalyticFunction(Object[] selectedCol){//add
		this.total=0.0;
		Object [] inputColumn = (Object[]) getParameterValue("FIELD_SELECTION");
	      for (Object value : selectedCol) {
	    	items1.add(Double.valueOf(value.toString()));
	      }
	      for (Object value : inputColumn) {
	    	  items2.add(Double.valueOf(value.toString()));
	      }
	      Double r = covariance(items1, items2);
	      this.total = r;
	}

	public Object applyAnalyticFunction(int index, Object value) throws Exception {//modify
		// TODO Auto-generated method stub
		if (value == null) return null;
        return this.total;
	}

	public Double covariance(final List<Double> items1, final List<Double> items2) {//add
		List<Double> items3 = new ArrayList<>();
		int n = items1.size();
		Double i1Mean = sum(items1)/n;
		Double i2Mean = sum(items2)/n;
		for (int i = 0; i < n; i++) {
			items3.add((i1Mean - items1.get(i)) * (i2Mean - items2.get(i)));
		}
		Double i3Sum = sum(items3);
		return i3Sum / n;
	}

	public Double sum(final List<Double> items) {//add
		Double result = 0.0;
		for (Double item : items) {
			result += item;
		}
		return result;
	}

Alors

Cela a été un peu long à expliquer, mais en créant une fonction avancée, c'est un peu ennuyeux de l'exprimer dans un rapport (multiple reportFromReport etc.) afin que vous puissiez rapidement obtenir une valeur tant que vous pouvez l'écrire en Java. Cela prend beaucoup de temps de codage, mais vous serez en mesure d'effectuer facilement des processus tels que l'application d'une certaine formule que vous utilisez toujours en interne et la recherche de la relation entre deux colonnes.

Recommended Posts

Créer des fonctions avancées pour Yellowfin
[Android] Créez une validation pour la saisie de la date!
Créez votre propre encodage pour String.getBytes ()
Créer un serveur fluentd pour les tests