javafx饼图特效

功能说明: 1、当鼠标移入饼图块时,该块位置发生偏移。

2、鼠标离开后,该块回复到原来位置。

原文地址

先看效果图:

piechart

实现技巧: 1、计算鼠标所在块的偏移角度。 从上图中可以看出:在javafx中,第一个数据块的位置从0开始,按逆时针方向一次排列。 因此数据块的偏移角度为,它之前所有数据块的角度之和,再加上本身所占角度的一半。 2、数据块角度的计算。 可以根据数据块所占数据的百分比计算对应的角度。 参考以下代码:

private static double calcAngle(PieChart.Data d) {
	        double total = 0;
		for (PieChart.Data tmp : d.getChart().getData()) {
			total += tmp.getPieValue();
		}
		return 360 * (d.getPieValue() / total);
	}
3、注意y坐标的计算,由于fx的y轴和直角坐标系相反,所以移动y坐标要取反。 全部源码:
public class PieChartSample extends Application {

	@Override
	public void start(Stage primaryStage) {
		BorderPane p = new BorderPane();

		ObservableList pieChartData = FXCollections
				.observableArrayList(new PieChart.Data("Austria", 8_430_558),
						new PieChart.Data("Swiss", 7_701_900),
						new PieChart.Data("Germany", 81_882_342),
						new PieChart.Data("France", 62_793_432),
						new PieChart.Data("Spain", 46_661_950),
						new PieChart.Data("Italy", 60_245_846));
		PieChart chart = new PieChart(pieChartData);
		// chart.setStyle("-fx-pie-label-visible: false");

		for (PieChart.Data d : pieChartData) {
			d.getNode().setOnMouseEntered(new MouseHoverAnimation(d, chart));
			d.getNode().setOnMouseExited(new MouseExitAnimation());
		}

		chart.setClockwise(false);
		p.setCenter(chart);

		Scene s = new Scene(p);
		primaryStage.setScene(s);
		primaryStage.setWidth(600);
		primaryStage.setHeight(600);
		primaryStage.setTitle("动态饼图");
		primaryStage.show();
	}

	public static void main(String[] args) {
		launch(args);
	}

	static class MouseHoverAnimation implements EventHandler {
		static final Duration ANIMATION_DURATION = new Duration(500);
		static final double ANIMATION_DISTANCE = 0.15;
		private double cos;
		private double sin;
		private PieChart chart;

		public MouseHoverAnimation(PieChart.Data d, PieChart chart) {
			this.chart = chart;
			double start = 0;
			double angle = calcAngle(d);
			for (PieChart.Data tmp : chart.getData()) {
				if (tmp == d) {
					break;
				}
				start += calcAngle(tmp);
			}

			cos = Math.cos(Math.toRadians(start + angle / 2));
			sin = Math.sin(Math.toRadians(start + angle / 2));
		}

		@Override
		public void handle(MouseEvent arg0) {
			Node n = (Node) arg0.getSource();
			double minX = Double.MAX_VALUE;
			double maxX = Double.MAX_VALUE * -1;

			for (PieChart.Data d : chart.getData()) {
				minX = Math
				.min(minX, d.getNode().getBoundsInParent().getMinX());
				maxX = Math
				.max(maxX, d.getNode().getBoundsInParent().getMaxX());
			}

			double radius = maxX - minX;
			System.out.println("cos:" + cos);
			System.out.println("sin" + sin);
			TranslateTransitionBuilder.create()
					.toX((radius * ANIMATION_DISTANCE) * cos)
					.toY((radius * ANIMATION_DISTANCE) * (-sin))
					.duration(ANIMATION_DURATION).node(n).build().play();
		}

		private static double calcAngle(PieChart.Data d) {
			double total = 0;
			for (PieChart.Data tmp : d.getChart().getData()) {
				total += tmp.getPieValue();
			}
			return 360 * (d.getPieValue() / total);
		}
	}

	static class MouseExitAnimation implements EventHandler {
		@Override
		public void handle(MouseEvent event) {
			TranslateTransitionBuilder.create().toX(0).toY(0)
			.duration(new Duration(500)).node((Node) event.getSource())
			.build().play();
		}
	}
}

你可能感兴趣的:(JavaFX,piechart)