Javafx 以易于阅读的格式转换图表值
我有一个条形图示例,其中我希望以易于阅读的格式显示数据:Javafx 以易于阅读的格式转换图表值,javafx,javafx-8,Javafx,Javafx 8,我有一个条形图示例,其中我希望以易于阅读的格式显示数据: import java.text.DecimalFormat; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java
import java.text.DecimalFormat;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.Tooltip;
import javafx.stage.Stage;
public class MainApp extends Application
{
private static final int MAX_DATA_POINTS = 50;
private Series series;
private Series series2;
private int xSeriesData = 0;
private ConcurrentLinkedQueue<Number> dataQ = new ConcurrentLinkedQueue<Number>();
private ConcurrentLinkedQueue<Number> dataQ2 = new ConcurrentLinkedQueue<Number>();
private ExecutorService executor;
private AddToQueue addToQueue;
private NumberAxis xAxis;
private void init(Stage primaryStage)
{
xAxis = new NumberAxis(0, MAX_DATA_POINTS, MAX_DATA_POINTS / 10);
xAxis.setForceZeroInRange(false);
xAxis.setAutoRanging(false);
NumberAxis yAxis = new NumberAxis();
yAxis.setAutoRanging(true);
//-- Chart
final AreaChart<Number, Number> sc = new AreaChart<Number, Number>(xAxis, yAxis);
sc.setAnimated(false);
sc.setCreateSymbols(false);
sc.setId("liveAreaChart");
sc.setTitle("Animated Area Chart");
//-- Chart Series
series = new AreaChart.Series<Number, Number>();
series.setName("Area Chart Series");
series2 = new AreaChart.Series<Number, Number>();
series2.setName("Area Chart Series");
sc.getData().addAll(series, series2);
xAxis.setTickLabelsVisible(false);
xAxis.setTickMarkVisible(false);
xAxis.setMinorTickVisible(false);
primaryStage.setScene(new Scene(sc));
}
@Override
public void start(Stage primaryStage) throws Exception
{
init(primaryStage);
primaryStage.show();
//-- Prepare Executor Services
executor = Executors.newCachedThreadPool(new ThreadFactory()
{
@Override
public Thread newThread(Runnable r)
{
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread;
}
});
addToQueue = new AddToQueue();
executor.execute(addToQueue);
//-- Prepare Timeline
prepareTimeline();
}
public static void main(String[] args)
{
launch(args);
}
private class AddToQueue implements Runnable
{
@Override
public void run()
{
try
{
// add a item of random data to queue
dataQ.add(randomInteger());
dataQ2.add(randomInteger());
Thread.sleep(400);
executor.execute(this);
}
catch (InterruptedException ex)
{
Logger.getLogger(MainApp.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public int randomInteger()
{
int min = 100;
int max = 900000000;
int randomNum = min + (int) (Math.random() * ((max - min) + 1));
return randomNum;
}
private static String readableFileSize(long size)
{
if (size <= 0)
return "0";
final String[] units = new String[]
{
"B", "kB", "MB", "GB", "TB"
};
int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
}
//-- Timeline gets called in the JavaFX Main thread
private void prepareTimeline()
{
// Every frame to take any data from queue and add to chart
new AnimationTimer()
{
@Override
public void handle(long now)
{
addDataToSeries();
}
}.start();
}
private void addDataToSeries()
{
for (int i = 0; i < 20; i++)
{ //-- add 20 numbers to the plot+
if (dataQ.isEmpty())
break;
// series.getData().add(new AreaChart.Data(xSeriesData++, dataQ.remove()));
Data data = new AreaChart.Data(xSeriesData++, dataQ.remove());
series.getData().add(data);
data.nodeProperty().addListener(new ChangeListener<Node>()
{
@Override
public void changed(ObservableValue<? extends Node> arg0, Node arg1,
Node arg2)
{
Tooltip t = new Tooltip(data.getYValue().toString() + '\n' + data.getXValue());
Tooltip.install(arg2, t);
data.nodeProperty().removeListener(this);
}
});
if (dataQ2.isEmpty())
break;
series2.getData().add(new AreaChart.Data(xSeriesData, dataQ2.remove()));
}
// remove points to keep us at no more than MAX_DATA_POINTS
if (series.getData().size() > MAX_DATA_POINTS)
{
series.getData().remove(0, series.getData().size() - MAX_DATA_POINTS);
}
// remove points to keep us at no more than MAX_DATA_POINTS
if (series2.getData().size() > MAX_DATA_POINTS)
{
series2.getData().remove(0, series2.getData().size() - MAX_DATA_POINTS);
}
// update
xAxis.setLowerBound(xSeriesData - MAX_DATA_POINTS);
xAxis.setUpperBound(xSeriesData - 1);
}
}
可以用于轴标记标签
一个简单的例子:
import java.text.DecimalFormat;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;
import javafx.util.StringConverter;
public class LineChartSample extends Application {
@Override
public void start(Stage stage) {
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
final LineChart<Number, Number> lineChart = new LineChart<Number, Number>(xAxis, yAxis);
XYChart.Series<Number,Number> series = new XYChart.Series<Number,Number>();
for (int i = 0; i < 10000000; i += 1000) {
series.getData().add(new XYChart.Data(i, i));
}
yAxis.setTickLabelFormatter(new StringConverter<Number>() {
@Override
public String toString(Number object) {
// conversion code from:
// http://stackoverflow.com/questions/13539871/converting-kb-to-mb-gb-tb-dynamicaly
double size = object.doubleValue();
String hrSize = null;
double b = size;
double k = size / 1024.0;
double m = ((size / 1024.0) / 1024.0);
double g = (((size / 1024.0) / 1024.0) / 1024.0);
double t = ((((size / 1024.0) / 1024.0) / 1024.0) / 1024.0);
DecimalFormat dec = new DecimalFormat("0.00");
if (t > 1) {
hrSize = dec.format(t).concat(" TB");
} else if (g > 1) {
hrSize = dec.format(g).concat(" GB");
} else if (m > 1) {
hrSize = dec.format(m).concat(" MB");
} else if (k > 1) {
hrSize = dec.format(k).concat(" KB");
} else {
hrSize = dec.format(b).concat(" Bytes");
}
return hrSize;
}
@Override
public Number fromString(String string) {
// TODO: convert from text to number
return null;
}
});
Scene scene = new Scene(lineChart, 800, 600);
lineChart.getData().add(series);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
导入java.text.DecimalFormat;
导入javafx.application.application;
导入javafx.scene.scene;
导入javafx.scene.chart.LineChart;
导入javafx.scene.chart.NumberAxis;
导入javafx.scene.chart.XYChart;
导入javafx.stage.stage;
导入javafx.util.StringConverter;
公共类LineChartSample扩展了应用程序{
@凌驾
公众假期开始(阶段){
最终数字axis xAxis=新数字axis();
最终数字axis yAxis=新数字axis();
最终线形图线形图=新线形图(xAxis,yAxis);
XYChart.Series系列=新的XYChart.Series();
对于(int i=0;i<10000000;i+=1000){
series.getData().add(新的XYChart.Data(i,i));
}
setTickLabelFormatter(新的StringConverter(){
@凌驾
公共字符串toString(数字对象){
//转换代码来自:
// http://stackoverflow.com/questions/13539871/converting-kb-to-mb-gb-tb-dynamicaly
double size=object.doubleValue();
字符串hrSize=null;
双b=尺寸;
双k=大小/1024.0;
双m=((大小/1024.0)/1024.0);
双g=((大小/1024.0)/1024.0)/1024.0);
双t=((大小/1024.0)/1024.0)/1024.0)/1024.0);
DecimalFormat dec=新的DecimalFormat(“0.00”);
如果(t>1){
hrSize=dec.format(t).concat(“TB”);
}如果(g>1),则为else{
hrSize=dec.格式(g).concat(“GB”);
}如果(m>1),则为else{
hrSize=十二月格式(m).concat(“MB”);
}否则如果(k>1){
hrSize=dec.format(k).concat(“KB”);
}否则{
hrSize=dec.format(b).concat(“字节”);
}
返回hrSize;
}
@凌驾
公共编号fromString(String){
//TODO:从文本转换为数字
返回null;
}
});
场景=新场景(线条图,800600);
lineChart.getData().add(系列);
舞台场景;
stage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
}
Use@James\u D:如果你在评论中写下答案,这个问题将永远没有答案。没有人会写一个正确的答案,因为它是你评论的副本。除此之外,每个自愿帮助他人的人都会浪费时间研究这个问题,结果发现已经有了答案;-)我创建了一个示例,但在尝试运行它时出错:
java.lang.NumberFormatException:对于输入字符串:“615.2”
@Roland是的,很公平。没有时间写一个完整的答案(仍然没有)。如果你愿意,可以写一个完整的答案。@James\u D:从你给出的答案数量可以理解。行。
import java.text.DecimalFormat;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;
import javafx.util.StringConverter;
public class LineChartSample extends Application {
@Override
public void start(Stage stage) {
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
final LineChart<Number, Number> lineChart = new LineChart<Number, Number>(xAxis, yAxis);
XYChart.Series<Number,Number> series = new XYChart.Series<Number,Number>();
for (int i = 0; i < 10000000; i += 1000) {
series.getData().add(new XYChart.Data(i, i));
}
yAxis.setTickLabelFormatter(new StringConverter<Number>() {
@Override
public String toString(Number object) {
// conversion code from:
// http://stackoverflow.com/questions/13539871/converting-kb-to-mb-gb-tb-dynamicaly
double size = object.doubleValue();
String hrSize = null;
double b = size;
double k = size / 1024.0;
double m = ((size / 1024.0) / 1024.0);
double g = (((size / 1024.0) / 1024.0) / 1024.0);
double t = ((((size / 1024.0) / 1024.0) / 1024.0) / 1024.0);
DecimalFormat dec = new DecimalFormat("0.00");
if (t > 1) {
hrSize = dec.format(t).concat(" TB");
} else if (g > 1) {
hrSize = dec.format(g).concat(" GB");
} else if (m > 1) {
hrSize = dec.format(m).concat(" MB");
} else if (k > 1) {
hrSize = dec.format(k).concat(" KB");
} else {
hrSize = dec.format(b).concat(" Bytes");
}
return hrSize;
}
@Override
public Number fromString(String string) {
// TODO: convert from text to number
return null;
}
});
Scene scene = new Scene(lineChart, 800, 600);
lineChart.getData().add(series);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}