Comment définir uniformément la position de l'étiquette au-dessus ou en dessous du point de données
Analyse et modélisation des données de baseRe : Comment définir uniformément la position de l'étiquette au-dessus ou en dessous du point de donnéesGraphique factice avec lequel jouer :

Names Default to Here(1);
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
Data Table( "Big Class" ) << Select All Rows << Label;
:weight << Label( 1 );
:name << Label( 0 );
Graph Builder(
Size( 437, 428 ),
Summary Statistic( "Median" ),
Graph Spacing( 4 ),
Variables( X( :name ), Y( :weight ) ),
Elements( Points( X, Y, Legend( 4 ) ) ),
Local Data Filter(
Add Filter(
columns( :name ),
Where( :name == {"AMY", "BARBARA", "CAROL", "CHRIS", "CLAY", "DANNY"} ),
Display( :name, N Items( 15 ), Find( Set Text( "" ) ) )
)
)
);
Re : Comment définir uniformément la position de l'étiquette au-dessus ou en dessous du point de donnéesUne approche consiste à utiliser JSL : il suffit d'ajouter les décalages « manuellement » pour toutes les étiquettes, via une liste :

// create a list of identical offsets
labels = As list(Index(0,10))[1]; // surprise: the fist index is 0!
offset Expr = Expr(Label Offset());
offsets= For Each ({label}, labels, Insert Into(offset Expr,Eval List({label,0.,-20}))); // vertical offset: -20
// send the command to the Point plot
mySeg = current report()[FrameBox(1)] << find seg(MarkerSeg);
Eval (Eval Expr(mySeg << Expr(Name expr(offset Expr) )))
Re : Comment définir uniformément la position de l'étiquette au-dessus ou en dessous du point de donnéesJe ne suis pas sûr que vous puissiez facilement ajuster les décalages d'étiquettes sans script.
Vous trouverez ci-dessous un exemple très rapide de la manière dont il pourrait être possible de le faire avec JSL
Names Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
Size(525, 512),
Show Control Panel(0),
Variables(X(:age), Y(:height)),
Elements(
Points(X, Y, Legend(3), Summary Statistic("Mean"), Label("Label by Value"))
)
);
frame = Report(gb)[FrameBox(1)];
seg = (frame << FindSeg(Marker Seg(1)));
For(i = 0, i <= N Items(seg << get markers), i++,
Eval(EvalExpr(
seg << Label Offset(Expr(Eval List({i, -5, -5})));
));
);
Re : Comment définir uniformément la position de l'étiquette au-dessus ou en dessous du point de donnéesRésolu, merci !

dt3 = Data Table("光伏供应链价格汇总");
obj1 = dt3 << Graph Builder(
Size(1476, 745),
Show Control Panel(0),
Legend Position("Inside Right"),
Fit to Window("Off"),
Variables(X(:日期), Y(:单价), Group X(:产品), Group Y(:型号)),
Elements(
Points(X, Y, Legend(5), Label("Label by Value"), Label Format("Fixed Dec", 7, 2)),
Smoother(X, Y, Legend(6))
),
SendToReport(
Dispatch({}, "日期", ScaleBox,
{Min(min_date - 86400), Max(max_date + 86400), Interval("Day"), Inc(1),
Minor Ticks(0), Label Row(
{Label Orientation("Vertical"), Show Major Grid(0), Show Minor Grid(0)}
)}
),
Dispatch({}, "单价", ScaleBox,
{Min(0.2), Max(2.5), Inc(0.5), Minor Ticks(1),
Label Row({Show Major Grid(0), Show Minor Grid(0)})}
)
)
);
Wait(1);
excluded_rows = dt3 << Get Excluded Rows; //获取排除行矩阵
mm = N Row(excluded_rows); //获取排除行数
nn = (N Row(dt3) - mm) / 7;
report = obj1 << Report;
indices = {4, 5, 8, 9, 10, 20, 21};
For(idx = 1, idx <= N Items(indices), idx++,
i = indices[idx];
frame = report[FrameBox(i)];
For(j = 0, j <= nn, j++,
seg = frame << Find Seg(Marker Seg(1));
seg << Label Offset({j, -10, -10});
);
); Edit (jthi): Added JSL formatting
Re : Comment définir uniformément la position de l'étiquette au-dessus ou en dessous du point de donnéesEn guise d'alternative, vous pouvez utiliser une approche plus automatisée (par exemple, si vous ne souhaitez pas saisir manuellement les indices de framebox ou si vous utilisez Overlay et qu'il y a plus de segments) :
- trouver toutes les lframeboxes
- pour chaque framebox, recherchez tous les segments
- pour chaque segment, trouvez tous les marqueurs
- appliquer le décalage
Names Default to Here(1);
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
Data Table( "Big Class" ) << Select All Rows << Label;
:weight << Label( 1 );
:name << Label( 0 );
gb = dt << Graph Builder(
Size( 437, 413 ),
Summary Statistic( "Median" ),
Graph Spacing( 4 ),
Variables( X( :height ), Y( :weight ), Wrap( :age ), Overlay( :sex ) ),
Elements( Points( X, Y ), Smoother( X, Y, Legend( 2 ) ) )
);
fbs = Current Report() << xpath( "//FrameBox" );
For Each( {frame}, fbs,
segs = (frame << FindSegs);
For Each( {seg}, segs,
Try( // skip non-Marker-segs
markers = seg << get markers;
For Each( {x, i}, markers,
seg << Label Offset( {i-1, -10, -10} )
);
);
);
);
Re : Comment définir uniformément la position de l'étiquette au-dessus ou en dessous du point de donnéesNote à moi-même :
Cool, aucune manipulation d'expression n'est nécessaire pour obtenir le bon "i-1" dans
seg << Label Offset( {i-1, -10, -10} )
Le segment reçoit le message - voit « i » et le recherche : Eval(i) - Similaire au nom de la colonne dans la nouvelle colonne (nom de la colonne)
D'autre part, la gestion des expressions est nécessaire pour
Eval (Eval Expr(mySeg << Expr(Name expr(offset Expr) )))
Avec
mySeg << offset Expr
on obtient le message d'erreur :

Le Seg vérifie simplement la liste des messages acceptés et l'offset Expr n'est pas répertorié.
Le nom Expr(offset Expr) n'est pas vérifié
- et Eval(décalage Expr) (comme pour i à l'intérieur du message) n'aurait pas de sens.