文档



JavaFX:使用JavaFX UI组件

32 折线图

本章介绍了折线图,一种将数据以一系列通过直线连接的点来呈现的双轴图表类型。

折线图通常用于展示特定时间间隔内数据的动态变化。图32-1展示了一个具有三个数据系列的典型折线图。

图32-1 折线图示例

图32-1的描述如下
"图32-1 折线图示例"的描述

每个双轴图表都有两个轴、数据点的绘制和图例。您还可以为图表指定一个标题。

图表设置

对于每个图表,您可以指定标题及其相对于图表的位置。标题可以位于图表的顶部、右侧、左侧或底部。同样,您可以指定图表图例的位置。

对于双轴图表,您可以管理图表绘制的外观,即数据值对应的图形符号所呈现的图表区域。您可以设置替代列和行,水平和垂直网格线以及零线。

您可以通过定义以下设置来更改每个图表的默认外观:

  • 轴标签

  • 轴相对于图表绘制的位置

  • 轴范围的上下边界

  • 刻度线的最小和最大刻度、刻度线之间的间隔以及刻度标签

您还可以指定对轴及其范围的任何更改都将进行动画处理,或者可以启用轴自动根据数据确定其范围。

图表数据

XYChart类是所有双轴图表的超类,提供了构建面积图、折线图、柱状图、散点图和气泡图的基本功能。使用XYChart.Data类来指定这些类型图表的数据模型。xValue属性定义要在X轴上绘制的图表元素的值,yValue属性定义Y轴的值。您还可以为每个图表元素设置额外的值。该值可以以图表需要的任何方式绘制,或者可以用于存储有关图表元素的附加信息。例如,它可以用于定义气泡图的半径。

对于双轴图表,您可以使用XYChart.Series类定义多个数据系列。您还可以为每个系列分配一个特定的名称以在图表图例中显示。

创建折线图

要创建折线图,至少需要定义两个轴,通过实例化LineChart类创建LineChart对象,使用XYChart.Series类创建一个或多个数据系列,并将数据分配给图表。示例32-1实现了这些任务。

示例32-1 简单折线图

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;
 
 
public class LineChartSample extends Application {
 
    @Override public void start(Stage stage) {
        stage.setTitle("折线图示例");
        //定义轴
        final NumberAxis xAxis = new NumberAxis();
        final NumberAxis yAxis = new NumberAxis();
        xAxis.setLabel("月份");
        //创建图表
        final LineChart<Number,Number> lineChart = 
                new LineChart<Number,Number>(xAxis,yAxis);
                
        lineChart.setTitle("股票监控, 2010");
        //定义数据系列
        XYChart.Series series = new XYChart.Series();
        series.setName("我的投资组合");
        //填充数据系列
        series.getData().add(new XYChart.Data(1, 23));
        series.getData().add(new XYChart.Data(2, 14));
        series.getData().add(new XYChart.Data(3, 15));
        series.getData().add(new XYChart.Data(4, 24));
        series.getData().add(new XYChart.Data(5, 34));
        series.getData().add(new XYChart.Data(6, 36));
        series.getData().add(new XYChart.Data(7, 22));
        series.getData().add(new XYChart.Data(8, 45));
        series.getData().add(new XYChart.Data(9, 43));
        series.getData().add(new XYChart.Data(10, 17));
        series.getData().add(new XYChart.Data(11, 29));
        series.getData().add(new XYChart.Data(12, 25));
        
        Scene scene  = new Scene(lineChart,800,600);
        lineChart.getData().add(series);
       
        stage.setScene(scene);
        stage.show();
    }
 
    public static void main(String[] args) {
        launch(args);
    }
}

在这个示例中,使用NumberAxis类创建了垂直和水平轴,NumberAxis类是Axis类的子类,用于表示数值。在创建数据系列时,由于已经声明了X轴和Y轴是数值类型,因此在创建XYChart.Data对象时应指定Number参数。XYChart.Data对象的第一个参数定义了水平轴的值,而第二个参数定义了垂直轴的值。

编译和运行此应用程序的结果如图32-2所示。

图32-2 带有一个数据系列的折线图

图32-2的描述
"图32-2 带有一个数据系列的折线图"的描述

图32-2中显示的折线图使用符号突出显示图表上的每个数据项。如果您想在折线图上显示趋势而不是具体的数据值,可以禁用图表符号,如示例32-2所示。

示例32-2 禁用折线图的符号

lineChart.setCreateSymbols(false);

趋势图的示例显示在图32-1中。

图32-1中,坐标轴显示在其相对于图表绘图的默认位置。但是,您可以通过应用setSide方法将坐标轴显示在图表绘图的另一侧。 示例32-3演示了如何将水平轴移动到图表绘图的顶部。

示例32-3 指定轴的位置

xAxis.setSide(Side.TOP);

创建线图的类别

使用CategoryAxis类而不是NumberAxis类来在线图中呈现非数字数据。

查看示例32-4中显示的应用程序的修改代码。它通过实例化CategoryAxis类来创建水平轴。修改了LineChart对象的声明以适应X轴类型的更改。

示例32-4 使用类别轴显示月份

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;
 
 
public class LineChartSample extends Application {
 
