Skip to content

Commit 6e16623

Browse files
committed
Add zooming to SmartChart
1 parent 0dc8e1a commit 6e16623

File tree

2 files changed

+286
-81
lines changed

2 files changed

+286
-81
lines changed

SmartChart/src/edu/nr/NRChart.java

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
package edu.nr;
2+
3+
import javafx.beans.InvalidationListener;
4+
import javafx.beans.binding.BooleanBinding;
5+
import javafx.beans.property.BooleanProperty;
6+
import javafx.beans.property.ObjectProperty;
7+
import javafx.beans.property.SimpleBooleanProperty;
8+
import javafx.beans.property.SimpleObjectProperty;
9+
import javafx.beans.value.ChangeListener;
10+
import javafx.beans.value.ObservableBooleanValue;
11+
import javafx.event.EventHandler;
12+
import javafx.geometry.Point2D;
13+
import javafx.scene.chart.LineChart;
14+
import javafx.scene.chart.NumberAxis;
15+
import javafx.scene.input.MouseEvent;
16+
import javafx.scene.shape.Rectangle;
17+
18+
import java.io.*;
19+
import java.nio.file.FileAlreadyExistsException;
20+
import java.nio.file.Files;
21+
import java.nio.file.Paths;
22+
import java.util.ArrayList;
23+
24+
/**
25+
* Created by Nashoba1768 on 1/22/2017.
26+
*/
27+
class NRChart extends LineChart<Number, Number>
28+
{
29+
private Series series = new Series();
30+
private long startTimeMillis;
31+
32+
SmartChart chart;
33+
34+
public BooleanProperty isAutoZooming;
35+
36+
public NRChart(SmartChart chart)
37+
{
38+
super(new NumberAxis(), new NumberAxis());
39+
setAnimated(false);
40+
41+
isAutoZooming = new SimpleBooleanProperty();
42+
setAutoZooming(true);
43+
44+
((NumberAxis)getXAxis()).setForceZeroInRange(false);
45+
((NumberAxis)getYAxis()).setForceZeroInRange(false);
46+
setLegendVisible(false);
47+
getData().add(this.series);
48+
this.chart = chart;
49+
}
50+
51+
public void addValue(double x)
52+
{
53+
if(this.series.getData().size() == 0)
54+
{
55+
startTimeMillis = System.currentTimeMillis();
56+
}
57+
58+
double currentTime = (System.currentTimeMillis() - startTimeMillis)/1000d;
59+
60+
61+
this.series.getData().add(new Data(currentTime, x));
62+
if (this.series.getData().size() > 10000) {
63+
this.series.getData().remove(0);
64+
}
65+
}
66+
67+
public void reset()
68+
{
69+
this.series.getData().clear();
70+
}
71+
72+
public void save()
73+
{
74+
StringBuilder sb = new StringBuilder();
75+
for(Object x:this.series.getData()) {
76+
Data<Double,Double> y = (Data<Double, Double>) x;
77+
sb.append(y.getXValue());
78+
sb.append(",");
79+
sb.append(y.getYValue());
80+
sb.append('\n');
81+
}
82+
83+
String fileName = System.getProperty("user.home") + "\\" + this.chart.getName().replace(' ', '_') + ".csv";
84+
85+
try {
86+
// Create the empty file with default permissions, etc.
87+
Files.createFile(Paths.get(fileName));
88+
} catch (FileAlreadyExistsException x) {
89+
System.err.format("file named %s" +
90+
" already exists%n", fileName);
91+
} catch (IOException x) {
92+
// Some other sort of failure, such as permissions.
93+
System.err.format("createFile error: %s%n", x);
94+
}
95+
96+
97+
try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName), "utf-8"))) {
98+
writer.write(sb.toString());
99+
} catch (IOException e) {
100+
e.printStackTrace();
101+
}
102+
}
103+
104+
protected void setUpZooming(final Rectangle rect) {
105+
final ObjectProperty<Point2D> mouseAnchor = new SimpleObjectProperty<>();
106+
this.setOnMousePressed(new EventHandler<MouseEvent>() {
107+
@Override
108+
public void handle(MouseEvent event) {
109+
mouseAnchor.set(new Point2D(event.getX(), event.getY()));
110+
rect.setWidth(0);
111+
rect.setHeight(0);
112+
}
113+
});
114+
this.setOnMouseDragged(new EventHandler<MouseEvent>() {
115+
@Override
116+
public void handle(MouseEvent event) {
117+
double x = event.getX();
118+
double y = event.getY();
119+
rect.setX(Math.min(x, mouseAnchor.get().getX()));
120+
rect.setY(Math.min(y, mouseAnchor.get().getY()));
121+
rect.setWidth(Math.abs(x - mouseAnchor.get().getX()));
122+
rect.setHeight(Math.abs(y - mouseAnchor.get().getY()));
123+
}
124+
});
125+
}
126+
127+
public void doZoom(Rectangle zoomRect) {
128+
final NumberAxis yAxis = (NumberAxis) getYAxis();
129+
final NumberAxis xAxis = (NumberAxis) getXAxis();
130+
//Point2D yAxisInScene = yAxis.localToScene(0, 0);
131+
//Point2D xAxisInScene = xAxis.localToScene(0, 0);
132+
double xtopLeftCornerOfGraph = 52;
133+
double ytopLeftCornerOfGraph = 17;
134+
135+
double x = zoomRect.getX() - xtopLeftCornerOfGraph;
136+
double y = zoomRect.getY() - ytopLeftCornerOfGraph;
137+
double w = zoomRect.getWidth();
138+
double h = zoomRect.getHeight();
139+
140+
double width_pixels = this.getWidth() - 65; //65 is the number of pixels of padding
141+
double height_pixels = this.getHeight() - 65;
142+
143+
double width_value = xAxis.getUpperBound() - xAxis.getLowerBound();
144+
double height_value = yAxis.getUpperBound() - yAxis.getLowerBound();
145+
146+
//Point2D zoomTopLeft = new Point2D(zoomRect.getX(), zoomRect.getY());
147+
//Point2D zoomBottomRight = new Point2D(zoomRect.getX() + zoomRect.getWidth(), zoomRect.getY() + zoomRect.getHeight());
148+
//double xOffset = zoomTopLeft.getX() - yAxisInScene.getX();
149+
//double yOffset = zoomBottomRight.getY() - xAxisInScene.getY();
150+
double xAxisScale = width_pixels/width_value;
151+
double yAxisScale = height_pixels/height_value;
152+
153+
double xLower = xAxis.getLowerBound();
154+
double yUpper = yAxis.getUpperBound();
155+
156+
xAxis.setLowerBound(xLower + x / xAxisScale);
157+
xAxis.setUpperBound(xLower + (x+w)/ xAxisScale);
158+
yAxis.setUpperBound(yUpper - y / yAxisScale);
159+
yAxis.setLowerBound(yUpper - (y+h) / yAxisScale);
160+
zoomRect.setWidth(0);
161+
zoomRect.setHeight(0);
162+
}
163+
164+
public double getLowestX() {
165+
if(this.series.getData().size() == 0) {
166+
return 0;
167+
}
168+
169+
return ((Data<Double,Double>) this.series.getData().get(0)).getXValue();
170+
}
171+
172+
public double getLowestY() {
173+
if(this.series.getData().size() == 0) {
174+
return 0;
175+
}
176+
double minValue = ((Data<Double,Double>) this.series.getData().get(0)).getYValue();
177+
for(int i=0; i<this.series.getData().size(); i++){
178+
if(((Data<Double,Double>) this.series.getData().get(i)).getYValue() < minValue) {
179+
minValue = ((Data<Double, Double>) this.series.getData().get(i)).getYValue();
180+
}
181+
}
182+
return minValue;
183+
}
184+
185+
public double getHighestX() {
186+
if(this.series.getData().size() == 0) {
187+
return 110;
188+
}
189+
return ((Data<Double,Double>) this.series.getData().get(this.series.getData().size()-1)).getXValue();
190+
}
191+
192+
public double getHighestY() {
193+
if(this.series.getData().size() == 0) {
194+
return 110;
195+
}
196+
double maxValue = ((Data<Double,Double>) this.series.getData().get(0)).getYValue();
197+
for(int i=0; i<this.series.getData().size(); i++){
198+
if(((Data<Double,Double>) this.series.getData().get(i)).getYValue() > maxValue){
199+
maxValue = ((Data<Double,Double>) this.series.getData().get(i)).getYValue();
200+
}
201+
}
202+
return maxValue;
203+
}
204+
205+
public void setAutoZooming(boolean val) {
206+
getXAxis().setAutoRanging(val);
207+
getYAxis().setAutoRanging(val);
208+
209+
isAutoZooming.set(val);
210+
}
211+
212+
public boolean isAutoZooming() {
213+
return isAutoZooming.get();
214+
}
215+
216+
}

0 commit comments

Comments
 (0)