Erstellen eines interaktiven Pareto-Diagramms mit interaktiven Schiebereglern zur Aktualisierung der SpaltenformelIch habe eine Reihe von Spezifikationen, die ein Produkt in der Produktion erfüllen muss. Ich habe eine Spalte mit einer Formel, die die für jede Spezifikation erforderlichen Werte (Grenzwerte) angibt und ein binäres Pass/Fail erstellt. Diese Formel wird verwendet, um ein Pareto-Diagramm mit vorbeikommenden Zahlen und Prozentsätzen zu erstellen. Ich möchte ein interaktives Pareto-Diagramm mit Schiebereglern erstellen, um die Testgrenzen anzupassen und zu sehen, wie sich eine Änderung dieser Grenzen auf die Anzahl der Elemente auswirken würde, die den Test bestehen/nicht bestehen.
Meine beiden Hauptprobleme sind folgende:
1) Es werden mehrere Produkttypen getestet. Da ich keine konsistente Anzahl von Spezifikationen pro Produkt habe, habe ich vor, diese Spezifikationen in eine Liste einzufügen (im angehängten Code wäre das „spec“) und eine externe Datentabelle zu verwenden, um diese Spezifikationen für das gewünschte Produkt einzugeben. Dabei benötige ich keine Hilfe, sollte aber bedenken, da ich Schiebereglerfelder, Zahlenfelder usw. in eine for-Schleife eingeben muss, ohne direkt auf die Variablen zu verweisen.
2) Ich benötige ein Array von Variablen (Spezifikationsgrenzen), damit ich die Formel zu Testzwecken aktualisieren kann. Auch dies muss in einer for-Schleife erfolgen. In der aktuellen Version des Skripts scheinen die Werte der Spezifikationsgrenzen in der Formel für die Spalte „Bestanden/Nicht bestanden“ nicht aktualisiert zu werden. Wenn das Schiebereglerfeld den Befehl << inval empfängt und das Diagramm aktualisiert wird, passiert nichts, da die eigentliche Pass/Fail-Spalte nicht aktualisiert wird. Ich verwende derzeit ein assoziatives Array, um die Spezifikationsgrenzen zu speichern. Dies ist möglicherweise nicht der richtige Weg, dies zu tun.
Ich habe die Beispieldatentabelle, die ich verwende, sowie das aktuelle Skript angehängt. Danke!
Names default to here(1);
RangeMin = Associative array(["m1" => 0,
"m2" => 0,
"m3" => 0,
"thickness" => 0]);
RangeMax = Associative array(["m1" => 1,
"m2" =>1,
"m3" => 1,
"thickness" => 20]);
limit = Associative array(["m1" => 0.5,
"m2" => 0.5,
"m3" => 0,
"thickness" => 4]);
SliderVars = {0.5,0.5,0.5,10};
spec = {"m1","m2","m3","thickness"};
GraphingTable = current data table();
finalDisplay = New Window ("test", testlist = h list box());
:name("Pass/Fail") << Set Formula(
if((:thickness >= limit["thickness"] & :m3 >= limit["m3"] & m2 >= limit["m2"] & m1 >= limit["m1"]), "Pass", "Fail" )
);
PP= Graphing Table << Pareto Plot( Cause( :"Pass/Fail"n ) );
ValuesOutlineBox = Outline Box ( "Values", SliderList = v list box());
For(i=1, i<= n items(spec),i++,
SliderList << append(
h list box(
Text box(spec[i]),
testing = spec[i];
eval(
parse(
eval insert(
"Var^char(i)^ = ^SliderVars[i]^;
SB^char(i)^ = Slider Box(
^RangeMin << get value(spec[i])^,
^RangeMax << get value(spec[i])^,
Var^char(i)^,
NEB^char(i)^ << set( Var^char(i)^ );
limit[testing] = Var^char(i)^;
testlist[2] << Delete Box();
wait(0.1);
testlist << append(report(PP));
);"
);
);
),
testing = spec[i];
eval(
parse(
eval insert(
"NEB^char(i)^ = Number Edit Box( Var^char(i)^,
<< set function(
Function( {this},
Var^char(i)^ = this << get;
SB^char(i)^ << inval;
limit[testing] = Var^char(i)^;
testlist[2] << Delete Box();
wait(0.1);
testlist << append(report(PP));
)
)
);"
);
);
),
)
)
);
testlist << append(ValuesOutlineBox);
testlist << append(report(PP));Qualitäts- und VerfahrenstechnikWindowsBetreff: Erstellen eines interaktiven Pareto-Diagramms mit interaktiven Schiebereglern zur Aktualisierung der SpaltenformelDas Specs-Array scheint dadurch nicht verändert zu werden. Das habe ich zunächst auch gedacht. Ich konnte jedoch auf die einzelnen Felder im V-Listenfeld verweisen.Ich schätze Ihre Hilfe wie immer.
Betreff: Erstellen eines interaktiven Pareto-Diagramms mit interaktiven Schiebereglern zur Aktualisierung der SpaltenformelDanke! Gutes Beispiel.
Betreff: Erstellen eines interaktiven Pareto-Diagramms mit interaktiven Schiebereglern zur Aktualisierung der SpaltenformelIch denke, die Werte sollten im assoziativen Array „specs“ gespeichert werden, wenn Sie sie ändern. Sie können aber auch versuchen, die Verweise auf Zahlenbearbeitungsfelder in einer Liste oder einem anderen assoziativen Array zu speichern. Oder Sie können XPath (oder eine andere Möglichkeit zum Durchsuchen der Baumstruktur) verwenden, um diese Referenzen abzurufen, wenn Sie sie benötigen.
Betreff: Erstellen eines interaktiven Pareto-Diagramms mit interaktiven Schiebereglern zur Aktualisierung der SpaltenformelIch bin auf ein weiteres Problem mit diesem Skript gestoßen und habe gehofft, Ihre Meinung zu erfahren. Wenn ich manuell eine Zahl in das Zahlenbearbeitungsfeld für die Spezifikationen eingebe, möchte ich eine Schaltfläche hinzufügen, um die Spezifikationen in einer anderen Tabelle speichern zu können. Das Hinzufügen der Schaltfläche ist kein Problem, aber ich weiß nicht, wie ich dann auf die aktuellen Werte der Zahlenbearbeitungsfelder verweisen kann. Nach jeder Funktion werden sie zum V-Listenfeld hinzugefügt und diese Werte werden in der Formelspalte aktualisiert. Aber ohne die Möglichkeit, auf die Werte des einzelnen Zahlenbearbeitungsfelds zu verweisen oder diese Zahlen zu speichern und sie in einer separaten Datenstruktur mit einem Verweis auf die Spezifikation einzugeben, weiß ich nicht, wie ich diese neuen Grenzwerte im Skript speichern kann. Wenn Sie auf das Listenfeld new_control H verweisen, wird nur das letzte Feld angezeigt, das die for-Schleife durchlaufen hat. Alle Gedanken oder Vorschläge wären großartig.
Betreff: Erstellen eines interaktiven Pareto-Diagramms mit interaktiven Schiebereglern zur Aktualisierung der SpaltenformelNach Angaben des JMP-Supports betrachtete die JMP-Entwicklung dies als unbeabsichtigtes Verhalten und wird in einer zukünftigen Version behoben.
Betreff: Erstellen eines interaktiven Pareto-Diagramms mit interaktiven Schiebereglern zur Aktualisierung der SpaltenformelDanke schön. Wenn Sie etwas zum Problem mit der Range Slider Box hören, wäre ich sehr daran interessiert.
Betreff: Erstellen eines interaktiven Pareto-Diagramms mit interaktiven Schiebereglern zur Aktualisierung der SpaltenformelIch würde Range Slider Box verwenden, aber es scheint nicht richtig mit assoziativem Array und Liste als viertem Argument zu funktionieren (ich werde morgen diesbezüglich eine E-Mail an den Support senden). Ich würde also zu den Slider-Boxen zurückkehren.
Dies verwendet jetzt Formelausdrücke und doppelte Schiebereglerfelder (es ist ziemlich einfach, Skripte wie dieses zu unterbrechen, die von Variablennamen in Windows abhängen, daher müssen Sie möglicherweise Namespaces oder etwas anderes für diese hinzufügen).
Names Default To Here(1);
//declare associative array for specs
specs = Associative Array();
//open limits file in JMP
LimitsTable = open("vinyl data limits.jmp", invisible);
//set testing data to be able to manipulate in JMP
GraphingTable = open("Vinyl Data.jmp");
//Select the Specs you want to compare by using a COL LIST BOX
ListNumericCols = GraphingTable << Get Column Names(numeric);
nw = New Window("Select Wanted Specifications", << Modal, << return result,
clb = Col List Box (<< Set Items (ListNumericCols))
);
ListSpecNames = nw["clb"];
show(ListSpecNames);
//insert spec names into associative array
for (i=1,i< (N Items(ListSpecNames) + 1), i++,
Insert Into(specs, ListSpecNames[i]);
ColSpec = Column(LimitsTable, 1); //1 is the coolumn for spec name
LimitList= {};
//Insert Lower Limit onto
for(j=1, j < (nrows(LimitsTable)+1), j++,
if (ColSpec[j] == ListSpecNames[i],
ColLimit = Column(LimitsTable, 2);//2 is the column for lower limit
MinVal = 0;
if(ColLimit[j] > 0, MinVal = ColLimit[j] / 2, MinVal = ColLimit[j]*2);
InsertInto(LimitList, MinVal );
break();
));
for(k=1, k < (nrows(LimitsTable)+1), k++,
if (ColSpec[k] == ListSpecNames[i],
ColLimit = Column(LimitsTable, 2);//2 is the column for lower limit
InsertInto(LimitList, ColLimit[k]);
break();
));
for(l=1, l < (nrows(LimitsTable)+1), l++,
if (ColSpec[l] == ListSpecNames[i],
ColLimit = Column(LimitsTable, 3);//3 is the column for lower limit
InsertInto(LimitList, ColLimit[l]);
break();
));
for(m = 1, m < (nrows(LimitsTable)+1), m++,
if (ColSpec[m] == ListSpecNames[i],
ColLimit = Column(LimitsTable, 3);//3 is the column for upper limit
MaxVal = 0;
if(ColLimit[m] > 0, MaxVal = ColLimit[m] *2, MaxVal = ColLimit[m] /2 );
InsertInto(LimitList, MaxVal );
break();
)
);
show (LimitList);
specs[ListSpecNames[i]] = LimitList
);
//show(specs); for debugging and making sure specs array is being populated
//sel_specs = Associative Array(ListSpecNames);
//specs << Intersect(sel_specs);
//*******************************************************************
//Create Pass Fail column if not existing.
if(!contains(GraphingTable << Get Column Names("String"), "Pass/Fail"),
GraphingTable << new column("Pass/Fail", Character);
);
//using a string to insert a formula into the row that can be called upon dynamically
formula_expr = Expr(
f = "If(All(";
For Each({{spec, limits}}, specs,
f ||= Eval Insert("^limits[2]^ < :^spec^ < ^limits[3]^ & ");
);
//drop last &
f = Left(f, Length(f) - 3);
f ||= "),"; // close all
f ||= "\!N\!t\!"PASS\!",\!"FAIL\!"
)";
Eval(EvalExpr(Column(GraphingTable, "Pass/Fail") << Set Formula(
Expr(Parse(f));
)));
);
formula_expr;
nw2 = New Window("test", testlist = H List Box(
ValuesOutlineBox = Outline Box("Values", SliderList = V List Box()),
Graphing Table << Pareto Plot(Cause(:"Pass/Fail"n))
));
For Each({{spec_name, spec_list, idx}}, specs,
new_control = H List Box(
Text Box(spec_name),
rsb = Slider Box(spec_list[1], spec_list[4]),
Number Edit Box(spec_list[2], << Set Minimum(spec_list[1]), << Set Maximum(spec_list[4]), << Set Function(function({this},
(this << Prev Sib) << Set(this << get);
formula_expr;
)))
);
Eval(EvalExpr(rsb << Set Var(specs[Expr(spec_name)][2])));
rsb << Set Function(function({this},
(this << sib) << Set(this << Get, Run Script(1));
));
SliderList << Append(new_control);
);
For Each({{spec_name, spec_list, idx}}, specs,
new_control = H List Box(
Text Box(spec_name),
rsb = Slider Box(spec_list[1], spec_list[4]),
Number Edit Box(spec_list[2], << Set Minimum(spec_list[1]), << Set Maximum(spec_list[4]), << Set Function(function({this},
(this << Prev Sib) << Set(this << get);
formula_expr;
)))
);
Eval(EvalExpr(rsb << Set Var(specs[Expr(spec_name)][3])));
rsb << Set Function(function({this},
(this << sib) << Set(this << Get, Run Script(1));
));
SliderList << Append(new_control);
);
Beispiel für das Problem:
Names Default To Here(1);
var1 = 1;
var2 = 2;
var3 = 2;
var4 = 1;
aa = ["low" => 1, "up" => 2];
l = {};
l[1] = 1;
l[2] = 2;
nw = New window("test",
rsb1 = Range Slider Box(1, 2, var1, var2, Show(1)),
rsb2 = Range Slider Box(1, 2, aa["low"], aa["up"]),
rsb2_1 = Range Slider Box(1, 2, aa["low"], var3),
rsb1_2 = Range Slider Box(1, 2, var4, aa["up"]),
rsb3 = Range Slider Box(1, 2, l[1], l[2]),
);
Show(rsb1 << Get Lower Var, rsb1 << Get Upper Var);
Show(rsb2 << Get Lower Var, rsb2 << Get Upper Var);
Show(rsb2_1 << Get Lower Var, rsb2_1 << Get Upper Var);
Show(rsb1_2 << Get Lower Var, rsb1_2 << Get Upper Var);
Show(rsb3 << Get Lower Var, rsb3 << Get Upper Var);
Eval(EvalExpr(rsb3 << Set Lower Var(Expr(Expr(l[1])))));
Eval(EvalExpr(rsb3 << Set Upper Var(Expr(Expr(l[2])))));
Show(rsb3 << Get Lower Var, rsb3 << Get Upper Var);
Betreff: Erstellen eines interaktiven Pareto-Diagramms mit interaktiven Schiebereglern zur Aktualisierung der SpaltenformelGlauben Sie, dass es besser wäre, zwei Schieberegler zu haben, einen für die Ober- und eine für die Untergrenze jeder Spezifikation, statt sich mit den Argumenten der Bereichs-Schieberegler zu befassen? Die gestrigen Tests ergaben viel mehr Probleme mit Bereichsschieberegler-Boxen und viel weniger Dokumentation zu Argumenten des Box-Typs. Ich denke, es würde das Problem mit der Bereichsbox beheben, könnte aber den Formelteil verkomplizieren.
Betreff: Erstellen eines interaktiven Pareto-Diagramms mit interaktiven Schiebereglern zur Aktualisierung der SpaltenformelFür die Formel haben Sie mindestens zwei Möglichkeiten: Sie können Ausdruck verwenden, um den Wert in der Formel zu aktualisieren, die Sie jedes Mal ausführen, wenn Spezifikationen aktualisiert werden, oder Sie können die Formel so ändern, dass sie ein assoziatives Spezifikationsarray verwendet
f = "If(All(";
For Each({{spec, limits}}, specs,
f ||= Eval Insert("specs[\!"^spec^\!"][2] < :^spec^ < specs[\!"^spec^\!"][3] & ");
);
//drop last &
f = Left(f, Length(f) - 3);
f ||= "),"; // close all
f ||= "\!N\!t\!"PASS\!",\!"FAIL\!"
)";
Range Slider Box ist noch chaotischer als Slider Box, daher ist es eine größere Herausforderung, die Probleme damit zu umgehen. Ich würde mich höchstwahrscheinlich nicht einmal um Eval(EvalExpr()) kümmern und einfach Eval(Parse()) verwenden und versuchen, dort korrekte Referenzen zu erhalten. Ich würde nur mit der Ranger-Schiebereglerbox beginnen und nachdem ich diese zum Laufen gebracht habe, würde ich nacheinander die Nummernbearbeitungsfelder hinzufügen (das vierte Argument der Bereichsschiebereglerboxen könnte etwas fehlerhaft sein ...)
Betreff: Erstellen eines interaktiven Pareto-Diagramms mit interaktiven Schiebereglern zur Aktualisierung der SpaltenformelIch schätze die Hilfe, die Sie in den letzten Tagen geleistet haben, sehr. Ich habe Ihre Lösungen zu diesem und meinem anderen Beitrag durchgearbeitet. Aktualisierung einer Spaltenformel basierend auf einem assoziativen Array, auf das von einer Liste verwiesen wird.
Ich habe mir die Parse- und Eval-Ausdrücke angeschaut und versucht, sie auszuarbeiten, und bekomme nun ein Verständnis dafür, wie das in JSL funktioniert. Ich habe ein Problem mit der Kombination der beiden Ideen. Mir wurde klar, dass es besser wäre, 4 Indizes im assoziativen Array zu haben, um Spezifikationen zu speichern. Im Format „spec“ => {, , , }. Dank Ihrer Hilfe beim Parsen erstellt das folgende Skript nun dieses Array und eine Pass/Fail-Spalte, um zu prüfen, ob alle Spezifikationen erfüllt sind. Das Ziel besteht darin, die Toleranzen in den Grenzen zu lockern, bis hin zu den niedrigsten oder maximalen Toleranzen, um die neue gewünschte Erfolgsausbeute des Produkts zu erreichen, und das Pareto-Diagramm wie oben festgelegt zu aktualisieren. Ich habe versucht, ein Bereichsschiebefeld zu implementieren, da dies intuitiver wäre, um Toleranzen bei Grenzwerten zu lockern, aber ich habe Probleme. Außerdem wird die automatische Aktualisierung des Pareto-Plots wie zuvor unterbrochen.
Ich glaube, ein Problem könnte darin bestehen, dass ich nicht glaube, dass die Zeichenfolge „f“ für zukünftige Ausführungen der Festlegung der Formel für die Spalte „Bestanden nicht bestanden“ aktualisiert wird, da sie anfänglich definiert wird. Wir wären Ihnen sehr dankbar, wenn Sie mir helfen könnten.
Names Default To Here(1);
//declare associative array for specs
specs = Associative Array();
//open limits file in JMP
LimitsTable = open("vinyl data limits.jmp", invisible);
//set testing data to be able to manipulate in JMP
GraphingTable = open("Vinyl Data.jmp");
//Select the Specs you want to compare by using a COL LIST BOX
ListNumericCols = GraphingTable << Get Column Names(numeric);
nw = New Window("Select Wanted Specifications", << Modal, << return result,
clb = Col List Box (<< Set Items (ListNumericCols))
);
ListSpecNames = nw["clb"];
show(ListSpecNames);
//insert spec names into associative array
for (i=1,i< (N Items(ListSpecNames) + 1), i++,
Insert Into(specs, ListSpecNames[i]);
ColSpec = Column(LimitsTable, 1); //1 is the coolumn for spec name
LimitList= {};
//Insert Lower Limit onto
for(j=1, j < (nrows(LimitsTable)+1), j++,
if (ColSpec[j] == ListSpecNames[i],
ColLimit = Column(LimitsTable, 2);//2 is the column for lower limit
MinVal = 0;
if(ColLimit[j] > 0, MinVal = ColLimit[j] / 2, MinVal = ColLimit[j]*2);
InsertInto(LimitList, MinVal );
break();
));
for(k=1, k < (nrows(LimitsTable)+1), k++,
if (ColSpec[k] == ListSpecNames[i],
ColLimit = Column(LimitsTable, 2);//2 is the column for lower limit
InsertInto(LimitList, ColLimit[k]);
break();
));
for(l=1, l < (nrows(LimitsTable)+1), l++,
if (ColSpec[l] == ListSpecNames[i],
ColLimit = Column(LimitsTable, 3);//3 is the column for lower limit
InsertInto(LimitList, ColLimit[l]);
break();
));
for(m = 1, m < (nrows(LimitsTable)+1), m++,
if (ColSpec[m] == ListSpecNames[i],
ColLimit = Column(LimitsTable, 3);//3 is the column for upper limit
MaxVal = 0;
if(ColLimit[m] > 0, MaxVal = ColLimit[m] *2, MaxVal = ColLimit[m] /2 );
InsertInto(LimitList, MaxVal );
break();
)
);
show (LimitList);
specs[ListSpecNames[i]] = LimitList
);
//show(specs); for debugging and making sure specs array is being populated
//sel_specs = Associative Array(ListSpecNames);
//specs << Intersect(sel_specs);
//*******************************************************************
//Create Pass Fail column if not existing.
if(!contains(GraphingTable << Get Column Names("String"), "Pass/Fail"),
GraphingTable << new column("Pass/Fail", Character);
);
//using a string to insert a formula into the row that can be called upon dynamically
f = "If(All(";
For Each({{spec, limits}}, specs,
f ||= Eval Insert("^limits[2]^ < :^spec^ < ^limits[3]^ & ");
);
//drop last &
f = Left(f, Length(f) - 3);
f ||= "),"; // close all
f ||= "\!N\!t\!"PASS\!",\!"FAIL\!"
)";
Eval(EvalExpr(Column(GraphingTable, "Pass/Fail") << Set Formula(
Expr(Parse(f));
)));
nw2 = New Window("test", testlist = H List Box(
ValuesOutlineBox = Outline Box("Values", SliderList = V List Box()),
Graphing Table << Pareto Plot(Cause(:"Pass/Fail"n))
));
filler = {};
For Each({{spec_name, spec_list, idx}}, specs,
new_control = H List Box(
Text Box(spec_name),
Range Slider Box(spec_list[1], spec_list[4] , spec_list[2], spec_list[3], << Set Function(function({this},
(this << Sib) << Set(this << get, run Script(1));
))) ,
Number Edit Box(spec_list[2], << Set Minimum(spec_list[1]), << Set Maximum(spec_list[4]), << Set Function(function({this},
(this << Prev Sib) << Set(this << get);
specs[((this << parent) << child) << get text][2] = this << get;
Column(GraphingTable, "Pass/Fail") << Eval Formula;
))),
Number Edit Box(spec_list[3], << Set Minimum(spec_list[1]), << Set Maximum(spec_list[4]), << Set Function(function({this},
(this << Prev Sib) << Set(this << get);
specs[((this << parent) << child) << get text][3] = this << get;
Column(GraphingTable, "Pass/Fail") << Eval Formula;
)))
);
SliderList << Append(new_control);
);
Betreff: Erstellen eines interaktiven Pareto-Diagramms mit interaktiven Schiebereglern zur Aktualisierung der SpaltenformelVielen Dank! Dies ist meine zweite Woche als Skriptersteller in JSL und Sie haben keine Ahnung, wie sehr Sie mir geholfen haben.
Betreff: Erstellen eines interaktiven Pareto-Diagramms mit interaktiven Schiebereglern zur Aktualisierung der SpaltenformelDer Code ist ziemlich stark verändert und ich bin mir nicht 100 % sicher, wie zuverlässig das sein wird, aber ich würde die Funktion „set“ und „child/sib/parent“ verwenden, um korrekte Referenzen in Bezug auf die Schiebereglerfelder zu erhalten. Auch Pareto scheint aktualisiert zu werden, wenn der Formelwert aktualisiert wird. Dies könnte von der Verwendung von Eval(EvalExpr()) profitieren.
Names Default To Here(1);
specs = Associative Array();
specs["m1"] = {0, 0.5, 1};
specs["m2"] = {0, 0.5, 1};
specs["m3"] = {0, 0, 1};
specs["thickness"] = {0, 4, 20};
GraphingTable = Current Data Table();
Column(GraphingTable, "Pass/Fail") << Set Formula(
If((:thickness >= specs["thickness"][2] & :m3 >= specs["m3"][2] & m2 >= specs["m2"][2] & m1 >= specs["m1"][2]),
"Pass",
"Fail"
)
);
nw = New Window("test", testlist = H List Box(
ValuesOutlineBox = Outline Box("Values", SliderList = V List Box()),
Graphing Table << Pareto Plot(Cause(:"Pass/Fail"n))
));
filler = {};
For Each({{spec_name, spec_list, idx}}, specs,
new_control = H List Box(
Text Box(spec_name),
Slider Box(spec_list[1], spec_list[3], 0, << Set Function(function({this},
(this << Sib) << Set(this << get, run Script(1));
))),
Number Edit Box(spec_list[2], << Set Minimum(spec_list[1]), << Set Maximum(spec_list[3]), << Set Function(function({this},
(this << Prev Sib) << Set(this << get);
specs[((this << parent) << child) << get text][2] = this << get;
Column(GraphingTable, "Pass/Fail") << Eval Formula;
)));
);
SliderList << Append(new_control);
);
In Ihrem Code scheint es so zu sein, als ob Ihnen ^ beim Testen fehlt, um Werte im assoziativen Limit-Array zu aktualisieren.