-
-
Save abhinayagarwal/9474756 to your computer and use it in GitHub Desktop.
/* | |
* 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); | |
} | |
} |
Hi
I'm having one issue with this.
The label above the bar is sometimes getting truncated.
Is there any way to avoid the truncation of the label??
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)
In accordance to
http://stackoverflow.com/questions/22312493/label-on-bar-chart-stays-on-value-refreshed