No conozco una forma de agregar fácilmente esas líneas al gráfico circular. Puede calcular esas líneas y agregarlas con un script o realizar algunos cálculos y establecer las compensaciones mediante un script.
Lo más probable es que use algo más que un gráfico circular (mucho más fácil que comenzar a crear secuencias de comandos de segmentos circulares, incluso la documentación en Scripting Index es incorrecta en la mayoría de los casos para eso...), pero esto parece un buen desafío, así que lo haré. Intente escribir algún tipo de guión para esto.
Lástima que no puedas deshacerte del gráfico circular (la forma más utilizada en exceso y generalmente mala de visualizar cualquier cosa). A continuación se muestra un script que podría dar una idea de lo que podría hacer; los cálculos definitivamente no son óptimos, pero podrían funcionar (realmente ya no recuerdo el círculo unitario ni la trigonometría).
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));
));
);
por defecto

UBICACIÓN_AJUSTADA = 0,8

UBICACIÓN_AJUSTADA = 1.1

Esto podría convertirse en una función que podría agregar líneas a las etiquetas.
Haciendo eco de los otros comentarios, no utilice gráficos circulares; soy más enfático que otros en este punto. Pero aquí hay una muy buena presentación que ilustra por qué siempre es mejor usar un gráfico de barras (o alternativas similares) que un gráfico circular: https://speakerdeck.com/cherdarchuk/data-looks-better-naked-pie-chart- edición . Vería esto como una oportunidad para educar a su supervisor.
Ejemplo de cómo se podrían agregar líneas
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)
);
);
));
);
