Comment parcourir par programme une arborescence de générateur de graphiques et associer des framebox à leurs titres.J'ai un élément d'analyse (voir ci-dessous) dans lequel je souhaite annoter des graphiques spécifiques à l'aide d'un script que j'ai écrit. Par exemple, je souhaite ajouter une annotation à XXX104 et XXX107. Sur ces deux graphiques, j'ajouterai un graphique et un texte personnalisés pour identifier un groupe de points sur lesquels je souhaite attirer l'attention.

En utilisant la commande '<< show tree structure', je peux identifier les framebox qui contiennent chaque graphique. Cependant, je ne vois pas le « nom » du graphique qui leur est associé. Par exemple, je veux pouvoir parcourir cet arbre en utilisant les noms de graphiques (par exemple XXX107) comme recherche et identifier le framebox associé (par exemple FrameBox(7)) afin de pouvoir le référencer et ajouter mon annotation de manière automatisée.

En fait, dans l'ensemble de l'arborescence, je ne vois aucun "nœud d'arbre" portant les "noms de graphique" tels que XXX107.
En fin de compte, le tableau ci-dessous est ce que je veux réaliser

Voici le code que j'ai utilisé pour le faire manuellement. Le fichier est également téléchargé.
Mon problème est que je n'arrive pas à comprendre comment référencer une framebox en identifiant son « titre » correspondant dans l'arborescence d'affichage.
Bravo, Troie
clearLog();
try(close(DT, noSave));
DT = open("PRE_CLEAN_DATA.jmp", invisible);
DT << newColumn("ENT_CLUSTER", character, nominal, formula(:ENTITY || "_" || :CLUSTER));
Plat = newWindow("CHART",
myGraphBox = DT << Graph Builder(
Size( 1446, 747 ),
Show Control Panel( 0 ),
Variables(
X( :WW ),
Y( :ENTITY_MEAN ),
Y( :GRAND_MEAN, Position( 1 ) ),
Wrap( :ENTITY ),
Color( :CLUSTER )
),
Elements(
Points( X, Y( 1 ), Y( 2 ), Legend( 23 ) ),
Smoother( X, Y( 1 ), Y( 2 ), Legend( 24 ) )
),
SendToReport(
Dispatch(
{},
"WW",
ScaleBox,
{Min( 202301.28 ), Max( 202320.72 ), Inc( 1 ), Minor Ticks( 1 ),
Label Row(
{Automatic Tick Marks( 0 ), Label Orientation( "Vertical" ),
Show Minor Ticks( 0 )}
)}
)
)
);
summarize(DT, clusters = by(:ENT_CLUSTER));
foreach({item}, clusters,
if(contains(item, "NON_CLUSTER"), continue());
ent = word(1, item, "_");
clust = word(2, item, "_");
write("Entity = " || ent || "\!n");
write("Cluster = " || clust || "\!n");
left = min(DT:WW[DT << getRowsWhere(:ENT_CLUSTER == item)]);
right = max(DT:WW[DT << getRowsWhere(:ENT_CLUSTER == item)]);
group_mean_min = min(DT:ENTITY_MEAN[DT << getRowsWhere(:ENT_CLUSTER == item)]);
group_mean_max = max(DT:ENTITY_MEAN[DT << getRowsWhere(:ENT_CLUSTER == item)]);
grand_mean_min = min(DT:GRAND_MEAN[DT << getRowsWhere(:ENT_CLUSTER == item)]);
grand_mean_max = max(DT:GRAND_MEAN[DT << getRowsWhere(:ENT_CLUSTER == item)]);
if(group_mean_min < grand_mean_min, bot = group_mean_min, bot = grand_mean_min);
if(group_mean_max > grand_mean_max, top = group_mean_max, top = grand_mean_max);
write("Left, Right, Top, Bot = " || char(left) || ", " || char(right) || ", " || char(top) || ", " || char(bot) || "\!n");
// ##########################################################
// ## This is what I want to do:
// ##########################################################
// 1. Traverse the graphbox tree
// 2. Identify Frame Box for each of the entities found
// 3. Get the Framebox Reference
// 4. Add my annotation.
// This is a manual Example I made using the show properties and tree structure commands
//myGraphBox << Show Properties();
//myGraphBox << Show tree structure();
rep = myGraphBox << report;
framebox = rep[frame box( 7 )];
framebox << Add Graphics Script(
penColor( "Black" );
fillcolor("Blue");
Transparency(0.1);
rect( left, top, right, bot, 0 );
rect( left, top, right, bot, 1 );
);
framebox << Add Graphics Script(
textSize(9);
textColor("Blue");
text( {left, top}, "Cluster 1" );
);
write("\!n");
);
);
Automatisation et scriptsRe : Comment parcourir par programme une arborescence de générateur de graphiques et associer des framebox à leurs titres.Les GFrameBox sont triées dans un ordre spécifique (ce pourrait être une bonne idée de le forcer à l'aide de la propriété de colonne Value Order). Vous pouvez obtenir l'index framebox en fonction de cet ordre
cluster_rows = Loc(dt[0, "ENT_CLUSTER"], "XXX104_CLUSTER1");
fb_idx = Contains(clusters, "XXX104_CLUSTER1"); // framebox idx // might not work in all cases!
fbs = Report(myGraphBox) << XPath("//FrameBox");
Eval(EvalExpr(
fbs[fb_idx] << Add Graphics Script(
Pen Color("Black");
Fill Color("Red");
Transparency(0.1);
Rect(Expr(left), Expr(top), Expr(right), Expr(bot), 0);
Rect(Expr(left), Expr(top), Expr(right), Expr(bot), 1);
);
));
N'oubliez pas non plus d'évaluer les valeurs dans un script graphique, afin de ne pas vous retrouver avec cela.

En général, les GraphBuilderGroupBox sont très difficiles d'accès/manipulation et j'essaierais de l'éviter autant que possible. Vous pouvez obtenir les titres avec XPath, mais il peut y avoir des titres supplémentaires
(Report(myGraphBox) << XPath("//GraphBuilderGroupBox/text()"))
{"ENTITY", "XXX101", "XXX102", "XXX103", "XXX104", "XXX105", "XXX106", "XXX107","XXX112", "XXX118", "XXX119"}Re : Comment parcourir par programme une arborescence de générateur de graphiques et associer des framebox à leurs titres.Exemple complet rapide et sale :
Names Default To Here(1);
dt = Open("$DOWNLOADS/PRE_CLEAN_DATA.jmp", invisible);
dt << New Column("ENT_CLUSTER", character, nominal, formula(:ENTITY || "_" || :CLUSTER));
gb = dt << Graph Builder(
Size(1446, 747),
Show Control Panel(0),
Variables(X(:WW), Y(:ENTITY_MEAN), Y(:GRAND_MEAN, Position(1)), Wrap(:ENTITY), Color(:CLUSTER)),
Elements(Points(X, Y(1), Y(2), Legend(23)), Smoother(X, Y(1), Y(2), Legend(24))),
SendToReport(
Dispatch(
{},
"WW",
ScaleBox,
{Min(202301.28), Max(202320.72), Inc(1), Minor Ticks(1), Label Row(
{Automatic Tick Marks(0), Label Orientation("Vertical"), Show Minor Ticks(0)}
)}
)
)
);
rep = Report(gb);
fbtitles = (rep << XPath("//GraphBuilderGroupBox/text()"));
Remove From(fbtitles, Contains(fbtitles, "ENTITY")); // we "know" we have wrap variable
// or we could perform filtering using Filter Each
Summarize(dt, clusters = by(:ENT_CLUSTER));
For Each({item}, clusters,
If(Contains(item, "NON_CLUSTER"),
Continue()
);
ent = Word(1, item, "_");
clust = Word(2, item, "_");
Write("Entity = " || ent || "\!n");
Write("Cluster = " || clust || "\!n");
left = Min(DT:WW[DT << getRowsWhere(:ENT_CLUSTER == item)]);
right = Max(DT:WW[DT << getRowsWhere(:ENT_CLUSTER == item)]);
group_mean_min = Min(DT:ENTITY_MEAN[DT << getRowsWhere(:ENT_CLUSTER == item)]);
group_mean_max = Max(DT:ENTITY_MEAN[DT << getRowsWhere(:ENT_CLUSTER == item)]);
grand_mean_min = Min(DT:GRAND_MEAN[DT << getRowsWhere(:ENT_CLUSTER == item)]);
grand_mean_max = Max(DT:GRAND_MEAN[DT << getRowsWhere(:ENT_CLUSTER == item)]);
If(group_mean_min < grand_mean_min,
bot = group_mean_min,
bot = grand_mean_min
);
If(group_mean_max > grand_mean_max,
top = group_mean_max,
top = grand_mean_max
);
Write("Left, Right, Top, Bot = " || Char(left) || ", " || Char(right) || ", " || Char(top) || ", " || Char(bot) || "\!n");
framebox = rep[frame box(Contains(fbtitles, ent);)];
Eval(EvalExpr(
framebox << Add Graphics Script(
Pen Color("Black");
Fill Color("Blue");
Transparency(0.1);
Rect(Expr(left), Expr(top), Expr(right), Expr(bot), 0);
Rect(Expr(left), Expr(top), Expr(right), Expr(bot), 1);
);
));
Eval(EvalExpr(
framebox << Add Graphics Script(
Text Size(9);
Text Color("Blue");
Text({Expr(left), Expr(top)}, Expr(clust));
);
));
Write("\!n");
);

(J'ai fait quelque chose d'un peu comme ça plus tôt pour les wafermaps)
Re : Comment parcourir par programme une arborescence de générateur de graphiques et associer des framebox à leurs titres.Merci pour l'aide Jarmo.
Je n'ai pas fait beaucoup de travail sur la traversée de ces arbres mais la façon dont vous l'expliquez est géniale..... peut-être que celui-ci pourrait être un sujet pour le club des scripteurs de l'année prochaine 
Bravo, Troie
Re : Comment parcourir par programme une arborescence de générateur de graphiques et associer des framebox à leurs titres.Approfondir la couche de rapport pourrait certainement être un bon sujet.