Existe-t-il un moyen de rendre le gestionnaire d'état de ligne moins lent?Est-il possible de faire en sorte que le gestionnaire d'état de ligne ne se déclenche que lorsque la souris est levée ou après la fin d'un événement de sélection ?
L'événement en temps réel entraîne un décalage de la sélection par glisser-déposer de mon graphique et rend l'expérience utilisateur désagréable.
Je suis allé jusqu'à réécrire complètement un événement de sélection dans le piège à souris, mais j'ai du mal à l'appliquer aux histogrammes et je n'aime même pas la façon dont il fonctionne non plus.
Cela répondrait à mes besoins si je pouvais utiliser la boîte de sélection l'outil "Flèche (A)" en même temps que la fonction de piège à souris afin que je puisse simplement récupérer mes lignes sélectionnées à la fin de l'événement moustrap au lieu de tirer un million événements tout en faisant glisser la souris.
Les trucs que je n'aime pas :
Plus vous déplacez la souris vers le bas tout en sélectionnant, de plus en plus de scripts graphiques inutiles s'entassent dans le graphique.
J'aimerais n'en avoir qu'un et un seul. J'ai ajouté une boucle à la fin pour les tuer tous hors du graphique, c'est pourquoi ils semblent "disparaître".
Je pourrais simplement les laisser là, mais ils ajoutent du bruit visuel au graphique et je ne sais pas ce qui se passe lorsque vous en obtenez trop.
Edit : lorsque vous en avez trop, ils commencent à être à la traîne. Il peut être plus rapide de détruire le graphique et de le reconstruire que de boucler pour supprimer les scripts graphiques restants. Edit 2 : Il est beaucoup plus rapide de détruire le graphique et de le recréer, mais le zoom est ensuite réinitialisé. Je devrai donc capturer davantage d'informations sur l'état du graphique afin de pouvoir le reconstruire pour masquer l'actualisation à l'utilisateur.
J'ai fait fonctionner le truc Shift / control click, c'est juste trop hacky pour la production. Surtout le clic de contrôle, il a ce long temps de latence après que vous ayez levé la souris et que la boîte de sélection poursuive la souris même lorsque vous avez déjà relâché le bouton, je pense que jmp gère un tas d'événements de glissement périmés entre-temps avant qu'il ne cesse de bouger.
Ou écartez simplement toute cette aventure et trouvez un moyen d'avoir un gestionnaire d'état de ligne qui se déclenche avec la souris (ce serait l'idéal).
Exemples auxquels j'ai emprunté du code :
http://www.pega-analytics.co.uk/blog/segmented-regression/
https://community.jmp.com/t5/Discussions/Quick-way-to-compare-two-lists-and-identify-the-uncommon/td-p/5811
Names Default To Here(1);
dt = open("$sample_data\Iris.jmp");
MY_GRAPH_BUILDER = Graph Builder(
Size( 531, 456 ),
Show Control Panel( 0 ),
Variables( X( :Sepal length ), Y( :Sepal width ) ),
Elements( Points( X, Y, Legend( 3 ) ) ),
SendToReport(
Dispatch({},"Graph Builder",
FrameBox,
{Add Graphics Script(MouseTrap( MouseDown(x,y), MouseUp(x,y)))}
),
),
);
//MOUSE STUFF
get_box_dims = Function({firstX,lastX,firstY,lastY},
show("get_box_dims");
//show(firstX,lastX,firstY,lastY,modifier_key);
If (lastX>firstX,
max_x = lastX; min_x =firstX,
max_x = firstX;min_x =lastX,
);
If (lastY>firstY,
max_y = lastY; min_y =firstY,
max_y = firstY;min_y =lastY,
);
show(min_x,min_y,max_x,max_y);
evallist({min_x,max_x,min_y,max_y});
);
do_normal_select = Function({select_range},
show("normal_select");
dt << Select Where(
AsColumn(:Sepal length) >= select_range[1]
& AsColumn(:Sepal length) <= select_range[2]
& AsColumn(:Sepal width) >= select_range[3]
& AsColumn(:Sepal width) <= select_range[4]
);
);
do_shift_select = Function({select_range},
show("shift_select");
new_rows_to_add = as list(dt << Get Rows Where(
AsColumn(:Sepal length) >= select_range[1]
& AsColumn(:Sepal length) <= select_range[2]
& AsColumn(:Sepal width) >= select_range[3]
& AsColumn(:Sepal width) <= select_range[4]
)
);
if (length(new_rows_to_add) > 0,
curr_rows = as list(dt << Get Selected Rows);
rows_to_select = curr_rows || new_rows_to_add;
dt << Select Rows( rows_to_select);
);
show(new_rows_to_add,length(new_rows_to_add));
);
do_ctrl_select = Function({select_range},
show("ctrl_select");
new_rows_to_subtract = associativearray(as list(dt << Get Rows Where(
AsColumn(:Sepal length) >= select_range[1]
& AsColumn(:Sepal length) <= select_range[2]
& AsColumn(:Sepal width) >= select_range[3]
& AsColumn(:Sepal width) <= select_range[4]
)
));
if (length(new_rows_to_subtract) > 0,
curr_rows = associativearray(as list(dt << Get Selected Rows));
show("current_rows_selected",length(curr_rows));
show("number_rows_to_subtract",length(new_rows_to_subtract));
intersection=curr_rows;intersection<<INTERSECT></INTERSECT>
Fusion et nettoyage des donnéesIngénierie de la qualité et des procédésles fenêtresRe : Existe-t-il un moyen de rendre le gestionnaire d'état de ligne moins lent ?Je doute que cela soit très bien documenté, nulle part... @Audrey_Shul
MouseTrap et la fonction Handle avec un comportement similaire ne sont pas exécutés en ligne comme Rect() et l'autre normal les fonctions de script graphique comme Rect().
Lorsque le flux de contrôle dans votre script graphique passe par Handle() ou MouseTrap(), la fonction ne fait rien dans le cas de MouseTrap ou dessine un petit rectangle à la position de la poignée pour Handle. Lorsque vous cliquez sur un graphique avec un script graphique, JMP recherche dans le script les fonctions MouseTrap ou Handle et les appelle, dans l'ordre, jusqu'à ce que l'une d'entre elles prend le point.
Ainsi, dans votre exemple, jusqu'à ce que vous cliquiez, le code qui définit x0 n'a jamais été exécuté. Mais le code Rect s'exécutera.
Je crois que, sans l'essayer, vous pourriez avoir plusieurs Handles() suivis d'un MouseTrap(), et JMP prendrait le point de clic et le transmettrait à chaque Handle() jusqu'à ce que l'un d'eux le prenne, ou le MouseTrap() qui prenez-le toujours.
Rect() peut être utilisé dans une boucle for pour dessiner plusieurs rectangles. Vous ne pouvez pas créer plusieurs poignées en mettant Handle(...) dans une boucle. Si vous deviez créer un nombre variable de poignées, vous pouvez soit utiliser MouseTrap() et une liste d'emplacements x,y à rechercher, soit utiliser une forme de manipulation d'expression pour créer plusieurs appels Handle().
Cela signifie également que MouseTrap/Handle doit se trouver dans le script graphique, et non dans une fonction utilisateur appelée par le script graphique. Rect, d'autre part, peut être dans une fonction utilisateur appelée à partir du script graphique.
Si vous mettez deux MouseTraps dans un script graphique, je pense que le 2ème ne pourra jamais être atteint car le 1er acceptera toujours le clic.
New Window( "Example",
exx = 20,
exy = 50;
Graph Box(
Frame Size( 200, 200 ),
If( 0, // note that it still works
Mousetrap(
exx = x;
exy = y;
)
);
Circle( {0, 0}, Sqrt( exx * exx + exy * exy ) );
);
);Re : Existe-t-il un moyen de rendre le gestionnaire d'état de ligne moins lent ?Cela a fait une grande amélioration. Merci!
Re : Existe-t-il un moyen de rendre le gestionnaire d'état de ligne moins lent ?Essayé cela mais obtenir.
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
Size(529, 457),
Show Control Panel(0),
Variables(X(:weight), Y(:height)),
Elements(Points(X, Y, Legend(3)))
);
fb = Report(gb)[FrameBox(1)];
i = 0;
fb << Add Graphics Script(
Mousetrap(
If(i == 0,
x0 = x; y0 = y;
);
exx = x; exy = y;
i++;
,
i = 0;
show("RELEASED");
);
Rect(x0, y0, exx, exy);
);
Nom non résolu : x0 dans l'accès ou l'évaluation de 'x0' , x0/*###*/
à la ligne 24 dans le script 2.jsl
Je ne suis pas très familier avec la souricière(); fonction, n'a-t-il pas besoin de 2x fonctions internes ?
MouseTrap( MouseDown(x,y), MouseUp(x,y)));
Je veux comprendre cela cependant parce que je pense qu'une grande partie de mon retard provient de la diffusion des points dans des listes 2x, puis de la sélection du premier et du dernier de ces listes.
Re : Existe-t-il un moyen de rendre le gestionnaire d'état de ligne moins lent ?J'utiliserais simplement le bouton (c'est ce que j'ai fait), mais peut-être que quelque chose pourrait être construit avec MouseTrap (ou MouseBox ?)
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
Size(529, 457),
Show Control Panel(0),
Variables(X(:weight), Y(:height)),
Elements(Points(X, Y, Legend(3)))
);
fb = Report(gb)[FrameBox(1)];
i = 0;
fb << Add Graphics Script(
Mousetrap(
If(i == 0,
x0 = x; y0 = y;
);
exx = x; exy = y;
i++;
,
i = 0;
show("RELEASED");
);
Rect(x0, y0, exx, exy);
);Re : Existe-t-il un moyen de rendre le gestionnaire d'état de ligne moins lent ?C'est super lag.
J'essaie de diffuser des requêtes http depuis JSL vers un serveur Web pour générer un tableau de bord en temps réel en direct basé sur des sélections jmp. Je pensais pouvoir le faire avec le gestionnaire d'état de ligne, mais il est tellement lent qu'il tue l'expérience utilisateur. Une fois que vous ramassez plus de 500 points, les performances chutent.
Ce que j'ai en ce moment, c'est faire une sélection sur le graphique, cliquer sur un bouton, puis le rapport http s'affiche.
Je veux me débarrasser de ce clic de bouton.
Donc, ce que j'essaie de faire maintenant, c'est d'envoyer un lot de données à mon serveur http pour générer mon tableau de bord. Tout comme un événement javascript.
Re : Existe-t-il un moyen de rendre le gestionnaire d'état de ligne moins lent ?Pour les multiples scripts, vous pouvez tout faire dans un seul script et utiliser une valeur manquante dans firstX pour le désactiver. Voici un hack q & d pour n'ajouter qu'une copie d'un deuxième script, ou rafraîchir le graphique s'il n'est pas ajouté, et toujours utiliser votre logique pour le supprimer une fois terminé.
MouseDown = Function( {px, py},
Insert Into( lstX, pX );
Insert Into( lstY, pY );
firstX = lstX[1];
lastX = lstX[N Items( lstX )];
firstY = lstY[1];
lastY = lstY[N Items( lstY )];
// quick and dirty hack to only add the script once
If( N Items( ((Report( MY_GRAPH_BUILDER )[FrameBox( 1 )]) << XPath( "//TopSeg" )) << get script ) < 2,
(Report( MY_GRAPH_BUILDER )[FrameBox( 1 )]) << Add Graphics Script(
Line Style( "solid" );
Fill Color( "BlueGreen" );
Transparency( 0.3 );
Rect( firstX, firstY, lastX, lastY, 1 );
);
, // ELSE make sure to redraw using new values (might work without this)
(Report( MY_GRAPH_BUILDER )[FrameBox( 1 )]) << inval << updatewindow;
);
);
Re : Existe-t-il un moyen de rendre le gestionnaire d'état de ligne moins lent ?Simplifiez la sélectionner où expression autant que possible. Je ne vois pas le décalage pour 150 lignes, mais pour 100 000 lignes, c'est plutôt mauvais. Cela me procure une amélioration 10X :
do_normal_select = Function( {select_range},
{start, stop, sr1, sr2, sr3, sr4},
//show("normal_select");
start = HP Time();
sr1 = select_range[1];
sr2 = select_range[2];
sr3 = select_range[3];
sr4 = select_range[4];
dt << Select Where( sr1 <= :Sepal length <= sr2 & sr3 <= :Sepal width <= sr4 );
// dt << Select Where(
// AsColumn(:Sepal length) >= select_range[1]
// & AsColumn(:Sepal length) <= select_range[2]
// & AsColumn(:Sepal width) >= select_range[3]
// & AsColumn(:Sepal width) <= select_range[4]
// );
stop = HP Time();
Write( Eval Insert( "\!nselect where ^stop-start^" ) );
);
Il y a trois changements : suppression de AsColumn, suppression de l'indice de la boucle implicite et chaînage de l'opérateur de comparaison.
@Audrey_Shul - J'aimerais que le profileur travaille avec ça. Le profileur s'arrête avant que la fenêtre ne s'ouvre, donc je n'arrive jamais à étudier le temps passé dans la sélection interactive.
Re : Existe-t-il un moyen de rendre le gestionnaire d'état de ligne moins lent ?Qu'essayez-vous de faire en faisant glisser la zone de cadre du générateur de graphiques ? S'il s'agit de sélectionner des lignes puis de répondre, un gestionnaire d'état de ligne associé à la table de données devrait suffire.
Re : Existe-t-il un moyen de rendre le gestionnaire d'état de ligne moins lent ?La suppression des impressions devrait le rendre plus rapide, le masquage de la table de données peut également aider un peu. Vérifier également qu'il y a un changement "réel" effectué entre deux événements peut aider, mais selon l'application, cela peut être difficile à vérifier.
Re : Existe-t-il un moyen de rendre le gestionnaire d'état de ligne moins lent ?Oui, ils ont toujours été difficiles à utiliser.
J'ai besoin de quelque chose pour obtenir une réponse en temps réel, j'espère que le gestionnaire d'état de ligne est lent car il essayait d'écrire sur la console et qu'il pourrait être plus rapide pour d'autres tâches.
La réécriture des critères de sélection fonctionne assez bien pour mon nuage de points bien que ce soit un peu bizarre, mes histogrammes de distribution, par contre, ne semblent pas l'aimer.
Re : Existe-t-il un moyen de rendre le gestionnaire d'état de ligne moins lent ?Les différents gestionnaires d'état sont un gâchis dans JMP et devraient être, à mon avis, évités si possible. J'ai créé un élément de liste de souhaits pour qu'ils soient améliorés Améliorer les gestionnaires d'état de JMP (étiquette de survol, gestionnaire d'état de ligne, gestionnaire d'état de filtre, planificateur, ...)