当前位置: 代码迷 >> Web前端 >> javafx饼图奇效
  详细解决方案

javafx饼图奇效

热度:588   发布时间:2013-03-25 15:43:04.0
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();
        }
    }
}

?

<script type="text/javascript" id="gdt-72058698036477044|discuz_22913820_001">
var TencentGDT = TencentGDT || [];
TencentGDT.push(['72058698036477044|discuz_22913820_001',960,90,'graphic']);
(function() { 
   var doc=document, h=doc.getElementsByTagName('head')[0], s=doc.createElement('script'); s.async=true; s.src='http://qzs.qq.com/qzone/biz/res/q.js'; h && h.insertBefore(s,h.firstChild)})();
</script>

?

  相关解决方案