在显示日期的线路图的工具提示 [英] Tooltip on Line Chart showing Date

查看:367
本文介绍了在显示日期的线路图的工具提示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在图表线上移动光标时添加工具提示。我发现这个例子:

  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.scene.Scene;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;


public class AnimatedLineChart extends应用程序{

private static final int MAX_DATA_POINTS = 50;
private int xSeriesData = 0;
private XYChart.Series series1;
private XYChart.Series series2;
private XYChart.Series series3;
private ExecutorService executor;
private AddToQueue addToQueue;
private ConcurrentLinkedQueue< Number> dataQ1 = new ConcurrentLinkedQueue< Number>();
private ConcurrentLinkedQueue< Number> dataQ2 = new ConcurrentLinkedQueue< Number>();
private ConcurrentLinkedQueue< Number> dataQ3 = new ConcurrentLinkedQueue< Number>();

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


xAxis.setTickLabelsVisible(false);
xAxis.setTickMarkVisible(false);
xAxis.setMinorTickVisible(false);

NumberAxis yAxis = new NumberAxis();
yAxis.setAutoRanging(true);

// - Chart
final LineChart< Number,Number> sc = new LineChart< Number,Number>(xAxis,yAxis){
//覆盖以删除每个数据点上的符号
@Override protected void dataItemAdded(Series< Number,Number> series,int itemIndex, Data< Number,Number> item){}
};
sc.setAnimated(false);
sc.setId(liveLineeChart);
sc.setTitle(Animated Line Chart);

// - 图表系列
series1 = new XYChart.Series< Number,Number>();
series2 = new XYChartSeries< Number,Number>();
series3 = new XYChart.Series< Number,Number>();
sc.getData()。addAll(series1,series2,series3);

primaryStage.setScene(new Scene(sc));
}





@Override public void start(Stage Stage){
stage.setTitle(图表样本);
init(stage);
stage.show();


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);
// - 准备时间轴
prepareTimeline();


}

private class AddToQueue implements Runnable {
public void run(){
try {
// add一个随机数据到队列
dataQ1.add(Math.random());
dataQ2.add(Math.random());
dataQ3.add(Math.random());

Thread.sleep(500);
executor.execute(this);
} catch(InterruptedException ex){
ex.printStackTrace();
}
}
}

// - 在JavaFX主线程中调用时间线
private void prepareTimeline(){
/ /每一帧从队列中取任何数据并添加到图表
new AnimationTimer(){
@Override public void handle(long now){
addDataToSeries();
}
} .start();
}

private void addDataToSeries(){
for(int i = 0; i <20; i ++){// - 向绘图添加20个数字+
if(dataQ1.isEmpty())break;
series1.getData()。add(new AreaChart.Data(xSeriesData ++,dataQ.remove()));
series2.getData()。add(new AreaChart.Data(xSeriesData ++,dataQ2.remove()));
series3.getData()。add(new AreaChart.Data(xSeriesData ++,dataQ3.remove()));
}
//删除点以使我们不超过MAX_DATA_POINTS
if(series1.getData()。size()> MAX_DATA_POINTS){
series1.getData() .remove(0,series1.getData()。size() - MAX_DATA_POINTS);
}
if(series2.getData()。size()> MAX_DATA_POINTS){
series2.getData()。remove(0,series2.getData()。size() - MAX_DATA_POINTS );
}
if(series3.getData()。size()> MAX_DATA_POINTS){
series3.getData()。remove(0,series3.getData()。size() - MAX_DATA_POINTS );
}
// update
xAxis.setLowerBound(xSeriesData-MAX_DATA_POINTS);
xAxis.setUpperBound(xSeriesData-1);
}


public static void main(String [] args){
launch(args);
}
}

例如,我想显示如下:



>



JavaFX 8是否可能?鼠标悬停时显示 Date



有没有类似的例子可以用于我的情况? / p>

解决方案

我已经设法拉近了你想要的东西。看看下面的图片





我使用了 DateAxis 用于在X轴上填充日期,以及Y轴上的事件。一旦数据填充在LineChart中,遍历其数据并在每个节点上应用工具提示。



我也使用了 styleclass mouseEntered 上应用图像上显示的效果。 mouseExit



请移除此类别 / p>

ToolTipOnLineChart.java

  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.scene.control.Tooltip;
import javafx.stage.Stage;

import java.text.ParseException;
import java.text.SimpleDateFormat
import java.util.Date;

