Rendi il gestore dello stato di riga non funzionante come previsto in una casella di contesto del filtro datiCara comunità,
Cerco di creare un dashboard utilizzando caselle di contesto/sorgente del filtro dati,
e funziona in alcuni dettagli come previsto.
Ma ho bisogno di funzionalità aggiuntive, in base alla selezione, per filtrare una tabella aggiuntiva, che si trova in Tab Page Box Details1.
Che ricreo ogni volta utilizzando Make Row State Handler in quel contesto.
Quando si selezionano singole righe in Tabulate, tutto funziona correttamente, ma:
- quando deseleziono tutto, la casella della pagina della scheda non cambia
- quando seleziono più di una riga in Tabulate, si verifica una selezione errata nella casella della pagina della scheda
- quando seleziono punti in GraphBuilder, la generazione della tabella viene eseguita in modo eccessivo
- ...
Come rendere questo scenario più solido?
Esiste un modo diverso (senza gestore dello stato di riga) per ottenere le righe selezionate in Tabulate e Graph Builder?
Esiste una strategia migliore per fare cose del genere?
Grazie mille e BR
Names Default To Here( 1 );
Clear Log();
dt = Open( "$SAMPLE_DATA\Big Class.jmp" );
dt << show window( 0 );
tabulate_expr = Expr(
tb_obj = dt << Tabulate( Show Control Panel( 0 ), Add Table( Row Table( Grouping Columns( :sex, :age ) ) ) )
);
gb_expr = Expr(
gb_obj = dt << Graph Builder(
Show Control Panel( 0 ),
Variables( X( :weight ), Y( :height ) ),
Elements( Points( X, Y, Legend( 3 ) ), Smoother( X, Y, Legend( 4 ) ) )
)
);
action_expr = Expr(
Button Box( "Start Analysis", Print( pb_details << get row states() ) )
);
nw = New Window( "Dashboard",
Data Filter Context Box(
H List Box(
V List Box(
H List Box(
Panel Box( "Filter (in Data Filter Source Box)", /* Filter and GB */ dfsb =
Data Filter Source Box( tabulate_expr )
),
Panel Box( "Graph Builder (to be filtered in context", gb_expr )
),
Panel Box( "Action", /* Action */ action_expr )
),
pb_details = Panel Box( "Details (as well in data filter context box)", /* Tab Box */
Tab Box(
Tab Page Box( "Details1 (Data Grid Box, update via Make Row State Handler)", dgb = Data Grid Box() ),
Tab Page Box( "Details2 (Filtered automatically)", tabulate_expr )
)
)
)
)
);
detail_dt = dt << subset( invisible, columns( {"name", "age", "sex"} ) );
dgb << set data table( detail_dt );
dgb << close side panels;
nw << on close(
Close( dt, NoSave );
Close( detail_dt, NoSave );
For Each( {dt}, detail_dt_lst, Try( Close( dt, NoSave ) ) );
);
last_a = []; /* remember last selection to avoid double action */
detail_dt_lst = {}; /* save all table references to be able to close later */
details_update = Function( {a},
If( Is Matrix( a ) & Char( a ) != Char( last_a ),
Show( a );
detail_old = dgb << Get Data Table();
detail_dt = dt << subset( invisible, columns( {"name", "age", "sex"} ) );
Insert Into( detail_dt_lst, detail_dt );
detail_dt << select rows( a ) << delete rows();
dgb << set data table( detail_dt );
dgb << close side panels;
Close( detail_old, NoSave );
last_a = a;
);
);
rsh = pb_details << Make Row State Handler( dt, details_update );
Automazione e scriptingFinestreRe: Il gestore dello stato di riga non funziona come previsto in una casella di contesto del filtro datiA mio parere ci sono così tanti problemi diversi con i gestori dello stato delle righe che non puoi renderli robusti (ad esempio vengono rimossi troppo facilmente, innescano troppe cose e molti altri problemi). Per evitare alcuni dei problemi che stai riscontrando, non usare il parametro che puoi avere nella funzione per il gestore dello stato delle righe , a nel tuo caso, e usa invece << Ottieni righe selezionate.
Quindi vuoi avere una dashboard con tabulate e graph builder e questi dovrebbero filtrare una tabella dati? È necessario avere una tabella dati che viene filtrata? Il modo più semplice per evitare tutti i problemi è utilizzare una casella di pulsanti per aggiornare la tabella.
Re: Il gestore dello stato di riga non funziona come previsto in una casella di contesto del filtro datiA seconda del tuo caso d'uso reale, ecco un'opzione che potrebbe funzionare. Si basa sull'aggiornamento del sottoinsieme anziché sulla sua ricreazione. Verificherà anche le righe selezionate anziché basarsi sul parametro "a"
Names Default To Here(1);
dt = Open("$SAMPLE_DATA\Big Class.jmp", Invisible);
tabulate_expr = Expr(
tb_obj = dt << Tabulate(
Show Control Panel(0),
Add Table(Row Table(Grouping Columns(:sex, :age)))
)
);
gb_expr = Expr(
gb_obj = dt << Graph Builder(
Show Control Panel(0),
Variables(X(:weight), Y(:height)),
Elements(Points(X, Y, Legend(3)), Smoother(X, Y, Legend(4)))
)
);
action_expr = Expr(
Button Box("Start Analysis", Print(pb_details << get row states()))
);
nw = New Window("Dashboard",
Data Filter Context Box(
H List Box(
V List Box(
H List Box(
Panel Box("Filter (in Data Filter Source Box)",
dfsb = Data Filter Source Box(tabulate_expr)
),
Panel Box("Graph Builder (to be filtered in context",
gb_expr
)
),
Panel Box("Action",
action_expr
)
),
pb_details = Panel Box("Details (as well in data filter context box)",
Tab Box(
Tab Page Box(
"Details1 (Data Grid Box, update via Make Row State Handler)",
dgb = Data Grid Box()
),
Tab Page Box("Details2 (Filtered automatically)",
tabulate_expr
)
)
)
)
)
);
detail_dt = dt << subset(invisible, columns({"name", "age", "sex"}));
dgb << set data table(detail_dt);
dgb << close side panels;
nw << on close(
Close(dt, NoSave);
Close(detail_dt, NoSave);
);
last_rows = {}; // use list as you can compare those directly
extra_triggers = 0;
details_update = Function({a},
// Write("\!N", Round(Tick Seconds(), 2), " \!thappy state handler triggering");
// Show(dt << Get Row States);
cur_rows = As List(dt << Get Selected Rows);
If(N Items(cur_rows) == 0,
cur_rows = As List((1::N Rows(dt))`); // same as all rows selected
);
If(cur_rows == last_rows,
extra_triggers++;
return();
);
Write("\!N", extra_triggers, " unnecessary triggers occured.");
extra_triggers = 0;
last_rows = cur_rows;
If(N Rows(detail_dt) > N Items(cur_rows),
detail_dt << Delete Rows(N Items(cur_rows) + 1::N Rows(detail_dt));
, N Rows(detail_dt) < N Items(cur_rows),
detail_dt << Add Rows(N Items(cur_rows) - N Rows(detail_dt));
);
detail_dt[0, {"name", "age", "sex"}] = dt[Matrix(last_rows), {"name", "age", "sex"}];
);
rsh = pb_details << Make Row State Handler(dt, details_update);
Questo non è l'unico metodo per farlo, ma è un'opzione piuttosto semplice che puoi provare.
Voce della lista dei desideri nella speranza che i gestori di stato siano utilizzabili in futuro: migliorare i gestori di stato di JMP (etichetta di passaggio del mouse, gestore di stato di riga, gestore di stato di filtro, scheduler, ...)
Re: Il gestore dello stato di riga non funziona come previsto in una casella di contesto del filtro datiUna fonte di confusione con < < m> è come interpretare l'argomento a . Il vettore rappresenta le righe che sono cambiate, ma non dice nulla sullo stato in cui si trovano. Riceverai anche callback per eventi non filtro, ad esempio: modifiche agli stati di riga di selezione, etichetta o marcatore apportate nella tabella. Ciò rende difficile limitare la risposta agli eventi di interesse.
Alla luce di quanto detto, ritengo che i problemi principali con lo script originale siano (1) la mancata risposta quando la funzione viene chiamata consecutivamente con gli stessi argomenti (ecco perché clear non funziona) e (2) l'utilizzo dei numeri di riga come righe da eliminare.
Lo script seguente (nota: solo JMP 18+) non tenta di tracciare e limitare le modifiche, ma dovrebbe rispondere correttamente rimuovendo le righe effettivamente escluse dal sottoinsieme.
Names Default To Here( 1 );
Clear Log();
//https://community.jmp.com/t5/Discussions/Make-Row-State-Handler-not-working-as-expected-in-a-Data-Filter/m-p/791520
dt = Open( "$SAMPLE_DATA\Big Class.jmp" );
dt << show window( 0 );
tabulate_expr = Expr(
tb_obj = dt << Tabulate( Show Control Panel( 0 ), Add Table( Row Table( Grouping Columns( :sex, :age ) ) ) )
);
gb_expr = Expr(
gb_obj = dt << Graph Builder(
Show Control Panel( 0 ),
Variables( X( :weight ), Y( :height ) ),
Elements( Points( X, Y, Legend( 3 ) ), Smoother( X, Y, Legend( 4 ) ) )
)
);
action_expr = Expr(
Button Box( "Start Analysis", Print( pb_details << get row states() ) )
);
nw = New Window( "Dashboard",
Data Filter Context Box(
H List Box(
V List Box(
H List Box(
Panel Box( "Filter (in Data Filter Source Box)", /* Filter and GB */ dfsb =
Data Filter Source Box( tabulate_expr )
),
Panel Box( "Graph Builder (to be filtered in context", gb_expr )
),
Panel Box( "Action", /* Action */ action_expr )
),
pb_details = Panel Box( "Details (as well in data filter context box)", /* Tab Box */
Tab Box(
Tab Page Box( "Details1 (Data Grid Box, update via Make Row State Handler)", dgb = Data Grid Box() ),
Tab Page Box( "Details2 (Filtered automatically)", tabulate_expr )
)
)
)
)
);
detail_dt = dt << subset( invisible, columns( {"name", "age", "sex"} ) );
dgb << set data table( detail_dt );
dgb << close side panels;
nw << on close(
Close( dt, NoSave );
Close( detail_dt, NoSave );
For Each( {dt}, detail_dt_lst, Try( Close( dt, NoSave ) ) );
);
detail_dt_lst = {}; /* save all table references to be able to close later */
details_update = Function( {a},
Show( a );
If( Is Matrix( a ),
detail_old = dgb << Get Data Table();
detail_dt = dt << subset( invisible, columns( {"name", "age", "sex"} ) );
Insert Into( detail_dt_lst, detail_dt );
filter_state = pb_details << Get Row States(dt);
detail_dt << select rows( Where(Excluded(As Row State(filter_state))) ) << delete rows();
dgb << set data table( detail_dt );
dgb << close side panels;
Close( detail_old, NoSave );
);
);
rsh = pb_details << Make Row State Handler( dt, details_update );
Re: Il gestore dello stato di riga non funziona come previsto in una casella di contesto del filtro datiGrazie per il suggerimento, la pulsantiera potrebbe essere una soluzione.
Ho due possibilità:
(1) caricare durante l'avvio della GUI tutti i dettagli di cui potrei aver bisogno, mantenendoli come una tabella nascosta e visualizzando una parte di cui ho bisogno in un determinato contesto, qui opterei per una soluzione dinamica con rowstate ecc.
(2) su richiesta caricare i dati dal database (qui opterei per una soluzione tramite pulsante).
Ma il caso è in generale piuttosto interessante per me, perché ci sono molti casi simili, in cui preferirei (1) o (2), e voglio capire meglio come funziona JMP con essi.
Re: Il gestore dello stato di riga non funziona come previsto in una casella di contesto del filtro datiGrazie mille per il vostro contributo @jthi e @danschikore , mi ha dato delle ottime idee per migliorare la mia dashboard.