Utilisez la zone de liste pour modifier le nom racine de plusieurs variables dans un tracé de série chronologiqueBonjour, j'essaie de donner à l'utilisateur la possibilité de choisir un nom de balise et de créer un tracé de série chronologique de plusieurs variables ayant ce nom de balise comme racine.
Cependant, j'ai du mal à savoir comment mettre à jour cela dynamiquement.
La zone de liste contient une liste de balises, puis les variables à tracer auront ce nom de balise, plus une extension, .PV, .ETARG, etc. dans cet exemple.

J'analyse l'instruction suivante pour générer les noms de variables
vars = {};
str = "Variables(
X( :Time ),
Y( :" || TAG || ".ETARG, Position (1) ),
Y( :" || TAG || ".LO, Position( 1 ) ),
Y( :" || TAG || ".PV, Position( 1 ) ),
Y( :" || TAG || ".UP, Position( 1 ) )
)";
vars = parse(str);alors le générateur de graphiques les référence, au lieu d'avoir des balises fixes à tracer
Eval Expr(
DataTable1<<GRAPH builder=""></GRAPH>
J'ai une zone de liste dans laquelle l'utilisateur peut choisir le nom racine des variables
ChooseET = List Box( ( ET_TAG_LIST ),
maxSelected( 1 ),
onChange(
TAG = ChooseET << Get Selected;Mais les noms de variables dans le générateur de graphiques sont statiques. Comment rendre cela dynamique ? J'ai essayé de faire de la zone de liste une expression dans le générateur de graphiques, mais cela ne fonctionne pas.
la zone de liste et le générateur de graphiques se trouvent dans une instruction d'allocation. Je ne suis pas sûr de ce que c'est et de sa pertinence.
merci d'avance, voici le code complet !
JMP App(
Set Name( "Application" ),
Set Description(
"An empty workspace for creating custom applications with one or more windows and scripts"
),
Auto Launch( 1 ),
Snap To Grid( 1 ),
Show Grid( 1 ),
Show Properties( 1 ),
Show Sources( 1 ),
Group By Category( 1 ),
Dashboard Mode( 0 ),
Parameters,
Tables(
DataTable1 = GuiTable(
Set Path( "" ),
Set Label( "Output Table" ),
Set Location( "Current Data Table" ),
Set Invisible( 0 )
)
),
Script(JSL Quote(// This script is executed when the application is run.
// Named objects have been created for the application modules
// (for example, "Module1") and the pre-defined object
// "thisApplication" refers to the application object itself.
// Variables and functions declared here are scoped to the
// Application namespace.
dt = Current data table();
ETSelected = "A04004DD";
TAG = ETSelected;;
vars = {};
str = "Variables(
X( :Time ),
Y( :" || TAG || ".ETARG, Position (1) ),
Y( :" || TAG || ".LO, Position( 1 ) ),
Y( :" || TAG || ".PV, Position( 1 ) ),
Y( :" || TAG || ".UP, Position( 1 ) )
)";
vars = parse(str);
show(vars);
PDChartproperties = "
{Legend Model(
3,
Properties( 0, {Line Color( 4 )}, Item ID( \!"" || TAG ||".ETarg\!", 1 ) ),
Properties( 1, {Line Color( 19 ), Marker Size( 1 )}, Item ID( \!"" || TAG ||".LO\!", 1 ) ),
Properties( 2, {Line Color( 53 )}, Item ID( \!"" || TAG ||".PV\!", 1 ) ),
Properties( 3, {Line Color( 19 ), Marker Size( 1 )},Item ID( \!"" || TAG ||".UP\!", 1 )
)
)}
";
props = parse(PDChartproperties);
show(props);
dt = Current Data Table();
ET_LIST = {};
ET_TAG_List = {};
For( i = N Col( dt ), i >= 1, i--,
ET_col = Column (dt, i) << Get Name ();
If(
(Col N Missing( Column( i ) ) / N Row()) != 1 &
Contains (ET_col, "ETarg"),
Insert Into(ET_LIST, ET_col);
);
);
Show (ET_LIST);
n = N Items( ET_LIST );
For( i = 1, i <= n, i++,
ETARG = ET_LIST[i] ;
NFull = Length(ETARG) ;
ETTAG = Left(ETARG,(NFull-6)) ;
Insert Into(ET_TAG_List, ETTAG);
);
Show(ET_TAG_List);
) ),
Allocate(
Module1 = Plan(
PreAllocate,
Script(JSL Quote(// This script is executed when a new module instance is
// created. The pre-defined object "thisModuleInstance" refers
// to the instance object, but other objects such as boxes and
// scripts have not yet been created. Variables declared here are
// scoped to the ModuleInstance namespace.
// This special function will receive parameters passed to CreateInstance()
OnModuleLoad({},
);
thisModuleInstance << Create Objects;
// After this point your module instance objects have been created
// and can be referred to by name (for example, "Button1").
ColList1Select=Function({this},{selectedIndices},
// This function is called when the List Box selection changes
selectedIndices = this << Get Selected Indices;
);
) ),
Allocate(
DataFilterContext1 = Data Filter Context Box();
Lineup2 = Lineup Box();
Report3 = Platform(
DataTable1,
Distribution(
Continuous Distribution(
Column( :A04004DD ET_DELTA Ratio )
),
SendToReport(
Dispatch(
{"A04004DD ET_DELTA Ratio"},
"1",
ScaleBox,
{Min( -5 ), Max( 5 ), Inc( 0.1 ), Minor Ticks( 0 )}
),
Dispatch(
{"A04004DD ET_DELTA Ratio"},
"Quantiles",
OutlineBox,
{Close( 1 )}
),
Dispatch(
{"A04004DD ET_DELTA Ratio"},
"Summary Statistics",
OutlineBox,
{Close( 1 )}
)
)
)
);
Report1 = Platform(
DataTable1,
Graph builder(
Size( 430, 370 ),
Show Control Panel( 0 ),
Fit to Window( "Maintain Aspect Ratio" ),
Variables(
X( :Time ),
Y( :ZZ ET Metric ),
Y( :A04004DD ET_Pass, Position( 1 ) ),
Y( :A04004DD ET_Pass Ave, Position( 1 ) )
),
Elements( Points( X, Y( 1 ), Y( 2 ), Y( 3 ), Legend( 3 ) ) ),
SendToReport(
Dispatch(
{},
"Time",
ScaleBox,
{Min( 3675484152 ), Max( 3676021620 ),
Interval( "Day" ), Inc( 5 ), Minor Ticks( 0 )}
)
)
)
);
ChooseET = List Box( ( ET_TAG_LIST ),
maxSelected( 1 ),
onChange(
TAG = ChooseET << Get Selected;
If( N Items( TAG ) != 0,
Show( TAG );
);
) );
DataFilter1 = DataTable1 << Data Filter(
Local,
Add Filter(
columns( :Day ),
Display( :Day, Size( 0, 0 ), Height( 0 ) )
)
);
Report2 = Platform(
DataTable1,
gb = Eval(
Eval Expr(
DataTable1<<GRAPH builder=""></GRAPH>Modélisation statistique avancéeRe : Utiliser une zone de liste pour modifier le nom racine de plusieurs variables dans un tracé de série chronologiqueen fait, j'ai résolu celui-ci, en ajoutant une autre boîte de vlist et en y ajoutant la distribution dans le script onchange (.
Merci pour le conseil!
Re : Utiliser une zone de liste pour modifier le nom racine de plusieurs variables dans un tracé de série chronologiqueBonjour, merci beaucoup, cela a clarifié certaines choses et j'ai investi dans le livre.
J'ai initialement construit l'application graphiquement et je pense que la distribution est imbriquée dans lineup2, mais définie dans l'instruction Organize(reparent (Lineup2(ChooseET)).
Lorsque j'exécute mon script, il fait presque tout ce que je veux, supprimant l'ancienne distribution « onchange », mais il crée une nouvelle distribution en dehors du tableau de bord/de l'application, plutôt que de l'imbriquer dans la zone Programmation.
J'ai joint le script complet. J'apprécierais tout aperçu supplémentaire, je ne trouve aucun document de référence sur les commandes reparent/allouer.</CODE></P></LINGO-BODY><LINGO-SUB id="lingo-sub-277091" slang="en-US" mode="NONE">Re : Utiliser une zone de liste pour modifier le nom racine de plusieurs variables dans un tracé de série chronologique</LINGO-SUB><LINGO-BODY id="lingo-body-277091" slang="en-US" mode="NONE"><P><A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/18907" target="_blank">@spudton</A> ,</P>
<P> </P>
<P>Les messages disponibles pour une plate-forme JMP peuvent ne pas être disponibles sur d'autres. La plateforme GraphBuilder permet à un utilisateur via l'interface utilisateur de glisser-déposer pour ajouter et supprimer des variables. Par conséquent, JSL a implémenté Add Variable() et Remove Variable() dans GraphBuilderBox.</P>
<P> </P>
<P>La distribution n'a pas une telle interface, il n'existe donc aucune méthode pour ajouter et supprimer des variables.L'index de script JMP, situé dans le menu Aide, affichera la plupart, sinon la totalité, des messages disponibles pour une plate-forme.Menu principal > Aide > Index des scripts > Objets (champ dans le coin supérieur gauche) > Distribution.</P>
<P> </P>
<P>Vous constaterez qu’il existe généralement plusieurs méthodes pour faire quelque chose en utilisant JSL.Voici quelques options :</P>
<P><STRONG>Option</STRONG> : Changez votre plate-forme de distribution pour devenir un GraphBuilder qui crée une distribution. Il n’aura pas les mêmes fonctionnalités ni ne sera identique. Cependant vous pouvez ajouter et supprimer des variables</P>
<PRE><CODE class=" language-jsl">gbdist =Graph Builder(
Size( 534, 456 ),
Show Control Panel( 0 ),
Variables( Y( :A04004DD ET_DELTA Ratio ) ),
Elements( Histogram( Y, Legend( 3 ), Counts( 1 ) ) )
);
Option : Utilisez un conteneur pour votre distribution. Vous devez avoir un espace réservé dans votre affichage pour cela. Ensuite, lorsque vous modifiez une variable, vous supprimez la distribution existante dans ce conteneur, puis en ajoutez une nouvelle. Rappelez-vous que j'ai dit qu'il y avait des éléments à nettoyer dans votre code. Je ne les ai pas tous nettoyés.
Le code a un conteneur vide, Lineup2. Si vous créez Report3, imbriqué dans cette boîte. En fait, je le changerais en VListBox puisque vous n'utilisez pas la puissance de LineupBox.
Lineup2 = Lineup Box();
Report3 = Platform(
DataTable1,
Distribution(
Continuous Distribution(
Column( :A04004DD ET_DELTA Ratio )
),
Ci-dessous une partie du script 7_InteractiveDisplays.jsl écrit pour Applications compagnon JSL du langage de script JMP, 2e édition .
clear globals();
orig_dt = Open( "$SAMPLE_DATA/Fitness.jmp" );
cnt = 0; Chosen Columns={}; //initiate values
//----Refresh display script---------------------------
refresh_script = Expr(
Try(dist_vlist << delete);
If( (cnt > 0 & N Items( Chosen Columns ) >= 1),
show(Chosen Columns);
dist_vlist = VListBox(
orig_dist = orig_dt << Distribution( Column( Eval( Chosen Columns ) ), invisible )
); //end VListBox
result_ob << append( dist_vlist );
) //end If
); //end Expr
//----Action to take for Add-----------------------------
add_script = Expr(
cnt = cnt + 1;
listocols << Append( selcol << Get Selected );
);
//----Action to take for Remove -----------------------------
remove_script= Expr(
cnt = cnt + 1;
listocols << Remove Selected;
);
//_______________________________________________________________________________
//-----Dialog Window layout---------------------------------
dist_win = New Window( "Create Distributions",
H List Box(
selcol = Col List Box( All, width( 100 ), nlines( 6 ) ),
Lineup Box( N Col( 1 ), Spacing( 3 ),
Button Box( "Add Column >>", add_script ),
Button Box( "<< Remove Column", remove_script )
),
// listocols is a Col List Box
listocols = Col List Box( width( 100 ), nlines( 6 ),
OnChange( Chosen Columns = listocols << Get Items;
refresh_script;)
) //end listocols
), //end HListBox
Text Box( " " ),
result_ob = Outline Box( "Current Selections" )
);
Je sais que vous travaillez probablement sur une tâche avec une date limite. Mais essayez ce script. Il fournit des exemples de plusieurs fonctionnalités auxquelles j'ai fait référence dans les articles de cette discussion. Il fournit un mode d'emploi pour ajouter et supprimer des distributions, la deuxième option.
Bonne chance!
Re : Utiliser une zone de liste pour modifier le nom racine de plusieurs variables dans un tracé de série chronologiqueC'est génial merci.
J'ai répété la syntaxe avec mon deuxième tracé de série chronologique et cela fonctionne bien.
Je n'arrive pas à trouver la syntaxe pour modifier la colonne dans la boîte de distribution lorsque le nom du TAG est modifié.
cela devrait-il fonctionner sur un objet Distribution ?
Eval( Eval Expr( Dstr3 << Remove Variable( {Expr( Column( dt, curr_TAG || " ET_DELTA Ratio" ) )} ) ) );
J'ai joint le script complet.
Merci encore pour votre aide. C'est presque en train de s'enfoncer !
Re : Utiliser une zone de liste pour modifier le nom racine de plusieurs variables dans un tracé de série chronologique@spudton ,
J'ai joint le script qui s'exécute sur votre table sur mon PC.
L'erreur que vous obtenez peut être que vous n'avez pas utilisé le JSL.
curr_TAG = TAG[1];
TAG est le résultat de ListBox << get selected ; qui renvoie une liste, vous devez obtenir le premier élément de la liste.
Oh, l'autre problème est que ma table générée utilise l'extension ETARG.Le code que vous avez inséré change ETARG en ETarg. Cela pourrait être l'autre source d'erreur.
Le script a une ligne commentée show(curr_TAG) . Décommentez et regardez le journal.
Notez que vous verrez quelques lignes commentées. J'ai inventé quelques variables dans le tableau que j'ai généré pour le tester hier.
Re : Utiliser une zone de liste pour modifier le nom racine de plusieurs variables dans un tracé de série chronologiqueSalut, merci encore. J'ai joint un tableau qui contient toutes les colonnes avec quelques données.
Je supprimerai les instructions codées en dur et ferai un peu de ménage comme vous l'avez recommandé une fois que j'aurai une méthode claire sur la façon dont je vais procéder.
J'ai inséré votre code mais j'ai obtenu l'erreur "L'argument jsl doit être un caractère lors de l'accès ou de l'évaluation de 'Concat'"
salutations
Wayne
Re : Utiliser une zone de liste pour modifier le nom racine de plusieurs variables dans un tracé de série chronologique@spudton
J'ai regardé ton code.Le script possède un handle vers le deuxième GraphBuilder.J'ai dû apporter quelques modifications, car je n'avais pas de tableau de données à utiliser.
Votre code comporte plusieurs éléments codés en dur, je vous suggère de les supprimer, par exemple
- Envoyer au rapport Plages de dates de l'axe X
- Envoyer aux éléments de légende du rapport (ou vous devez les conserver)
Il semble que votre TAG de départ soit codé en dur.J'ai donc défini le curr_TAG de départ sur cette valeur.Ci-dessous, je montre le JSL à supprimer, ajouter des variables à la GraphBuilderBox. Je pense qu'il pourrait être plus élégant d'avoir un conteneur autour de gb, et en cas de changement, de supprimer gb puis d'ajouter un nouveau gb.
Quelques commentaires, êtes-vous sûr que le tableau de données comportera toujours les colonnes PV, LO, UP ?Est-ce quelque chose que vous devez vérifier ?
Comme indiqué précédemment, il existe plusieurs méthodes pour obtenir le même résultat.Bonne chance!
curr_TAG = "A04004DD";
ChooseET = List Box( ( ET_TAG_LIST ),
maxSelected( 1 ),
onChange(
TAG = ChooseET << Get Selected;
If( N Items( TAG ) != 0,
Show( TAG );
gbb2 = Report(gb)[GraphBuilderBox(1)];
Eval( EvalExpr(gbb2 << Remove Variable({Expr(column(dt,curr_TAG||".ETARG")), Role("Y"), Position(1)} );
gbb2 << Remove Variable({Expr(column(dt,curr_TAG||".LO")), Role("Y"), Position(1)} );
gbb2 << Remove Variable({Expr(column(dt,curr_TAG||".PV")), Role("Y"), Position(1)} );
gbb2 << Remove Variable({Expr(column(dt,curr_TAG||".UP")), Role("Y"), Position(1)} );
));
curr_TAG = TAG[1];
//show(curr_TAG);
wait(0);
Eval( EvalExpr(gbb2 << Add Variable({Expr(column(dt,curr_TAG||".ETARG")), Role("Y"), Position(1)} );
gbb2 << Add Variable({Expr(column(dt,curr_TAG||".LO")), Role("Y"), Position(1)} );
gbb2 << Add Variable({Expr(column(dt,curr_TAG||".PV")), Role("Y"), Position(1)} );
gbb2 << Add Variable({Expr(column(dt,curr_TAG||".UP")), Role("Y"), Position(1)} );
));
);
);
) ;
Re : Utiliser une zone de liste pour modifier le nom racine de plusieurs variables dans un tracé de série chronologique@spudton ,
Vous trouverez ci-dessous une capture d'écran d'une application avec une zone de liste, dans laquelle un utilisateur sélectionne une variable puis le rapport change. Dans cet exemple, tous les graphiques sont prédéfinis (voir les onglets) et l'action lors de la sélection consiste à changer l'onglet visible. Votre action de sélection serait de supprimer la "balise" actuelle et d'ajouter la nouvelle balise, je suppose que cela serait fait en utilisant les messages pour supprimer et ajouter des variables à votre 2ème GraphBuilderBox.

Si vous modifiez votre application de << Exécuter à << Modifier,
vous devriez voir l'interface utilisateur d'ApplicationBuilder. La ListBox (cart_lb) est mise en surbrillance et le contour rouge indique où ajouter une fonction/un script pour l'action à entreprendre lorsqu'une sélection est effectuée.

Voici le script du ListBox de cette application
Local({idx, nme, tList},
tlist = (cart_lb << get selected);
if(nitems(tlist) >0,
nme = tlist[1];
//show(nme);
idx = var_tabs << index of tab(nme);
var_tabs << set selected(idx);
//show(idx);
); //end if
); //end Local
Comme indiqué pour cette application, j'obtiens l'index de la liste. Les onglets sont alignés avec la liste donc une fois l'index connu, l'onglet associé s'affiche.
Ne sachant pas si vous avez nommé le 2ème affichage GraphBuilder, je ne peux pas vous aider avec le script. Je n'ai pas essayé votre application car je n'ai pas de table de données avec les noms de colonnes attendus.
Peut-être que ce n'est pas nouveau pour vous.J'essaie juste de vous donner quelques pistes, juste au cas où.
Re : Utiliser une zone de liste pour modifier le nom racine de plusieurs variables dans un tracé de série chronologiqueMerci pour la réponse.
Je ne veux pas que l'utilisateur doive sélectionner plusieurs balises. Je veux qu'ils choisissent un élément dans la liste, puis l'application affiche le tracé de la série chronologique de plusieurs colonnes, toutes avec cette balise comme racine du nom.
Sélectionnez donc TAG ABC123, et la série chronologique affichera ABC123.ETARG, ABC123.UP, ABC123.LO et ABC123.PV
Re : Utiliser une zone de liste pour modifier le nom racine de plusieurs variables dans un tracé de série chronologique@spudton ,
Il existe plusieurs méthodes pour ce faire. La méthode que vous choisissez dépend de l'action que vous attendez pour l'interface utilisateur.
Un utilisateur peut sélectionner 1 élément dans votre liste, puis utiliser le contrôle, en sélectionner d'autres, maintenir Shift peut-être une plage, puis en supprimer certains. Mon point est de savoir si vous souhaitez que le rapport soit mis à jour avec chaque sélection, ou peut-être ajouter un bouton, donc une fois sélectionné, l'utilisateur appuie sur un bouton Go, Rerun ou Do It pour refaire les analyses.
Concernant le rapport GraphBuilder, vous pouvez ajouter et supprimer des variables dans la boîte Graph Builder. ou vous pouvez ajouter un filtre local d'exclusion dont la visibilité est réduite qui capture toutes les sélections sauf les sélections des utilisateurs. Il peut s'agir d'options au lieu de Eval Expr.Lorsque JSL Companion 2nd Edition a été écrit, l'utilisation de GraphBuilderBox a été manquée.
Je vous suggère de créer un graphique avec les filtres et d'essayer différentes options pour comprendre comment cela pourrait fonctionner.
Personnellement, à moins que l'utilisateur ne puisse faire qu'une seule sélection, j'aime avoir un bouton pour lancer une tâche si plusieurs sélections sont possibles.
Je n'ai pas lu votre code de très près, mais vous pouvez vous référer à une zone d'affichage en utilisant l'espace de noms de fenêtre, peut-être window:GraphBuilderBox(2) ou établir une relation comme (this<< parent) etc.
Il existe donc plusieurs options pour obtenir ce que vous voulez et cela dépend de la structure arborescente actuelle du rapport et du comportement que vous souhaitez de votre interface utilisateur.