Création d'un diagramme de Pareto interactif avec des curseurs interactifs pour mettre à jour la formule de la colonneJ'ai un ensemble de spécifications qu'un produit en production devrait respecter. J'ai une colonne avec une formule qui spécifie les valeurs nécessaires (limites) par chaque spécification et crée un succès/échec binaire. Cette formule est utilisée pour créer un graphique de Pareto du nombre et du pourcentage de réussite. Je souhaite créer un graphique de Pareto interactif avec des curseurs pour ajuster les limites de test et voir comment la modification de ces limites modifierait le nombre d'éléments réussissant/échouant au test.
Mes deux principaux problèmes sont les suivants :
1) Plusieurs types de produits seront testés. Je n'aurai pas un nombre constant de spécifications par produit, donc je prévois d'insérer ces spécifications dans une liste (dans le code joint, ce serait "spec") et d'utiliser une table de données externe pour remplir ces spécifications pour le produit souhaité. Ce n'est pas quelque chose pour lequel j'ai besoin d'aide, mais c'est quelque chose à considérer car je devrai saisir des curseurs, des nombres, etc. dans une boucle for sans faire directement référence aux variables.
2) J'ai besoin d'un tableau de variables (limites de spécification) pour pouvoir mettre à jour la formule à des fins de test. Encore une fois, cela devra être dans une boucle for. Dans l'état actuel du script, il semble que les valeurs des limites de spécification ne soient pas mises à jour dans la formule de la colonne réussite/échec. Lorsque le curseur reçoit la commande <
J'ai joint l'exemple de table de données que j'utilise ainsi que le script actuel. Merci!
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));Ingénierie de la qualité et des procédésles fenêtresRe : Création d'un diagramme de Pareto interactif avec des curseurs interactifs pour mettre à jour la formule de la colonneIl ne semble pas modifier le tableau des spécifications. C'est ce que je pensais au départ aussi. Cependant, j'ai pu référencer les cases individuelles à l'intérieur de la V List Box.J'apprécie votre aide comme toujours.
Re : Création d'un diagramme de Pareto interactif avec des curseurs interactifs pour mettre à jour la formule de la colonneMerci! Bon exemple.
Re : Création d'un diagramme de Pareto interactif avec des curseurs interactifs pour mettre à jour la formule de la colonneJe pense que les valeurs doivent être enregistrées dans le tableau associatif des spécifications lorsque vous les modifiez. Mais vous pouvez également essayer d'enregistrer les références aux zones d'édition de nombres dans une liste ou un autre tableau associatif. Ou peut-être pouvez-vous utiliser XPath (ou un autre moyen de parcourir l'arborescence) pour obtenir ces références lorsque vous en avez besoin.
Re : Création d'un diagramme de Pareto interactif avec des curseurs interactifs pour mettre à jour la formule de la colonneJe suis tombé sur un autre problème avec ce script et j'espérais avoir votre avis. Si je saisis manuellement un nombre dans la zone d'édition du nombre pour les spécifications, je souhaite ajouter un bouton pour pouvoir enregistrer les spécifications dans une autre table. L'ajout du bouton n'est pas un problème, mais je ne sais pas comment je pourrai référencer les valeurs actuelles des zones d'édition de nombre. Après la pour chaque fonction, elles sont ajoutées à la zone de liste V et ces valeurs sont mises à jour dans la colonne de formule. Mais sans moyen de référencer les valeurs de la zone d'édition de numéro individuel ou la possibilité de stocker ces nombres et de les saisir dans une structure de données séparée avec une référence à la spécification, je ne sais pas comment enregistrer ces nouvelles limites dans le script. La référence à la zone de liste new_control H n'affichera que la dernière zone qui est passée par la boucle for each. Toutes les pensées ou suggestions seraient formidables.
Re : Création d'un diagramme de Pareto interactif avec des curseurs interactifs pour mettre à jour la formule de la colonneSelon la prise en charge de JMP, le développement de JMP a considéré qu'il s'agissait d'un comportement involontaire et sera traité dans une future version.
Re : Création d'un diagramme de Pareto interactif avec des curseurs interactifs pour mettre à jour la formule de la colonneMerci. Si vous entendez quelque chose sur le problème de Range Slider Box, je serais très intéressé de le voir.
Re : Création d'un diagramme de Pareto interactif avec des curseurs interactifs pour mettre à jour la formule de la colonneJ'utiliserais Range Slider Box, mais cela ne semble pas fonctionner correctement avec un tableau associatif et une liste comme quatrième argument (j'enverrai un e-mail au support demain à ce sujet). Je reviendrais donc aux boîtes Slider.
Ceci utilise maintenant une expression de formule et des boîtes à double curseur (il est assez facile de casser des scripts comme celui-ci qui dépendent des noms de variables dans Windows, vous devrez donc peut-être ajouter des espaces de noms ou autre chose pour ceux-ci)
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);
);
Exemple de problème :
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);
Re : Création d'un diagramme de Pareto interactif avec des curseurs interactifs pour mettre à jour la formule de la colonnePensez-vous qu'il serait préférable d'avoir deux curseurs, un pour la limite supérieure et un pour la limite inférieure de chaque spécification plutôt que de traiter les arguments des curseurs de plage ? Les tests d'hier ont révélé beaucoup plus de problèmes avec les boîtes de curseur de plage avec beaucoup moins de documentation sur les arguments du type de boîte. Je pense que cela résoudrait le problème de la boîte de plage, mais pourrait compliquer la partie formule.
Re : Création d'un diagramme de Pareto interactif avec des curseurs interactifs pour mettre à jour la formule de la colonnePour la formule, vous avez au moins deux options : vous pouvez utiliser l'expression pour mettre à jour la valeur dans la formule que vous exécutez chaque fois que les spécifications sont mises à jour ou modifier la formule pour utiliser le tableau associatif des spécifications.
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 est encore plus désordonné que Slider Box, donc contourner les problèmes avec cela est un plus grand défi. Je ne m'embêterais probablement même pas avec Eval(EvalExpr()) et j'utiliserais simplement Eval(Parse()) et j'essaierais d'y obtenir des références correctes. Je commencerais avec seulement Ranger Slider Box et après avoir fait fonctionner ceux-ci, j'ajouterais des boîtes d'édition de nombre une à la fois (le quatrième argument de Range Slider Boxes pourrait être un peu bogué ...)
Re : Création d'un diagramme de Pareto interactif avec des curseurs interactifs pour mettre à jour la formule de la colonneJ'apprécie beaucoup l'aide que vous m'avez apportée ces derniers jours. J'ai travaillé sur vos solutions à cela ainsi que sur mon autre message, Avoir une mise à jour de formule de colonne basée sur un tableau associatif référencé par une liste.
J'ai parcouru et essayé de comprendre les expressions d'analyse et d'évaluation et je comprends comment cela fonctionne dans jsl. J'ai un problème avec la combinaison des deux idées. Je me suis rendu compte qu'il serait préférable d'avoir 4 indices dans le tableau associatif pour stocker les spécifications. Au format "spec" => {, , , }. Grâce à votre aide pour l'analyse, le script ci-dessous crée maintenant ce tableau et une colonne Pass/Fail pour voir si toutes les spécifications sont respectées. Le but étant de desserrer les tolérances dans les limites, jusqu'aux tolérances les plus basses ou maximales afin d'obtenir le nouveau taux de rendement de produit souhaité, et de mettre à jour le diagramme de Pareto comme vous l'avez fixé ci-dessus. J'ai essayé d'implémenter une boîte de curseur de plage, car ce serait plus intuitif pour assouplir les tolérances sur les limites, mais j'ai du mal. Cela interrompt également la mise à jour automatique du diagramme de Pareto comme auparavant.
Je pense qu'un problème pourrait être que, parce que la chaîne "f" est définie initialement, je ne pense pas qu'elle sera mise à jour pour les futures exécutions de définition de la formule pour la colonne d'échec de réussite. Toute façon dont vous pourriez être en mesure d'aider serait grandement appréciée.
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);
);
Re : Création d'un diagramme de Pareto interactif avec des curseurs interactifs pour mettre à jour la formule de la colonneMerci beaucoup! C'est ma deuxième semaine de script en JSL et vous ne savez pas à quel point vous m'avez aidé.
Re : Création d'un diagramme de Pareto interactif avec des curseurs interactifs pour mettre à jour la formule de la colonneLe code est assez fortement modifié et je ne suis pas sûr à 100% de sa fiabilité, mais j'utiliserais la fonction set et child/sib/parent pour obtenir les références correctes liées aux curseurs. Pareto semble également être mis à jour lorsque la valeur de la formule est mise à jour. Cela pourrait bénéficier d'une certaine utilisation de Eval(EvalExpr())
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);
);
Dans votre code, il semble qu'il vous manque peut-être ^ autour des tests pour obtenir les valeurs dans le tableau associatif limit mis à jour.