32 折线图
本章介绍了折线图,一种将数据以一系列通过直线连接的点来呈现的双轴图表类型。
折线图通常用于展示特定时间间隔内数据的动态变化。图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-1中。
在图32-1中,坐标轴显示在其相对于图表绘图的默认位置。但是,您可以通过应用setSide方法将坐标轴显示在图表绘图的另一侧。 示例32-3演示了如何将水平轴移动到图表绘图的顶部。
创建线图的类别
使用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所示。
通常,线图可以在同一时间段内分析不同的数据集。在应用程序中使用多个XYChart.Data对象系列来实现这个任务。
向折线图添加系列
示例32-5提供了带有三个数据系列的股票监控应用程序的源代码。除了示例32-4中使用的系列之外,还声明了两个新的系列。
通过连续调用getData和addAll方法将系列分配给图表。
示例 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所示。
请注意,线条的不同颜色是由addAll方法中相应系列的声明顺序定义的。将顺序更改为:lineChart.getData().addAll(series3, series1, series2),然后编译和运行应用程序。修改后的输出如图32-5所示。
相关API文档

