열 수식을 업데이트하기 위해 대화형 슬라이더 상자로 대화형 파레토 플롯 만들기생산 중인 제품이 통과해야 하는 일련의 사양이 있습니다. 각 사양에 필요한 값(제한)을 지정하고 이진 통과/실패를 생성하는 수식이 포함된 열이 있습니다. 이 수식은 합격 수와 백분율의 파레토 그래프를 만드는 데 사용됩니다. 테스트 제한을 조정하기 위해 슬라이더 상자가 있는 대화형 Pareto 그래프를 만들고 이러한 제한을 변경하면 테스트를 통과/실패하는 항목의 양이 어떻게 변경되는지 확인하려고 합니다.
내 주요 두 가지 문제는 다음과 같습니다.
1) 테스트할 제품 유형이 여러 개 있습니다. 제품당 일관된 사양이 없기 때문에 이러한 사양을 목록에 삽입하고(첨부된 코드는 "사양"이 됨) 외부 데이터 테이블을 사용하여 원하는 제품에 대한 사양을 채울 계획입니다. 이것은 내가 도움이 필요한 것은 아니지만 변수를 직접 참조하지 않고 for 루프에 슬라이더 상자, 숫자 상자 등을 입력해야 하므로 고려해야 할 사항입니다.
2) 테스트 목적으로 수식을 업데이트할 수 있도록 변수 배열(사양 제한)이 필요합니다. 다시 이것은 for 루프에 있어야 합니다. 스크립트가 바로 지금 서 있기 때문에 합격/불합격 열에 대한 공식에서 사양 제한 값이 업데이트되지 않는 것으로 보입니다. 슬라이더 상자가 << inval 명령을 수신하고 그래프가 새로 고쳐지면 실제 통과/실패 열이 업데이트되지 않으므로 아무 일도 일어나지 않습니다. 현재 사양 제한을 저장하기 위해 연관 배열을 사용하고 있습니다. 이 작업을 수행하는 올바른 방법이 아닐 수 있습니다.
제가 사용하고 있는 샘플 데이터 테이블과 현재 스크립트를 첨부했습니다. 감사해요!
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));품질 및 프로세스 엔지니어링윈도우Re: 열 수식을 업데이트하기 위해 대화형 슬라이더 상자로 대화형 파레토 플롯 만들기사양 배열을 변경하는 것 같지 않습니다. 저도 처음에는 그렇게 생각했습니다. 그러나 V List Box 내부의 개별 상자를 참조할 수 있었습니다.항상 도움을 주셔서 감사합니다.
Re: 열 수식을 업데이트하기 위해 대화형 슬라이더 상자로 대화형 파레토 플롯 만들기감사해요! 좋은 예입니다.
Re: 열 수식을 업데이트하기 위해 대화형 슬라이더 상자로 대화형 파레토 플롯 만들기값을 변경할 때 사양 연관 배열에 저장해야 한다고 생각합니다. 그러나 숫자 편집 상자에 대한 참조를 목록이나 다른 연관 배열에 저장할 수도 있습니다. 또는 XPath(또는 트리 구조를 이동하는 다른 방법)를 사용하여 필요할 때 해당 참조를 가져올 수 있습니다.
Re: 열 수식을 업데이트하기 위해 대화형 슬라이더 상자로 대화형 파레토 플롯 만들기이 스크립트에서 또 다른 문제를 발견했고 여러분의 생각을 듣고 싶었습니다. 사양에 대한 숫자 편집 상자에 수동으로 숫자를 입력하면 사양을 다른 테이블에 저장할 수 있는 버튼을 추가하고 싶습니다. 버튼을 추가하는 것은 문제가 되지 않지만 숫자 편집 상자의 현재 값을 어떻게 참조할 수 있을지 모르겠습니다. 각 함수 다음에 V 목록 상자에 추가되고 해당 값이 수식 열에서 업데이트됩니다. 그러나 개별 숫자 편집 상자의 값을 참조하는 방법이나 해당 숫자를 저장하고 사양에 대한 참조와 함께 별도의 데이터 구조에 입력하는 기능이 없으면 이러한 새로운 제한을 스크립트에 저장할 수 있는 방법을 모르겠습니다. new_control H 목록 상자를 참조하면 for each 루프를 통과한 마지막 상자만 표시됩니다. 어떤 생각이나 제안이라도 좋을 것입니다.
Re: 열 수식을 업데이트하기 위해 대화형 슬라이더 상자로 대화형 파레토 플롯 만들기JMP 지원에 따르면 JMP 개발에서는 이를 의도하지 않은 동작으로 간주했으며 향후 릴리스에서 해결될 예정입니다.
Re: 열 수식을 업데이트하기 위해 대화형 슬라이더 상자로 대화형 파레토 플롯 만들기감사합니다. Range Slider Box 문제에 대해 다시 듣게 된다면 매우 관심을 가질 것입니다.
Re: 열 수식을 업데이트하기 위해 대화형 슬라이더 상자로 대화형 파레토 플롯 만들기Range Slider Box를 사용하겠지만 연관 배열과 목록을 네 번째 인수로 사용하면 제대로 작동하지 않는 것 같습니다(이에 대해 내일 지원 이메일을 보내겠습니다). 그래서 저는 슬라이더 상자로 돌아갈 것입니다.
이것은 이제 수식 표현식과 이중 슬라이더 상자를 사용하고 있습니다(창의 변수 이름에 의존하는 이와 같은 스크립트를 중단하기가 상당히 쉽기 때문에 이를 위해 네임스페이스 또는 다른 것을 추가해야 할 수 있습니다).
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);
);
문제의 예:
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: 열 수식을 업데이트하기 위해 대화형 슬라이더 상자로 대화형 파레토 플롯 만들기범위 슬라이더 상자의 인수를 처리하는 것보다 각 사양의 상한과 하한에 각각 하나씩 두 개의 슬라이더 상자를 갖는 것이 더 잘 작동한다고 생각하십니까? 어제 테스트한 결과 상자 유형의 인수에 대한 문서가 훨씬 적은 범위 슬라이더 상자에서 더 많은 문제가 발생했습니다. 범위 상자 문제를 해결할 것이라고 생각하지만 수식 부분을 복잡하게 만들 수 있습니다.
Re: 열 수식을 업데이트하기 위해 대화형 슬라이더 상자로 대화형 파레토 플롯 만들기수식에는 최소한 두 가지 옵션이 있습니다. 사양이 업데이트될 때마다 실행하는 수식의 값을 업데이트하기 위해 표현식을 사용하거나 사양 연관 배열을 사용하도록 수식을 수정할 수 있습니다.
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는 Slider Box보다 훨씬 복잡하므로 문제를 해결하는 것이 더 큰 과제입니다. 나는 Eval(EvalExpr())을 사용하지 않을 가능성이 높으며 Eval(Parse())를 사용하고 올바른 참조를 얻으려고 노력할 것입니다. Ranger Slider Box만 가지고 시작해서 작업을 마친 후 한 번에 하나씩 Number Edit Box를 추가했습니다(Range Slider Boxes의 네 번째 인수는 약간 버그가 있을 수 있습니다...).
Re: 열 수식을 업데이트하기 위해 대화형 슬라이더 상자로 대화형 파레토 플롯 만들기지난 며칠 동안 보내주신 도움에 진심으로 감사드립니다. 나는 이것과 다른 게시물에 대한 귀하의 솔루션을 통해 노력해 왔습니다. 목록에서 참조하는 연관 배열을 기반으로 열 수식을 업데이트합니다.
구문 분석 및 평가 표현식을 살펴보고 해결하려고 시도했으며 jsl에서 작동하는 방식을 이해하고 있습니다. 두 아이디어를 결합하는 데 문제가 있습니다. 사양을 저장하기 위해 연관 배열에 4개의 인덱스를 갖는 것이 더 낫다는 것을 깨달았습니다. "사양" => {<허용되는 최저 공차>, <사양의 하한>, <사양의 상한>, <최대 허용 공차>}. 구문 분석에 대한 귀하의 도움 덕분에 아래 스크립트는 이제 이 배열과 통과/실패 열을 생성하여 모든 사양이 충족되는지 확인합니다. 목표는 제품의 원하는 새 통과 수율을 얻기 위해 한계의 허용 오차를 최저 또는 최대 허용 오차까지 완화하고 위에서 수정한 대로 파레토 차트를 업데이트하는 것입니다. 한도에 대한 허용 오차를 완화하는 데 더 직관적일 것이므로 범위 슬라이더 상자를 구현하려고 시도했지만 문제가 있습니다. 또한 이전과 같이 파레토 플롯 자동 업데이트를 중단합니다.
한 가지 문제는 "f" 문자열이 초기에 정의되고 있기 때문에 통과 실패 열에 대한 수식 설정의 향후 실행을 위해 업데이트되지 않을 것이라고 생각합니다. 당신이 도울 수 있는 방법은 무엇이든 매우 감사할 것입니다.
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: 열 수식을 업데이트하기 위해 대화형 슬라이더 상자로 대화형 파레토 플롯 만들기매우 감사합니다! 이것은 JSL에서의 두 번째 주 스크립팅이며 귀하가 저를 얼마나 도왔는지 모릅니다.
Re: 열 수식을 업데이트하기 위해 대화형 슬라이더 상자로 대화형 파레토 플롯 만들기코드가 상당히 많이 수정되었으며 이것이 얼마나 신뢰할 수 있을지 100% 확신할 수는 없지만 set 함수와 자식/자매/부모를 사용하여 슬라이더 상자와 관련된 올바른 참조를 얻습니다. 또한 수식 값이 업데이트되면 파레토도 업데이트되는 것 같습니다. 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);
);
귀하의 코드에서 업데이트된 제한 연관 배열의 값을 얻기 위해 테스트하는 동안 ^가 누락된 것처럼 보입니다.