Created
March 10, 2014 21:28
-
-
Save abhinayagarwal/9474756 to your computer and use it in GitHub Desktop.
BarChart with Label and refresh Data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* To change this license header, choose License Headers in Project Properties. | |
* To change this template file, choose Tools | Templates | |
* and open the template in the editor. | |
*/ | |
import java.text.DecimalFormat; | |
import javafx.application.Application; | |
import javafx.beans.value.*; | |
import javafx.event.ActionEvent; | |
import javafx.event.EventHandler; | |
import javafx.geometry.Bounds; | |
import javafx.geometry.Pos; | |
import javafx.scene.*; | |
import javafx.scene.chart.*; | |
import javafx.scene.control.Button; | |
import javafx.scene.control.Label; | |
import javafx.scene.layout.*; | |
import javafx.scene.paint.Color; | |
import javafx.scene.shape.*; | |
import javafx.scene.text.Text; | |
import javafx.stage.Stage; | |
/** | |
* Displays a bar with a single series whose bars are different colors depending | |
* upon the bar value. A custom legend is created and displayed for the bar | |
* data. Bars in the chart are customized to include a text label of the bar's | |
* data value above the bar. | |
*/ | |
public class DynamicallyColoredBarChartWithLabel extends Application { | |
Button button = new Button("Refresh"); | |
BarChart<String, Number> bc; | |
@Override | |
public void start(Stage stage) { | |
final CategoryAxis xAxis = new CategoryAxis(); | |
xAxis.setLabel("Bars"); | |
final NumberAxis yAxis = new NumberAxis(); | |
yAxis.setLabel("Value"); | |
bc = new BarChart<>(xAxis, yAxis); | |
bc.setLegendVisible(false); | |
XYChart.Series series1 = new XYChart.Series(); | |
for (int i = 0; i < 10; i++) { | |
final XYChart.Data<String, Number> data = new XYChart.Data("Value " + i, i); | |
data.nodeProperty().addListener(new ChangeListener<Node>() { | |
@Override | |
public void changed(ObservableValue<? extends Node> ov, Node oldNode, final Node node) { | |
if (node != null) { | |
setNodeStyle(data); | |
displayLabelForData(data); | |
} | |
} | |
}); | |
series1.getData().add(data); | |
} | |
bc.getData().add(series1); | |
LevelLegend legend = new LevelLegend(); | |
legend.setAlignment(Pos.CENTER); | |
VBox chartWithLegend = new VBox(); | |
chartWithLegend.getChildren().setAll(bc, legend); | |
VBox.setVgrow(bc, Priority.ALWAYS); | |
chartWithLegend.getStylesheets().add(getClass().getResource("colored-chart.css").toExternalForm()); | |
stage.setScene(new Scene(chartWithLegend)); | |
stage.setMinHeight(400); | |
stage.setMinWidth(400); | |
stage.show(); | |
} | |
/** | |
* Change color of bar if value of i is <5 then red, if >5 then green if i>8 | |
* then blue | |
*/ | |
private void setNodeStyle(XYChart.Data<String, Number> data) { | |
Node node = data.getNode(); | |
if (data.getYValue().intValue() > 8) { | |
node.setStyle("-fx-bar-fill: -fx-exceeded;"); | |
} else if (data.getYValue().intValue() > 5) { | |
node.setStyle("-fx-bar-fill: -fx-achieved;"); | |
} else { | |
node.setStyle("-fx-bar-fill: -fx-not-achieved;"); | |
} | |
} | |
/** | |
* places a text label with a bar's value above a bar node for a given | |
* XYChart.Data | |
*/ | |
private void displayLabelForData(XYChart.Data<String, Number> data) { | |
final Node node = data.getNode(); | |
final DecimalFormat df = new DecimalFormat( "$###,##0.00" ); | |
final Text dataText = new Text(df.format(data.getYValue()) + ""); | |
node.parentProperty().addListener(new ChangeListener<Parent>() { | |
@Override | |
public void changed(ObservableValue<? extends Parent> ov, Parent oldParent, Parent parent) { | |
if(null!=parent) | |
{ | |
Group parentGroup = (Group) parent; | |
parentGroup.getChildren().add(dataText); | |
} | |
} | |
}); | |
node.boundsInParentProperty().addListener(new ChangeListener<Bounds>() { | |
@Override | |
public void changed(ObservableValue<? extends Bounds> ov, Bounds oldBounds, Bounds bounds) { | |
dataText.setLayoutX( | |
Math.round( | |
bounds.getMinX() + bounds.getWidth() / 2 - dataText.prefWidth(-1) / 2 | |
) | |
); | |
dataText.setLayoutY( | |
Math.round( | |
bounds.getMinY() - dataText.prefHeight(-1) * 0.5 | |
) | |
); | |
} | |
}); | |
button.setOnAction(new EventHandler<ActionEvent>() { | |
@Override | |
public void handle(ActionEvent paramT) { | |
bc.getData().clear(); | |
XYChart.Series series1 = new XYChart.Series(); | |
for (int i = 10; i < 20; i++) { | |
final XYChart.Data<String, Number> data = new XYChart.Data("Value " + i, 1.0 + (Math.random()*(10-1+1))); | |
data.nodeProperty().addListener(new ChangeListener<Node>() { | |
@Override | |
public void changed(ObservableValue<? extends Node> ov, Node oldNode, final Node node) { | |
if (node != null) { | |
setNodeStyle(data); | |
displayLabelForData(data); | |
} | |
} | |
}); | |
series1.getData().add(data); | |
} | |
bc.getData().add(series1); | |
} | |
}); | |
} | |
/** | |
* A simple custom legend for a three valued chart. | |
*/ | |
class LevelLegend extends GridPane { | |
LevelLegend() { | |
setHgap(10); | |
setVgap(10); | |
addRow(0, createSymbol("-fx-exceeded"), new Label("Exceeded")); | |
addRow(1, createSymbol("-fx-achieved"), new Label("Achieved")); | |
addRow(2, createSymbol("-fx-not-achieved"), new Label("Not Achieved")); | |
addRow(3, button); | |
getStyleClass().add("level-legend"); | |
} | |
/** | |
* Create a custom symbol for a custom chart legend with the given | |
* fillStyle style string. | |
*/ | |
private Node createSymbol(String fillStyle) { | |
Shape symbol = new Ellipse(10, 5, 10, 5); | |
symbol.setStyle("-fx-fill: " + fillStyle); | |
symbol.setStroke(Color.BLACK); | |
symbol.setStrokeWidth(2); | |
return symbol; | |
} | |
} | |
public static void main(String[] args) { | |
launch(args); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yo i have an issue i post u the errore
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$154(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
at DynamicallyColoredBarChartWithLabel.start(DynamicallyColoredBarChartWithLabel.java:70)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
... 1 more
Exception running application DynamicallyColoredBarChartWithLabel
C:\Users\mattia tanchis\Documents\NetBeansProjects\JavaFXApplication1\nbproject\build-impl.xml:1340: The following error occurred while executing this line:
C:\Users\mattia tanchis\Documents\NetBeansProjects\JavaFXApplication1\nbproject\build-impl.xml:981: Java returned: 1
BUILD FAILED (total time: 1 second)