for (int i = 0; i < chart.getCurrentStore().size(); i++) {
if (exclude.contains(i)) {
continue;
}
final Sprite sprite;
if (labels.get(i) != null) {
sprite = labels.get(i);
sprite.setHidden(false);
} else {
sprite = labelConfig.getSpriteConfig().copy();
labels.put(i, sprite);
chart.addSprite(sprite);
}
setLabelText(sprite, i);
PrecisePoint middle = middlePoints.get(i);
double x = middle.getX() - center.getX();
double y = middle.getY() - center.getY();
double rho = 1;
double theta = Math.atan2(y, x == 0 ? 1 : x);
double degrees = Math.toDegrees(theta);
LabelPosition labelPosition = labelConfig.getLabelPosition();
if (labelPosition == LabelPosition.OUTSIDE) {
Slice slice = slices.get(i);
rho = slice.getEndRho() + 20;
double rhoCenter = (slice.endRho + slice.startRho) / 2.0 + (slice.endRho - slice.startRho) / 3.0;
PrecisePoint calloutPoint = new PrecisePoint(rho * Math.cos(theta) + center.getX(), rho * Math.sin(theta)
+ center.getY());
x = rhoCenter * Math.cos(theta);
y = rhoCenter * Math.sin(theta);
final PathSprite line;
if (calloutLines.get(i) != null) {
line = calloutLines.get(i);
line.setHidden(false);
} else {
line = new PathSprite();
line.setStrokeWidth(1);
line.setStroke(RGB.BLACK);
line.setFill(Color.NONE);
calloutLines.put(i, line);
chart.addSprite(line);
}
final RectangleSprite box;
if (calloutBoxes.get(i) != null) {
box = calloutBoxes.get(i);
box.setHidden(false);
} else {
box = new RectangleSprite();
box.setStroke(RGB.BLACK);
box.setStrokeWidth(1);
box.setFill(Color.NONE);
calloutBoxes.put(i, box);
chart.addSprite(box);
}
sprite.redraw();
PreciseRectangle bbox = sprite.getBBox();
List<PathCommand> commands = new ArrayList<PathCommand>();
commands.add(new MoveTo(x + center.getX(), y + center.getY()));
commands.add(new LineTo(calloutPoint.getX(), calloutPoint.getY()));
commands.add(new LineTo(x > 0 ? 10 : -10, 0, true));
PreciseRectangle rect = new PreciseRectangle(calloutPoint.getX() + (x > 0 ? 10 : -(bbox.getWidth() + 30)),
calloutPoint.getY() + (y > 0 ? (-(bbox.getHeight() - 5)) : (-(bbox.getHeight() - 5))),
bbox.getWidth() + 20, bbox.getHeight() + 20);
PrecisePoint labelPoint = new PrecisePoint(calloutPoint.getX() + (x > 0 ? 20 : -(20 + bbox.getWidth())),
calloutPoint.getY() + (y > 0 ? -bbox.getHeight() / 4.0 : -bbox.getHeight() / 4.0));
if (chart.isAnimated() && line.size() > 0 && !Double.isNaN(box.getX()) && sprite.getTranslation() != null) {
DrawFx.createCommandsAnimator(line, commands).run(chart.getAnimationDuration(), chart.getAnimationEasing());
DrawFx.createRectangleAnimator(box, rect).run(chart.getAnimationDuration(), chart.getAnimationEasing());
DrawFx.createTranslationAnimator(sprite, labelPoint.getX(), labelPoint.getY()).run(
chart.getAnimationDuration(), chart.getAnimationEasing());
} else {
line.setCommands(commands);
line.redraw();
box.setX(rect.getX());
box.setY(rect.getY());
box.setWidth(rect.getWidth());
box.setHeight(rect.getHeight());
box.redraw();
sprite.setTranslation(labelPoint.getX(), labelPoint.getY());
sprite.redraw();
}
} else if (labelPosition == LabelPosition.END) {
rho = Math.sqrt(x * x + y * y) * 2.0;
x = rho * Math.cos(theta) + center.getX();
y = rho * Math.sin(theta) + center.getY();
if (chart.isAnimated() && sprite.getTranslation() != null) {
DrawFx.createTranslationAnimator(sprite, x, y).run(chart.getAnimationDuration(), chart.getAnimationEasing());
} else {
sprite.setTranslation(x, y);
}
labelPoints.put(i, new PrecisePoint(x, y));
} else if (labelPosition == LabelPosition.START) {
degrees = fixAngle(degrees);
if (degrees > 90 && degrees < 270) {
degrees += 180;
}
if (!Double.isNaN(previousDegrees) && Math.abs(previousDegrees - degrees) > 180) {
if (degrees > previousDegrees) {
degrees -= 360;
} else {
degrees += 360;
}
degrees %= 360;
} else {
degrees = fixAngle(degrees);
}
if (labelConfig.isLabelContrast()) {
final Sprite back = sprites.get(i);
if (chart.isAnimated()) {
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
setLabelContrast(sprite, labelConfig, back);