Non conosco un modo per aggiungere facilmente tali linee al grafico a torta. Potresti calcolare quelle righe e aggiungerle con uno script o eseguire alcuni calcoli e impostare gli offset tramite script.
Molto probabilmente utilizzerei qualcos'altro rispetto al grafico a torta (molto più semplice che iniziare a creare script di segmenti a torta, anche la documentazione in Scripting Index è sbagliata nella maggior parte dei casi per quello...), ma sembra una bella sfida, quindi lo farò prova a scrivere una sorta di script per questo.
Peccato che non sia possibile eliminare il grafico a torta (il modo più abusato e solitamente pessimo per visualizzare qualsiasi cosa). Di seguito è riportato lo script che potrebbe dare un'idea di cosa potresti fare, i calcoli sicuramente non sono ottimali ma potrebbero funzionare (non ricordo più il cerchio unitario e la trigonometria)
Names Default To Here(1);
ADJUSTED_LOCATION = 0.8 ; // default is 1
dt = open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
Variables(X(:age), Y(:height)),
Elements(Pie(X, Y, Legend(2), Summary Statistic("Sum"), Label("Label by Value")))
);
fb = Report(gb)[FrameBox(1)];
pie = fb << Find Seg("Pie Seg");
{x_origo, y_origo} = pie << Get Origin;
radius = pie << Get Radius;
Summarize(dt, groups = By(:age), sums = Sum(:height)); // we must know summary statistic used in pie chart
r_sections = Reverse((sums / Sum(sums)) * 2 * Pi());
angles = {};
For Each({section, idx}, r_sections,
angle = (section + Pi()) / 2;
If(idx > 1,
angle = angle + Sum(r_sections[1::idx - 1]);
);
Insert Into(angles, angle);
);
label_locations = {};
For Each({angle, idx}, angles,
i = N Items(angles) - idx;
xcoord = x_origo + ADJUSTED_LOCATION * Cos(angle);
ycoord = y_origo + ADJUSTED_LOCATION * Sin(angle);
location = Eval List({i, xcoord, ycoord});
Insert Into(label_locations, Eval List({location}));
);
For Each({location}, label_locations,
Eval(EvalExpr(
pie << Set Label Offset(Expr(location));
));
);
predefinito

POSIZIONE_REGOLATA = 0,8

POSIZIONE_REGOLATA = 1.1

Questo potrebbe essere trasformato in una funzione in grado di aggiungere linee alle etichette.
Facendo eco agli altri commenti, non utilizzare grafici a torta: sono più enfatico di altri su questo punto. Ma ecco un'ottima presentazione che illustra perché è sempre meglio utilizzare un grafico a barre (o alternative simili) rispetto a un grafico a torta: https://speakerdeck.com/cherdarchuk/data-looks-better-naked-pie-chart- edizione . Considererei questa un'opportunità per istruire il tuo supervisore.
Esempio di come potrebbero essere aggiunte le linee
Names Default To Here(1);
ADJUSTED_LOCATION = 1 ; // default is 1
dt = open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
Variables(X(:age), Y(:height)),
Elements(Pie(X, Y, Legend(2), Summary Statistic("Sum"), Label("Label by Value")))
);
calculate_pie_graph_angles = Function({gb}, {Default Local},
dt = gb << Get Data Table;
// Get X and Y columns (doesn't currently support Overlay)
vars = gb << Get Variables;
xcol = Empty();
ycol = Empty();
For Each({var}, vars,
role = var["Role"];
If(role == "X",
xcol = Arg(var, 1) << get name; // I don't use references
, role == "Y",
ycol = Arg(var, 1) << get name; // I don't use references
);
);
// Get summary statistic
elements = gb << Get Elements(1, 1);
summary_stat = Try(elements[1]["Summary Statistic"], "Mean"); // We assume Mean is the default one
// Calculate groups and segments
// I'm lazy and use Evil Parse here
stat = Eval Insert("^summary_stat^(Eval(ycol))");
Eval(EvalExpr(
dt_summary = dt << Summary(
Group(Eval(xcol)),
Expr(Parse(stat)),
Freq("None"),
Weight("None"),
statistics column name format("column"),
Link to original data table(0),
invisible
);
));
groups = dt_summary[0, 1]; // 2 is N Rows
stats = dt_summary[0, 3];
Close(dt_summary, no save);
// calculate segments
r_sections = Reverse((stats / Sum(stats)) * 2 * Pi());
angles = {};
For Each({section, idx}, r_sections,
angle = (section + Pi()) / 2;
If(idx > 1,
angle = angle + Sum(r_sections[1::idx - 1]);
);
Insert Into(angles, angle);
);
Return(Reverse(angles));
);
get_segment_locations = Function({pie, angles, radius = 1}, {Default Local},
{x_origo, y_origo} = pie << Get Origin;
pie_radius = pie << Get Radius;
label_locations = {};
For Each({angle, idx}, angles,
i = idx - 1;
xcoord = x_origo + radius * Cos(angle);
ycoord = y_origo + radius * Sin(angle);
location = Eval List({i, xcoord, ycoord});
Insert Into(label_locations, Eval List({location}));
);
return(label_locations);
);
fb = Report(gb)[FrameBox(1)];
pie = fb << Find Seg("Pie Seg");
angles = calculate_pie_graph_angles(gb);
offsets1 = get_segment_locations(pie, angles, 1.05);
For Each({location}, offsets,
Eval(EvalExpr(
pie << Set Label Offset(Expr(location));
));
);
offsets2 = get_segment_locations(pie, angles, 0.9);
offsets3 = get_segment_locations(pie, angles, 1.02);
For Each({{start, end}}, Across(offsets2, offsets3),
Eval(EvalExpr(
x = start[2] || end[2];
y = start[3] || end[3];
fb << Add Graphics Script(
Line(
Expr(x), Expr(y)
);
);
));
);