public class ToolTipOnLineChart extends应用程序{

@SuppressWarnings({unchecked,rawtypes})
@Override
public void start阶段)throws ParseException {
stage.setTitle(Line Chart Sample);
final DateAxis xAxis = new DateAxis();
final NumberAxis yAxis = new NumberAxis();
xAxis.setLabel(Date);
yAxis.setLabel(Events);

final LineChart< Date,Number> lineChart = new LineChart<>(xAxis,yAxis);
lineChart.setTitle(Events);

SimpleDateFormat dateFormat = new SimpleDateFormat(dd / MMM / yyyy);


XYChart.Series< Date,Number> series = new XYChart.Series<>();
series.setName(Events this Year);
series.getData()。add(new XYChart.Data(dateFormat.parse(11 / Jan / 2014),23));
series.getData()。add(new XYChart.Data(dateFormat.parse(09 / Feb / 2014),14));
series.getData()。add(new XYChart.Data(dateFormat.parse(22 / Mar / 2014),15));
series.getData()。add(new XYChart.Data(dateFormat.parse(14 / Apr / 2014),24)
series.getData()。add(new XYChart.Data(dateFormat.parse(22 / May / 2014),34)
series.getData()。add(new XYChart.Data(dateFormat.parse(07 / Jun / 2014),36));
series.getData()。add(new XYChart.Data(dateFormat.parse(22 / Jul / 2014),22));
series.getData()。add(new XYChart.Data(dateFormat.parse(21 / Aug / 2014),45));
series.getData()。add(new XYChart.Data(dateFormat.parse(04 / Sep / 2014),43));
series.getData()。add(new XYChart.Data(dateFormat.parse(22 / Oct / 2014),17));
series.getData()。add(new XYChart.Data(dateFormat.parse(30 / Nov / 2014),29)
series.getData()。add(new XYChart.Data(dateFormat.parse(10 / Dec / 2014),25));


场景scene = new Scene(lineChart,800,600);
scene.getStylesheets()。add(getClass()。getResource(chart.css)。toExternalForm());
lineChart.getData()。add(series);
stage.setScene(scene);
stage.show();

/ **
*浏览数据并应用ToolTip
*以及悬停时的类
* /
(XYChart.Series< ; Date,Number> s:lineChart.getData()){
for(XYChart.Data< Date,Number> d:s.getData()){
Tooltip.install(d.getNode ,new tooltip(
d.getXValue()。toString()+\\\
+
Number of Events:+ d.getYValue()));

//在悬停时添加类
d.getNode()。setOnMouseEntered(event - > d.getNode()。getStyleClass()。add(onHover));

//在退出时删除类
d.getNode()。setOnMouseExited(event - > d.getNode()。getStyleClass()。remove(onHover));
}
}
}

public static void main(String [] args){
launch(args);
}
}

chart.css / p>

  .onHover {
-fx-background-color:ORANGE;
}


I want to add Tooltip when I move cursor over a chart line. I found this example:

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.scene.Scene;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;


public class AnimatedLineChart extends Application {

    private static final int MAX_DATA_POINTS = 50;
    private int xSeriesData = 0;
    private XYChart.Series series1;
    private XYChart.Series series2;
    private XYChart.Series series3;
    private ExecutorService executor;
    private AddToQueue addToQueue;
    private ConcurrentLinkedQueue<Number> dataQ1 = new ConcurrentLinkedQueue<Number>();
    private ConcurrentLinkedQueue<Number> dataQ2 = new ConcurrentLinkedQueue<Number>();
    private ConcurrentLinkedQueue<Number> dataQ3 = new ConcurrentLinkedQueue<Number>();

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


        xAxis.setTickLabelsVisible(false);
        xAxis.setTickMarkVisible(false);
        xAxis.setMinorTickVisible(false);

        NumberAxis yAxis = new NumberAxis();
        yAxis.setAutoRanging(true);

        //-- Chart
        final LineChart<Number, Number> sc = new LineChart<Number, Number>(xAxis, yAxis) {
            // Override to remove symbols on each data point
            @Override protected void dataItemAdded(Series<Number, Number> series, int itemIndex, Data<Number, Number> item) {}
        };
        sc.setAnimated(false);
        sc.setId("liveLineeChart");
        sc.setTitle("Animated Line Chart");

        //-- Chart Series
        series1 = new XYChart.Series<Number, Number>();
        series2 = new XYChart.Series<Number, Number>();
        series3 = new XYChart.Series<Number, Number>();
        sc.getData().addAll(series1, series2, series3);

        primaryStage.setScene(new Scene(sc));
    }





    @Override public void start(Stage stage) {
        stage.setTitle("Animated Line Chart Sample");
        init(stage);
        stage.show();


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


    }

    private class AddToQueue implements Runnable {
        public void run() {
            try {
                // add a item of random data to queue
                dataQ1.add(Math.random());
                dataQ2.add(Math.random());
                dataQ3.add(Math.random());

                Thread.sleep(500);
                executor.execute(this);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

  //-- 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 (dataQ1.isEmpty()) break;
            series1.getData().add(new AreaChart.Data(xSeriesData++, dataQ1.remove()));
            series2.getData().add(new AreaChart.Data(xSeriesData++, dataQ2.remove()));
            series3.getData().add(new AreaChart.Data(xSeriesData++, dataQ3.remove()));
        }
        // remove points to keep us at no more than MAX_DATA_POINTS
        if (series1.getData().size() > MAX_DATA_POINTS) {
            series1.getData().remove(0, series1.getData().size() - MAX_DATA_POINTS);
        }
        if (series2.getData().size() > MAX_DATA_POINTS) {
            series2.getData().remove(0, series2.getData().size() - MAX_DATA_POINTS);
        }
        if (series3.getData().size() > MAX_DATA_POINTS) {
            series3.getData().remove(0, series3.getData().size() - MAX_DATA_POINTS);
        }
        // update 
        xAxis.setLowerBound(xSeriesData-MAX_DATA_POINTS);
        xAxis.setUpperBound(xSeriesData-1);
    }


    public static void main(String[] args) {
        launch(args);
    }
}

For example I would like to display something like this:

Is this possible with JavaFX 8? On mouse hover it is showing Date.

Is there any similar example that I can use for my case?

解决方案

I have managed to pull something very close to what you want. Have a look at the image below

I have used DateAxis for populating date on X-axis, along with events on Y-axis. Once the data is populated in the LineChart, iterate through its data and apply a tooltip on each node.

I have also used a styleclass on mouseEntered to apply the effect as shown on the image. This styleclass is removed on mouseExit

Have a look at the code below :

ToolTipOnLineChart.java

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.scene.control.Tooltip;
import javafx.stage.Stage;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ToolTipOnLineChart extends Application {

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public void start(Stage stage) throws ParseException {
        stage.setTitle("Line Chart Sample");
        final DateAxis xAxis = new DateAxis();
        final NumberAxis yAxis = new NumberAxis();
        xAxis.setLabel("Date");
        yAxis.setLabel("Events");

        final LineChart<Date,Number> lineChart = new LineChart<>(xAxis, yAxis);
        lineChart.setTitle("Events");

        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MMM/yyyy");


        XYChart.Series<Date,Number> series = new XYChart.Series<>();
        series.setName("Events this Year");
        series.getData().add(new XYChart.Data(dateFormat.parse("11/Jan/2014"), 23));
        series.getData().add(new XYChart.Data(dateFormat.parse("09/Feb/2014"), 14));
        series.getData().add(new XYChart.Data(dateFormat.parse("22/Mar/2014"), 15));
        series.getData().add(new XYChart.Data(dateFormat.parse("14/Apr/2014"), 24));
        series.getData().add(new XYChart.Data(dateFormat.parse("22/May/2014"), 34));
        series.getData().add(new XYChart.Data(dateFormat.parse("07/Jun/2014"), 36));
        series.getData().add(new XYChart.Data(dateFormat.parse("22/Jul/2014"), 22));
        series.getData().add(new XYChart.Data(dateFormat.parse("21/Aug/2014"), 45));
        series.getData().add(new XYChart.Data(dateFormat.parse("04/Sep/2014"), 43));
        series.getData().add(new XYChart.Data(dateFormat.parse("22/Oct/2014"), 17));
        series.getData().add(new XYChart.Data(dateFormat.parse("30/Nov/2014"), 29));
        series.getData().add(new XYChart.Data(dateFormat.parse("10/Dec/2014"), 25));


        Scene scene  = new Scene(lineChart,800,600);
        scene.getStylesheets().add(getClass().getResource("chart.css").toExternalForm());
        lineChart.getData().add(series);
        stage.setScene(scene);
        stage.show();

        /**
         * Browsing through the Data and applying ToolTip
         * as well as the class on hover
         */
        for (XYChart.Series<Date, Number> s : lineChart.getData()) {
            for (XYChart.Data<Date, Number> d : s.getData()) {
                Tooltip.install(d.getNode(), new Tooltip(
                        d.getXValue().toString() + "\n" +
                                "Number Of Events : " + d.getYValue()));

                //Adding class on hover
                d.getNode().setOnMouseEntered(event -> d.getNode().getStyleClass().add("onHover"));

                //Removing class on exit
                d.getNode().setOnMouseExited(event -> d.getNode().getStyleClass().remove("onHover"));
            }
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

chart.css

.onHover{
    -fx-background-color: ORANGE;
}

这篇关于在显示日期的线路图的工具提示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