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);
    }
}