How to use Filter Change Handler to work with Page option in Graph Builder?
Feb 1, 2024 08:32 AM(5742 views)
Attached is an example data table. The script below tries to plot each parameter selected via the Local Data Filter in a new "Page" in Graph Builder. As it stands, the y-axis title is shown as "Median" every time a new "Parameter" is selected via the Local Data Filter.
I would like the Parameter name to be the y-axis title when new a parameter gets selected and plotted on a new "Page".
I tried using the filter change handler for this, but my script does not quite work. I think I need the index i below to be updated each time a new parameter is selected or may be there is another way. Any direction will be useful.
XPath( "//TextEditBox" ))[i]
here is my script
Names Default To Here (1);
Clear Log ();
gb = Graph Builder(
Size( 531, 325 ),
Show Control Panel( 0 ),
Variables( X( :PartID ), Y( :Median ), Page( :Parameter ), Color( :TestStage ) ),
Elements( Points( X, Y, Legend( 34 ) ) ),
Local Data Filter(
Conditional,
Add Filter(
columns( :TestStage, :Parameter ),
Where( :TestStage == {"A", "B"} ),
Where( :Parameter == {"BKDVoltage", "Capacitance"} )
)
),
SendToReport( Dispatch( {}, "graph title", TextEditBox, {Set Text( "myTitleGoesHere" )} ) )
);
ldf = Current Report()["Local Data Filter"] << get scriptable object;
changeTitle = Function( {this},
print(this);
ldfText = Regex(ldf << get where clause(),"\(?\s*(:Parameter == .*?)\)","\1");
if(ismissing(ldfText),ldfText = " Selected Test Parameter ");
(Report( gb ) << XPath( "//TextEditBox" ))[6] << Set Text(ldfText);
);
fsh = ldf << Make Filter Change Handler(changeTitle());
@jthi Thanks, I tried to see which rows are getting filtered and the script partially works with the data table exampleSummaryTableNoLimsNew.jmp, but not in all filtering cases.
I am trying to select the filtered rows in the data table and manually check if they are correct. Currently I am stuck.
Clearly its my lack of understanding of the code flow which is preventing me to debug further so I would request some more help.
Modified script below (line 28 is where I check with get filtered rows).
Names Default To Here(1);
clear log ();
dt = Current Data Table();
gb = dt << Graph Builder(
Size( 571, 174 ),
Show Control Panel(0),
Variables(X(:PartID), Y(:Median), Page(:Parameter), Color(:TestStage)),
Elements(Points(X, Y, Legend(34))),
SendToReport(Dispatch({}, "graph title", TextEditBox, {Set Text("Trend Chart")}))
);
ldf = gb<<Local Data Filter(
Conditional,
Add Filter(
columns(:TestDate, :Has Limits?, :TestStage, :Parameter ),
Where( :Has Limits? == "Yes" ),
Where( :TestStage == "STG5" ),
)
);
Summarize(dt, uniq_params = By(:Parameter));
update_title = Function({this},
param_where = Regex(local_filter << get where clause(), "\(?\s*(:Parameter == .*?)\)", "\1");
fr = ldf << get filtered rows; dt<< select rows (fr);
If(Is Missing(param_where),
param_list = uniq_params,
param_where_list = Words(param_where, "|");
param_list = Transform Each({where_str}, param_where_list,
title = Trim Whitespace(Word(-1, where_str, "="));
Substitute(title, "\!"", "");
);
);
tebs = Report(gb) << XPath("//GraphBuilderTitleBox/TextEditBox");
y_tebs = tebs[4 :: N Items(tebs) :: 2]; // skip title, subtitle and xaxis?
If(N Items(y_tebs) != N Items(param_list),
Return(0); // some problem
);
gb << inval;
For Each({param_val, idx}, param_list, y_tebs[idx] << Set Text(param_val));
gb << update window;
Return(1);
);
local_filter = Current Report()["Local Data Filter"] << get scriptable object;
update_title(local_filter);
filter_handler = local_filter << Make Filter Change Handler(update_title());
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Cities.jmp");
obj = dt << Data Filter(
Add Filter(columns(:Region, :POP)),
Mode(Select(0), Show(0), Include(1))
);
Summarize(dt, all_states = By(:State));
show(all_states);
// Change filter value at this point and run the code below
cur_rows = obj << Get Filtered Rows;
visible_states = Associative Array(dt[cur_rows, "State"]) << get keys;
Show(N Items(all_states), N Items(visible_states));
@jthi using my data table exampleSummaryTableNoLimsNew.jmp, the following appears to work as expected (I have manually checked the data table and outputs). How does one proceed from this to my actual problem where the data filter is within the Graph Builder. I find associative arrays very confusing so requesting some help here.
Names Default To Here(1);
clear log ();
dt = Current Data Table();
obj = dt << Data Filter(Conditional,
Add Filter(columns(:TestDate, :Has Limits?, :TestStage, :Parameter) ),
Mode(Select(0), Show(0), Include(1))
);
Summarize(dt, all_Parameters = By(:Parameter));
show(all_Parameters);
// Change filter value at this point and run the code below
cur_rows = obj << Get Filtered Rows;
visible_Parameters = Associative Array(dt[cur_rows, "Parameter"]) << get keys;
Show(N Items(all_Parameters), N Items(visible_Parameters));
Keep with the simple JMP Sample Data and solve your problems one by one. First you have to define your problems. I skip quite a few problems you have to solve (or have already solved) to get this working and try to get focus on the current issue:
On top level you want to be able to figure out how to update Y-axis titles based on the Page name
You have filters which affect which pages are visible
You can have filter set to all, one, many and none
All and none are basically the same (all pages are visible) but they need to be managed in separate manner
How can you handle the these different situations; All, None, One and Many?
How can you handle these situations inside a function used in filter change hander?
Until you get this issue solved, there is no point moving to the full application you have (if you get stuck, you could solve some separate problem first if you have them). Below is example script, you should be able to get the else statement to always return 41 (or rather full list of states if you remove N Items()).
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Cities.jmp");
gb = dt << Graph Builder(
Size(630, 590),
Show Control Panel(0),
Include Missing Categories(1),
Variables(X(:State)),
Elements(Treemap(X, Legend(4))),
Local Data Filter(
Conditional,
Add Filter(columns(:Region, :POP), Display(:Region, N Items(6)))
)
);
Summarize(dt, all_states = By(:State));
show(N Items(all_states));
filter_ref = (Report(gb) << top parent)[OutlineBox("Local Data Filter")] << Get Scriptable Object;
get_selected_states = function({a},
cur_rows = filter_ref << Get Filtered Rows;
If(!Is Empty(cur_rows),
visible_states = Associative Array(dt[cur_rows, "State"]) << get keys;
Show(N Items(visible_states));
,
Show("Empty..."); // Your problem, you should have all states visible here
);
);
get_selected_states(1);
f = filter_ref << Make Filter Change Handler(get_selected_states);
@jthi Thanks. Your last script works when I run it and results are as expected with JMP Sample Data (true for all your scripts so far). The reason I used my data table is because I thought the data form I have could be causing my issue.
I am afraid, I am a bit lost now with all the different scripts on the table.
What is returned can be a bit finicky in my experience (especially when nothing/everything is selected). Next you would have to figure out what to do in those situations and then you should be able to modify my earlier script.
Below are few solutions to this whole thing which do work for me, not sure if the "simpler" one does work in JMP16. I wouldn't suggest looking into these until you have managed to figure out what you could do int the "Empty" situation so you understand what type of issues there could be.