    @Override public void start(Stage stage) {
        stage.setTitle("线图示例");
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
        xAxis.setLabel("月份");       
        
        final LineChart<String,Number> lineChart = 
                new LineChart<String,Number>(xAxis,yAxis);
                
        lineChart.setTitle("股票监控, 2010");
                                
        XYChart.Series series = new XYChart.Series();
        series.setName("我的投资组合");
        
        series.getData().add(new XYChart.Data("一月", 23));
        series.getData().add(new XYChart.Data("二月", 14));
        series.getData().add(new XYChart.Data("三月", 15));
        series.getData().add(new XYChart.Data("四月", 24));
        series.getData().add(new XYChart.Data("五月", 34));
        series.getData().add(new XYChart.Data("六月", 36));
        series.getData().add(new XYChart.Data("七月", 22));
        series.getData().add(new XYChart.Data("八月", 45));
        series.getData().add(new XYChart.Data("九月", 43));
        series.getData().add(new XYChart.Data("十月", 17));
        series.getData().add(new XYChart.Data("十一月", 29));
        series.getData().add(new XYChart.Data("十二月", 25));
        
        
        Scene scene  = new Scene(lineChart,800,600);
        lineChart.getData().add(series);
       
        stage.setScene(scene);
        stage.show();
    }
 
    public static void main(String[] args) {
        launch(args);
    }
}

XYChartData对象包含月份名称和相应的数值。水平轴的标签会相应地进行修改。

编译和运行修改后的应用程序的结果如图32-3所示。

图32-3 水平分类轴

图32-3的描述
"图32-3 水平分类轴"的描述

通常,线图可以在同一时间段内分析不同的数据集。在应用程序中使用多个XYChart.Data对象系列来实现这个任务。

向折线图添加系列

示例32-5提供了带有三个数据系列的股票监控应用程序的源代码。除了示例32-4中使用的系列之外,还声明了两个新的系列。

通过连续调用getDataaddAll方法将系列分配给图表。

示例 32-5 向股票监控示例中添加两个系列

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;
 
 
public class LineChartSample extends Application {
 
    @Override public void start(Stage stage) {
        stage.setTitle("折线图示例");
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
         xAxis.setLabel("月份");
        final LineChart<String,Number> lineChart = 
                new LineChart<String,Number>(xAxis,yAxis);
       
        lineChart.setTitle("股票监控, 2010");
                          
        XYChart.Series series1 = new XYChart.Series();
        series1.setName("投资组合 1");
        
        series1.getData().add(new XYChart.Data("一月", 23));
        series1.getData().add(new XYChart.Data("二月", 14));
        series1.getData().add(new XYChart.Data("三月", 15));
        series1.getData().add(new XYChart.Data("四月", 24));
        series1.getData().add(new XYChart.Data("五月", 34));
        series1.getData().add(new XYChart.Data("六月", 36));
        series1.getData().add(new XYChart.Data("七月", 22));
        series1.getData().add(new XYChart.Data("八月", 45));
        series1.getData().add(new XYChart.Data("九月", 43));
        series1.getData().add(new XYChart.Data("十月", 17));
        series1.getData().add(new XYChart.Data("十一月", 29));
        series1.getData().add(new XYChart.Data("十二月", 25));
        
        XYChart.Series series2 = new XYChart.Series();
        series2.setName("投资组合 2");
        series2.getData().add(new XYChart.Data("一月", 33));
        series2.getData().add(new XYChart.Data("二月", 34));
        series2.getData().add(new XYChart.Data("三月", 25));
        series2.getData().add(new XYChart.Data("四月", 44));
        series2.getData().add(new XYChart.Data("五月", 39));
        series2.getData().add(new XYChart.Data("六月", 16));
        series2.getData().add(new XYChart.Data("七月", 55));
        series2.getData().add(new XYChart.Data("八月", 54));
        series2.getData().add(new XYChart.Data("九月", 48));
        series2.getData().add(new XYChart.Data("十月", 27));
        series2.getData().add(new XYChart.Data("十一月", 37));
        series2.getData().add(new XYChart.Data("十二月", 29));
        
        XYChart.Series series3 = new XYChart.Series();
        series3.setName("投资组合 3");
        series3.getData().add(new XYChart.Data("一月", 44));
        series3.getData().add(new XYChart.Data("二月", 35));
        series3.getData().add(new XYChart.Data("三月", 36));
        series3.getData().add(new XYChart.Data("四月", 33));
        series3.getData().add(new XYChart.Data("五月", 31));
        series3.getData().add(new XYChart.Data("六月", 26));
        series3.getData().add(new XYChart.Data("七月", 22));
        series3.getData().add(new XYChart.Data("八月", 25));
        series3.getData().add(new XYChart.Data("九月", 43));
        series3.getData().add(new XYChart.Data("十月", 44));
        series3.getData().add(new XYChart.Data("十一月", 45));
        series3.getData().add(new XYChart.Data("十二月", 44));
        
        Scene scene  = new Scene(lineChart,800,600);       
        lineChart.getData().addAll(series1, series2, series3);
       
        stage.setScene(scene);
        stage.show();
    }
 
 
    public static void main(String[] args) {
        launch(args);
    }
}

每个数据系列都有一个唯一的名称,可以使用setName方法来定义。

编译和运行此应用程序的结果如图32-4所示。

图32-4 带有三个数据系列的股票监控示例

图32-4的描述如下
"图32-4 带有三个数据系列的股票监控示例"的描述

请注意,线条的不同颜色是由addAll方法中相应系列的声明顺序定义的。将顺序更改为:lineChart.getData().addAll(series3, series1, series2),然后编译和运行应用程序。修改后的输出如图32-5所示。

图32-5 线图中系列的替代顺序

图32-5的描述如下
"图32-5 线图中系列的替代顺序"的描述

相关API文档 

关闭窗口

目录

JavaFX:使用JavaFX UI组件

展开 折叠