├── .classpath
├── .github
└── FUNDING.yml
├── .project
├── .settings
├── org.eclipse.jdt.core.prefs
└── org.eclipse.m2e.core.prefs
├── .travis.yml
├── LICENSE.txt
├── README.md
├── pom.xml
└── src
└── main
└── java
└── com
└── github
└── javafx
└── charts
└── zooming
├── BarChartSample.java
├── LineChartSample.java
├── MiniTest.java
├── ScatterChartSample.java
└── ZoomManager.java
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [kerner1000]
4 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | javafx-chart-zooming
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.m2e.core.maven2Builder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javanature
21 | org.eclipse.m2e.core.maven2Nature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
3 | org.eclipse.jdt.core.compiler.compliance=1.8
4 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
5 | org.eclipse.jdt.core.compiler.source=1.8
6 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.m2e.core.prefs:
--------------------------------------------------------------------------------
1 | activeProfiles=
2 | eclipse.preferences.version=1
3 | resolveWorkspaceProjects=true
4 | version=1
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk:
3 | - oraclejdk8
4 | # Use JDK 8u45. The above line just causes the use of a minor version of Java 8.
5 | addons:
6 | apt:
7 | packages:
8 | - oracle-java8-installer
9 | script: "mvn -q clean package"
10 | notifications:
11 | email:
12 | recipients:
13 | - kerner1000@gmail.com
14 | on_failure: change # default: always
15 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JavaFX Chart Zooming
2 |
3 | [](https://travis-ci.org/kerner1000/javafx-chart-zooming)
4 | [](https://github.com/kerner1000/javafx-chart-zooming/blob/master/LICENSE.txt)
5 | [](https://maven-badges.herokuapp.com/maven-central/com.github.silicosciences/javafx-chart-zooming)
6 |
7 | 
8 |
9 | 
10 |
11 | 
12 |
13 | ## HoTo use
14 | There is only one class that is realizing the zooming functionality:
15 | [ZoomManager](https://github.com/kerner1000/javafx-chart-zooming/blob/master/src/main/java/com/github/javafx/charts/zooming/ZoomManager.java).
16 |
17 | Check out the examples on how to use the ZoomManager:
18 | [Examples](https://github.com/kerner1000/javafx-chart-zooming/blob/master/src/main/java/com/github/javafx/charts/zooming/).
19 |
20 | ### Maven
21 | This project is synced to Maven Central, so you can just add the following dependency to your project:
22 |
23 | ```xml
24 |
25 | com.github.kerner1000
26 | javafx-chart-zooming
27 | 0.0.8
28 |
29 | ```
30 | ### Eclipse RCP/ OSGi
31 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 | com.github.kerner1000
5 | javafx-chart-zooming
6 | 0.0.10-SNAPSHOT
7 |
8 | org.sonatype.oss
9 | oss-parent
10 | 9
11 |
12 |
13 |
14 | kerner
15 | Alexander Kerner
16 | alexkerner1000@gmail.com
17 |
18 | Project Manager
19 | Architect
20 |
21 |
22 |
23 |
24 |
25 | The Apache Software License, Version 2.0
26 | http://www.apache.org/licenses/LICENSE-2.0.txt
27 |
28 |
29 |
30 | git:git@github.com:kerner1000/javafx-chart-zooming.git
31 | scm:git:git@github.com:kerner1000/javafx-chart-zooming.git
32 | scm:git:git@github.com:kerner1000/javafx-chart-zooming.git
33 | HEAD
34 |
35 |
36 |
37 |
38 |
39 | sonatype-nexus-snapshots
40 | Sonatype Nexus snapshot repository
41 | https://oss.sonatype.org/content/repositories/snapshots
42 |
43 |
44 | sonatype-nexus-staging
45 | Sonatype Nexus release repository
46 | https://oss.sonatype.org/service/local/staging/deploy/maven2/
47 |
48 |
49 |
50 |
51 |
52 |
53 | maven-compiler-plugin
54 | 3.6.0
55 |
56 | 1.8
57 | 1.8
58 |
59 |
60 |
61 | org.apache.maven.plugins
62 | maven-release-plugin
63 |
64 |
65 | org.apache.maven.plugins
66 | maven-javadoc-plugin
67 | 2.10.2
68 |
69 |
70 | attach-javadocs
71 |
72 | jar
73 |
74 |
75 | -Xdoclint:none
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/src/main/java/com/github/javafx/charts/zooming/BarChartSample.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 |
20 | package com.github.javafx.charts.zooming;
21 |
22 | import javafx.application.Application;
23 | import javafx.scene.Scene;
24 | import javafx.scene.chart.BarChart;
25 | import javafx.scene.chart.CategoryAxis;
26 | import javafx.scene.chart.NumberAxis;
27 | import javafx.scene.chart.XYChart;
28 | import javafx.scene.layout.StackPane;
29 | import javafx.stage.Stage;
30 |
31 | public class BarChartSample extends Application {
32 | final static String austria = "Austria";
33 | final static String brazil = "Brazil";
34 | final static String france = "France";
35 | final static String italy = "Italy";
36 | final static String usa = "USA";
37 |
38 | public static void main(final String[] args) {
39 | launch(args);
40 | }
41 |
42 | @Override
43 | public void start(final Stage stage) {
44 | stage.setTitle("Bar Chart Sample");
45 | final CategoryAxis xAxis = new CategoryAxis();
46 | final NumberAxis yAxis = new NumberAxis();
47 | final BarChart bc = new BarChart(xAxis, yAxis);
48 | bc.setTitle("Country Summary");
49 | xAxis.setLabel("Country");
50 | yAxis.setLabel("Value");
51 |
52 | final XYChart.Series series1 = new XYChart.Series();
53 | series1.setName("2003");
54 | series1.getData().add(new XYChart.Data(austria, 25601.34));
55 | series1.getData().add(new XYChart.Data(brazil, 20148.82));
56 | series1.getData().add(new XYChart.Data(france, 10000));
57 | series1.getData().add(new XYChart.Data(italy, 35407.15));
58 | series1.getData().add(new XYChart.Data(usa, 12000));
59 |
60 | final XYChart.Series series2 = new XYChart.Series();
61 | series2.setName("2004");
62 | series2.getData().add(new XYChart.Data(austria, 57401.85));
63 | series2.getData().add(new XYChart.Data(brazil, 41941.19));
64 | series2.getData().add(new XYChart.Data(france, 45263.37));
65 | series2.getData().add(new XYChart.Data(italy, 117320.16));
66 | series2.getData().add(new XYChart.Data(usa, 14845.27));
67 |
68 | final XYChart.Series series3 = new XYChart.Series();
69 | series3.setName("2005");
70 | series3.getData().add(new XYChart.Data(austria, 45000.65));
71 | series3.getData().add(new XYChart.Data(brazil, 44835.76));
72 | series3.getData().add(new XYChart.Data(france, 18722.18));
73 | series3.getData().add(new XYChart.Data(italy, 17557.31));
74 | series3.getData().add(new XYChart.Data(usa, 92633.68));
75 |
76 | // DO NOT ADD DATA TO CHART
77 | // bc.getData().addAll(series1, series2, series3);
78 | final StackPane pane = new StackPane();
79 | pane.getChildren().add(bc);
80 | final Scene scene = new Scene(pane, 500, 400);
81 | new ZoomManager(pane, bc, series1, series2, series3);
82 | stage.setScene(scene);
83 | stage.show();
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/main/java/com/github/javafx/charts/zooming/LineChartSample.java:
--------------------------------------------------------------------------------
1 | package com.github.javafx.charts.zooming;
2 |
3 | import javafx.application.Application;
4 | import javafx.scene.Scene;
5 | import javafx.scene.chart.LineChart;
6 | import javafx.scene.chart.NumberAxis;
7 | import javafx.scene.chart.XYChart;
8 | import javafx.scene.layout.StackPane;
9 | import javafx.stage.Stage;
10 |
11 | public class LineChartSample extends Application {
12 |
13 | public static void main(final String[] args) {
14 | launch(args);
15 | }
16 |
17 | @Override
18 | public void start(final Stage stage) {
19 | stage.setTitle("Line Chart Sample");
20 | // defining the axes
21 | final NumberAxis xAxis = new NumberAxis();
22 | final NumberAxis yAxis = new NumberAxis();
23 | xAxis.setAutoRanging(true);
24 | xAxis.setForceZeroInRange(false);
25 | yAxis.setAutoRanging(true);
26 | yAxis.setForceZeroInRange(false);
27 | xAxis.setLabel("Number of Month");
28 | // creating the chart
29 | final LineChart lineChart = new LineChart(xAxis, yAxis);
30 |
31 | lineChart.setTitle("Stock Monitoring, 2010");
32 | // defining a series
33 | final XYChart.Series series = new XYChart.Series();
34 | series.setName("My portfolio");
35 | // populating the series with data
36 | series.getData().add(new XYChart.Data(1, 23));
37 | series.getData().add(new XYChart.Data(2, 14));
38 | series.getData().add(new XYChart.Data(3, 15));
39 | series.getData().add(new XYChart.Data(4, 24));
40 | series.getData().add(new XYChart.Data(5, 34));
41 | series.getData().add(new XYChart.Data(6, 36));
42 | series.getData().add(new XYChart.Data(7, 22));
43 | series.getData().add(new XYChart.Data(8, 45));
44 | series.getData().add(new XYChart.Data(9, 43));
45 | series.getData().add(new XYChart.Data(10, 17));
46 | series.getData().add(new XYChart.Data(11, 29));
47 | series.getData().add(new XYChart.Data(12, 25));
48 |
49 | // DO NOT ADD DATA TO CHART
50 | // bc.getData().addAll(series1, series2, series3);
51 | final StackPane pane = new StackPane();
52 | pane.getChildren().add(lineChart);
53 | final Scene scene = new Scene(pane, 500, 400);
54 | new ZoomManager(pane, lineChart, series);
55 | stage.setScene(scene);
56 | stage.show();
57 | }
58 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/javafx/charts/zooming/MiniTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 | package com.github.javafx.charts.zooming;
20 |
21 | import javafx.application.Application;
22 | import javafx.event.EventHandler;
23 | import javafx.scene.Scene;
24 | import javafx.scene.chart.BarChart;
25 | import javafx.scene.chart.CategoryAxis;
26 | import javafx.scene.chart.NumberAxis;
27 | import javafx.scene.chart.XYChart;
28 | import javafx.scene.input.MouseEvent;
29 | import javafx.scene.layout.StackPane;
30 | import javafx.stage.Stage;
31 |
32 | public class MiniTest extends Application {
33 |
34 | final static String austria = "Austria";
35 | final static String brazil = "Brazil";
36 | final static String france = "France";
37 | final static String italy = "Italy";
38 | final static String usa = "USA";
39 |
40 | public static void main(final String[] args) {
41 | launch(args);
42 |
43 | }
44 |
45 | @Override
46 | public void start(final Stage stage) throws Exception {
47 |
48 | final CategoryAxis xAxis = new CategoryAxis();
49 | final NumberAxis yAxis = new NumberAxis();
50 | final BarChart chart = new BarChart(xAxis, yAxis);
51 | final XYChart.Series series1 = new XYChart.Series();
52 | series1.setName("2003");
53 | series1.getData().add(new XYChart.Data(austria, 25601.34));
54 | series1.getData().add(new XYChart.Data(brazil, 20148.82));
55 | series1.getData().add(new XYChart.Data(france, 10000));
56 | series1.getData().add(new XYChart.Data(italy, 35407.15));
57 | series1.getData().add(new XYChart.Data(usa, 12000));
58 | chart.getData().add(series1);
59 | chart.setOnMouseClicked(new EventHandler() {
60 | @Override
61 | public void handle(final MouseEvent event) {
62 | if (chart.getData().isEmpty()) {
63 | chart.getData().add(series1);
64 | } else {
65 | chart.getData().clear();
66 | }
67 | }
68 | });
69 | final StackPane pane = new StackPane();
70 | pane.getChildren().add(chart);
71 | final Scene scene = new Scene(pane, 800, 600);
72 | stage.setScene(scene);
73 | stage.show();
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/java/com/github/javafx/charts/zooming/ScatterChartSample.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | * under the License.
18 | */
19 |
20 | package com.github.javafx.charts.zooming;
21 |
22 | import javafx.application.Application;
23 | import javafx.scene.Scene;
24 | import javafx.scene.chart.NumberAxis;
25 | import javafx.scene.chart.ScatterChart;
26 | import javafx.scene.chart.XYChart;
27 | import javafx.scene.layout.StackPane;
28 | import javafx.stage.Stage;
29 |
30 | public class ScatterChartSample extends Application {
31 |
32 | public static void main(final String[] args) {
33 | launch(args);
34 | }
35 |
36 | @SuppressWarnings({ "rawtypes", "unchecked" })
37 | @Override
38 | public void start(final Stage stage) {
39 | stage.setTitle("Scatter Chart Sample");
40 | final NumberAxis xAxis = new NumberAxis(0, 10, 1);
41 | final NumberAxis yAxis = new NumberAxis(-100, 500, 100);
42 | xAxis.setAutoRanging(true);
43 | xAxis.setForceZeroInRange(false);
44 | yAxis.setAutoRanging(true);
45 | yAxis.setForceZeroInRange(false);
46 | final ScatterChart sc = new ScatterChart(xAxis, yAxis);
47 | xAxis.setLabel("Age (years)");
48 | yAxis.setLabel("Returns to date");
49 | sc.setTitle("Investment Overview");
50 |
51 | final XYChart.Series series1 = new XYChart.Series<>();
52 | series1.setName("Equities");
53 | series1.getData().add(new XYChart.Data(4.2, 193.2));
54 | series1.getData().add(new XYChart.Data(2.8, 33.6));
55 | series1.getData().add(new XYChart.Data(6.2, 24.8));
56 | series1.getData().add(new XYChart.Data(1, 14));
57 | series1.getData().add(new XYChart.Data(1.2, 26.4));
58 | series1.getData().add(new XYChart.Data(4.4, 114.4));
59 | series1.getData().add(new XYChart.Data(8.5, 323));
60 | series1.getData().add(new XYChart.Data(6.9, 289.8));
61 | series1.getData().add(new XYChart.Data(9.9, 287.1));
62 | series1.getData().add(new XYChart.Data(0.9, -9));
63 | series1.getData().add(new XYChart.Data(3.2, 150.8));
64 | series1.getData().add(new XYChart.Data(4.8, 20.8));
65 | series1.getData().add(new XYChart.Data(7.3, -42.3));
66 | series1.getData().add(new XYChart.Data(1.8, 81.4));
67 | series1.getData().add(new XYChart.Data(7.3, 110.3));
68 | series1.getData().add(new XYChart.Data(2.7, 41.2));
69 |
70 | final XYChart.Series series2 = new XYChart.Series<>();
71 | series2.setName("Mutual funds");
72 | series2.getData().add(new XYChart.Data(5.2, 229.2));
73 | series2.getData().add(new XYChart.Data(2.4, 37.6));
74 | series2.getData().add(new XYChart.Data(3.2, 49.8));
75 | series2.getData().add(new XYChart.Data(1.8, 134));
76 | series2.getData().add(new XYChart.Data(3.2, 236.2));
77 | series2.getData().add(new XYChart.Data(7.4, 114.1));
78 | series2.getData().add(new XYChart.Data(3.5, 323));
79 | series2.getData().add(new XYChart.Data(9.3, 29.9));
80 | series2.getData().add(new XYChart.Data(8.1, 287.4));
81 |
82 | // DO NOT ADD DATA TO CHART
83 | // sc.getData().addAll(series1, series2);
84 |
85 | final StackPane pane = new StackPane();
86 | pane.getChildren().add(sc);
87 | final Scene scene = new Scene(pane, 500, 400);
88 | new ZoomManager(pane, sc, series1, series2);
89 | stage.setScene(scene);
90 | stage.show();
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/main/java/com/github/javafx/charts/zooming/ZoomManager.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 |
20 | package com.github.javafx.charts.zooming;
21 |
22 | import java.util.Arrays;
23 | import java.util.Collection;
24 | import java.util.Iterator;
25 | import java.util.List;
26 | import java.util.Objects;
27 |
28 | import javafx.beans.property.ObjectProperty;
29 | import javafx.beans.property.SimpleObjectProperty;
30 | import javafx.collections.FXCollections;
31 | import javafx.collections.ObservableList;
32 | import javafx.event.EventHandler;
33 | import javafx.geometry.Bounds;
34 | import javafx.geometry.Point2D;
35 | import javafx.scene.Node;
36 | import javafx.scene.chart.Axis;
37 | import javafx.scene.chart.XYChart;
38 | import javafx.scene.chart.XYChart.Data;
39 | import javafx.scene.chart.XYChart.Series;
40 | import javafx.scene.input.MouseButton;
41 | import javafx.scene.input.MouseEvent;
42 | import javafx.scene.layout.Pane;
43 | import javafx.scene.paint.Color;
44 | import javafx.scene.shape.Rectangle;
45 |
46 | public class ZoomManager {
47 |
48 | static ObservableList> deepCopySeries(final Collection> data) {
49 | final ObservableList> backup = FXCollections.observableArrayList();
50 | for (final Series s : data) {
51 | backup.add(deepCopySeries(s));
52 | }
53 | return backup;
54 | }
55 |
56 | static XYChart.Series deepCopySeries(final XYChart.Series series) {
57 | final XYChart.Series result = new XYChart.Series<>();
58 | result.setName(series.getName());
59 | result.setData(deepCopySeriesData(series.getData()));
60 | return result;
61 | }
62 |
63 | static ObservableList> deepCopySeriesData(
64 | final Collection extends XYChart.Data> data) {
65 | final ObservableList> result = FXCollections.observableArrayList();
66 | for (final Data i : data) {
67 | result.add(new Data<>(i.getXValue(), i.getYValue()));
68 | }
69 | return result;
70 | }
71 |
72 | static ObservableList extractXValues(final ObservableList> data) {
73 | final ObservableList result = FXCollections.observableArrayList();
74 | for (final Data d : data) {
75 | result.add(d.getXValue());
76 | }
77 | return result;
78 | }
79 |
80 | static ObservableList extractYValues(final ObservableList> data) {
81 | final ObservableList result = FXCollections.observableArrayList();
82 | for (final Data d : data) {
83 | result.add(d.getYValue());
84 | }
85 | return result;
86 | }
87 |
88 | static Object getObject(final Axis> axis, final double cooridnate) {
89 | final Object object = axis.getValueForDisplay(cooridnate);
90 | return object;
91 | }
92 |
93 | static Node getRootNode(final Node node) {
94 | Node n = node;
95 | while (n.getParent() != null) {
96 | n = n.getParent();
97 | }
98 | return n;
99 | }
100 |
101 | private final ObservableList> series;
102 |
103 | private final XYChart chart;
104 |
105 | private volatile boolean zoomed;
106 |
107 | /**
108 | *
109 | *
110 | * Creates a new {@code ZoomManager}.
111 | *
112 | * Due to a bug, {@code series} must not be added to the chart! If you
113 | * do so, the chart will be emtpy.
114 | *
115 | *
116 | *
117 | * @param chartParent
118 | * the chart's parent {@link Pane}.
119 | * @param chart
120 | * the {@link XYChart} to which zooming functionality is added
121 | * @param series
122 | * collection of chart data to display
123 | * @throws IllegalArgumentException
124 | * if chart data is empty or {@code null}
125 | */
126 | public ZoomManager(final Pane chartParent, final XYChart chart,
127 | final Collection extends Series> series) {
128 | super();
129 | this.chart = Objects.requireNonNull(chart);
130 | if (series == null || series.isEmpty()) {
131 | throw new IllegalArgumentException("No chart data given");
132 | }
133 | this.series = FXCollections.observableArrayList(series);
134 | restoreData();
135 | final Rectangle zoomRect = new Rectangle();
136 | zoomRect.setManaged(false);
137 | zoomRect.setFill(Color.LIGHTSEAGREEN.deriveColor(0, 1, 1, 0.5));
138 | chartParent.getChildren().add(zoomRect);
139 | setUpZooming(zoomRect, chart);
140 |
141 | }
142 |
143 | /**
144 | *
145 | *
146 | * Creates a new {@code ZoomManager}.
147 | *
148 | * Due to a bug, {@code series} must not be added to the chart! If you
149 | * do so, the chart will be emtpy.
150 | *
151 | *
152 | *
153 | * @param chartParent
154 | * the chart's parent {@link Pane}.
155 | * @param chart
156 | * the {@link XYChart} to which zooming functionality is added
157 | * @param series
158 | * array of chart data to display
159 | * @throws IllegalArgumentException
160 | * if chart data is empty or {@code null}
161 | */
162 | public ZoomManager(final Pane chartParent, final XYChart chart, final Series... series) {
163 | this(chartParent, chart, Arrays.asList(series));
164 |
165 | }
166 |
167 | private void doZoom(final boolean x, final Number n1, final Number n2) {
168 | final double min = Math.min(n1.doubleValue(), n2.doubleValue());
169 | final double max = Math.max(n1.doubleValue(), n2.doubleValue());
170 | if (max - min > 1) {
171 | zoomed = true;
172 | final Iterator> it = chart.getData().iterator();
173 | while (it.hasNext()) {
174 | final XYChart.Series s = it.next();
175 | final Iterator> it2 = s.getData().iterator();
176 | while (it2.hasNext()) {
177 | final XYChart.Data d = it2.next();
178 | final Object value;
179 | if (x) {
180 | value = d.getXValue();
181 | } else {
182 | value = d.getYValue();
183 | }
184 | if (value instanceof Number) {
185 | final Number n = (Number) value;
186 | final double dd = n.doubleValue();
187 | if (dd < min || dd > max) {
188 | it2.remove();
189 | } else {
190 | }
191 | }
192 | if (s.getData().isEmpty()) {
193 | it.remove();
194 | }
195 | }
196 | }
197 | } else {
198 | // System.out.println("Skip tiny zoom");
199 | }
200 |
201 | }
202 |
203 | private void doZoom(final boolean x, final Object o1, final Object o2) {
204 | if (o1 instanceof Number && o2 instanceof Number) {
205 | doZoom(x, (Number) o1, (Number) o2);
206 | } else if (o1 instanceof String || o2 instanceof String) {
207 | doZoom(x, (String) o1, (String) o2);
208 | } else {
209 | final int wait = 0;
210 | }
211 | }
212 |
213 | private void doZoom(final boolean x, String s1, String s2) {
214 | if (s1 == null && s2 == null) {
215 | return;
216 | }
217 | if (s1 == null) {
218 | s1 = s2;
219 | }
220 | if (s2 == null) {
221 | s2 = s1;
222 | }
223 |
224 | final Iterator> it = chart.getData().iterator();
225 | while (it.hasNext()) {
226 | final XYChart.Series s = it.next();
227 | final List> values;
228 | if (x) {
229 | values = extractXValues(s.getData());
230 | } else {
231 | values = extractYValues(s.getData());
232 | }
233 | final int index1 = values.indexOf(s1);
234 | final int index2 = values.indexOf(s2);
235 | final int lower = Math.min(index1, index2);
236 | final int upper = Math.max(index1, index2);
237 | final Iterator> it2 = s.getData().iterator();
238 | while (it2.hasNext()) {
239 | final Data d = it2.next();
240 | final Object value;
241 | if (x) {
242 | value = d.getXValue();
243 | } else {
244 | value = d.getYValue();
245 | }
246 | final int index = values.indexOf(value);
247 | if (index != -1 && (index < lower || index > upper)) {
248 | it2.remove();
249 | }
250 | }
251 | }
252 | }
253 |
254 | private void restoreData() {
255 | // make a tmp variable of data, since we will modify it but need to be
256 | // able to restore
257 | final ObservableList> backup2 = deepCopySeries(series);
258 | chart.getData().setAll(backup2);
259 |
260 | }
261 |
262 | private void setUpZooming(final Rectangle rect, final XYChart chart) {
263 |
264 | setUpZoomingRectangle(rect);
265 |
266 | }
267 |
268 | /**
269 | * Displays a colored rectangle that will indicate zooming boundaries
270 | *
271 | * @param rect
272 | */
273 | private void setUpZoomingRectangle(final Rectangle rect) {
274 |
275 | /*
276 | * The chart background. Needed to get the correct rectangle boundaries.
277 | */
278 | final Node chartBackground = chart.lookup(".chart-plot-background");
279 | final ObjectProperty mouseAnchor = new SimpleObjectProperty<>();
280 | chart.setOnMousePressed(new EventHandler() {
281 | @Override
282 | public void handle(final MouseEvent event) {
283 | mouseAnchor.set(new Point2D(event.getX(), event.getY()));
284 | }
285 | });
286 | chart.setOnMouseClicked(new EventHandler() {
287 | @Override
288 | public void handle(final MouseEvent event) {
289 | if (event.getButton().equals(MouseButton.PRIMARY)) {
290 | if (zoomed && event.getClickCount() == 2) {
291 | restoreData();
292 | zoomed = false;
293 | event.consume();
294 | }
295 | }
296 | }
297 | });
298 | chart.setOnMouseDragged(new EventHandler() {
299 | @Override
300 | public void handle(final MouseEvent event) {
301 | final double x = event.getX();
302 | final double y = event.getY();
303 | rect.setX(Math.min(x, mouseAnchor.get().getX()));
304 | rect.setY(Math.min(y, mouseAnchor.get().getY()));
305 | rect.setWidth(Math.abs(x - mouseAnchor.get().getX()));
306 | rect.setHeight(Math.abs(y - mouseAnchor.get().getY()));
307 | }
308 | });
309 | chart.setOnMouseReleased(new EventHandler() {
310 | @Override
311 | public void handle(final MouseEvent event) {
312 |
313 | // final Bounds bb = chartBackground.sceneToLocal(rect.getBoundsInLocal());
314 | final Bounds bb = chartBackground.parentToLocal(rect.getBoundsInParent());
315 |
316 | final double minx = bb.getMinX();
317 | final double maxx = bb.getMaxX();
318 |
319 | final double miny = bb.getMinY();
320 | final double maxy = bb.getMaxY();
321 |
322 | doZoom(true, chart.getXAxis().getValueForDisplay(minx), chart.getXAxis().getValueForDisplay(maxx));
323 |
324 | doZoom(false, chart.getYAxis().getValueForDisplay(miny), chart.getYAxis().getValueForDisplay(maxy));
325 |
326 | rect.setWidth(0);
327 | rect.setHeight(0);
328 | }
329 | });
330 | }
331 |
332 | }
333 |
--------------------------------------------------------------------------------