Example how lines could be added
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)
);
);
));
);
-Jarmo