java horizontalbarchart_DOC-03-36 柱状图(Bar Chart)

本教程详细介绍了如何在JavaFX中创建和自定义Bar Chart,包括水平柱状图和堆叠柱状图。通过示例代码展示了如何设置数据、调整Bar间距、改变Bar方向以及实现数据动画效果,适用于表示和比较不同类别间的数值数据。
摘要由CSDN通过智能技术生成

DOC-03-36 柱状图(Bar Chart)

本章将介绍柱状图(Bar Chart),一种带有矩形条(Rectangular bar)的双轴图表,Rectangular bar可以水平放置也可以竖垂直放置。

每个Bar的长度与图表表示的特定数据是成比例的。Bar Chart一般用来展示散列数据。你可以使用多组Bar来分类绘制数据,如图36-1所示。

图36-1 Bar Chart样例

3e2858c673921f844599d52cb42c7629.png

创建Bar Chart

要在你的JavaFX应用程序中创建Bar Chart,需要创建两个坐标轴、实例化BarClass类、定义数据序列并且把数据指定给Bar Chart。例36-1创建了一个有三组数据的Bar Chart来表示5个国家的金融数据。每个国家的数据被当作一个分类以水平坐标轴上的一组Bar来展示。

例36-1创建有3组数据的Bar Chart

Java

scene.getStylesheets().add("scaterchartsample/Chart.css");

1

scene.getStylesheets().add("scaterchartsample/Chart.css");

图36-2显示了此应用程序的运行结果。

图36-2创建有3组数据的bar chart

cbc31e92de4b3339269ef5552c42b369.png

BarChart类有两个属性分别控制着两个Category数据的间距和同Category数据中两个Bar之间的间距。使用barGap和categoryGap属性来使图表中的Bar更好地分布。例36-2使用setBarGap和setCategoryGap方法来为这两个属性设置了特定的值。

例36-2设置Bar之间和Category之间的间距

Java

bc.setBarGap(3);

bc.setCategoryGap(20);

1

2

bc.setBarGap(3);

bc.setCategoryGap(20);

水平柱状图(Horizontal Bar Chart)

你可以通过为纵轴定义Category将Bar Chart的方向由垂直变为水平。例36-3为Country Summary应用程序实现了这个需求。将横轴定义为NumberAxis类型,纵轴定义为CategoryAxis类型。不要忘了修改BarChart对象的声明。

例36-3改变Bar Chart的方向

Java

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.chart.BarChart;

import javafx.scene.chart.CategoryAxis;

import javafx.scene.chart.NumberAxis;

import javafx.scene.chart.XYChart;

import javafx.stage.Stage;

public class BarChartSample extends Application {

final static String austria = "Austria";

final static String brazil = "Brazil";

final static String france = "France";

final static String italy = "Italy";

final static String usa = "USA";

@Override public void start(Stage stage) {

stage.setTitle("Bar Chart Sample");

final NumberAxis xAxis = new NumberAxis();

final CategoryAxis yAxis = new CategoryAxis();

final BarChart bc =

new BarChart<>(xAxis,yAxis);

bc.setTitle("Country Summary");

xAxis.setLabel("Value");

xAxis.setTickLabelRotation(90);

yAxis.setLabel("Country");

XYChart.Series series1 = new XYChart.Series();

series1.setName("2003");

series1.getData().add(new XYChart.Data(25601.34, austria));

series1.getData().add(new XYChart.Data(20148.82, brazil));

series1.getData().add(new XYChart.Data(10000, france));

series1.getData().add(new XYChart.Data(35407.15, italy));

series1.getData().add(new XYChart.Data(12000, usa));

XYChart.Series series2 = new XYChart.Series();

series2.setName("2004");

series2.getData().add(new XYChart.Data(57401.85, austria));

series2.getData().add(new XYChart.Data(41941.19, brazil));

series2.getData().add(new XYChart.Data(45263.37, france));

series2.getData().add(new XYChart.Data(117320.16, italy));

series2.getData().add(new XYChart.Data(14845.27, usa));

XYChart.Series series3 = new XYChart.Series();

series3.setName("2005");

series3.getData().add(new XYChart.Data(45000.65, austria));

series3.getData().add(new XYChart.Data(44835.76, brazil));

series3.getData().add(new XYChart.Data(18722.18, france));

series3.getData().add(new XYChart.Data(17557.31, italy));

series3.getData().add(new XYChart.Data(92633.68, usa));

Scene scene = new Scene(bc,800,600);

bc.getData().addAll(series1, series2, series3);

stage.setScene(scene);

stage.show();

}

public static void main(String[] args) {

launch(args);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

importjavafx.application.Application;

importjavafx.scene.Scene;

importjavafx.scene.chart.BarChart;

importjavafx.scene.chart.CategoryAxis;

importjavafx.scene.chart.NumberAxis;

importjavafx.scene.chart.XYChart;

importjavafx.stage.Stage;

publicclassBarChartSampleextendsApplication{

finalstaticStringaustria="Austria";

finalstaticStringbrazil="Brazil";

finalstaticStringfrance="France";

finalstaticStringitaly="Italy";

finalstaticStringusa="USA";

@Overridepublicvoidstart(Stagestage){

stage.setTitle("Bar Chart Sample");

finalNumberAxisxAxis=newNumberAxis();

finalCategoryAxisyAxis=newCategoryAxis();

finalBarChartbc=

newBarChart<>(xAxis,yAxis);

bc.setTitle("Country Summary");

xAxis.setLabel("Value");

xAxis.setTickLabelRotation(90);

yAxis.setLabel("Country");

XYChart.Seriesseries1=newXYChart.Series();

series1.setName("2003");

series1.getData().add(newXYChart.Data(25601.34,austria));

series1.getData().add(newXYChart.Data(20148.82,brazil));

series1.getData().add(newXYChart.Data(10000,france));

series1.getData().add(newXYChart.Data(35407.15,italy));

series1.getData().add(newXYChart.Data(12000,usa));

XYChart.Seriesseries2=newXYChart.Series();

series2.setName("2004");

series2.getData().add(newXYChart.Data(57401.85,austria));

series2.getData().add(newXYChart.Data(41941.19,brazil));

series2.getData().add(newXYChart.Data(45263.37,france));

series2.getData().add(newXYChart.Data(117320.16,italy));

series2.getData().add(newXYChart.Data(14845.27,usa));

XYChart.Seriesseries3=newXYChart.Series();

series3.setName("2005");

series3.getData().add(newXYChart.Data(45000.65,austria));

series3.getData().add(newXYChart.Data(44835.76,brazil));

series3.getData().add(newXYChart.Data(18722.18,france));

series3.getData().add(newXYChart.Data(17557.31,italy));

series3.getData().add(newXYChart.Data(92633.68,usa));

Scenescene=newScene(bc,800,600);

bc.getData().addAll(series1,series2,series3);

stage.setScene(scene);

stage.show();

}

publicstaticvoidmain(String[]args){

launch(args);

}

}

需要注意上面调用了横轴的setTickLabelRotation方法来旋转Label以使文字更加易读。

修改后的程序运行结果如图36-3所示。

图36-3水平柱状图

6e0b37c16ace2baafedb9cc49dad4893.png

水平柱状图在你想要表示排名数据时会很有用。

创建堆叠柱状图(Stacked Bar Chart)

你可以让Bar Chart中属于同一个Category的Bar都堆叠起来。使用StackedBarChart类来完成,如例36-4所示。

例36-4创建Stacked Bar Chart

Java

import java.util.Arrays;

import javafx.application.Application;

import javafx.collections.FXCollections;

import javafx.scene.Scene;

import javafx.scene.chart.CategoryAxis;

import javafx.scene.chart.NumberAxis;

import javafx.scene.chart.StackedBarChart;

import javafx.scene.chart.XYChart;

import javafx.stage.Stage;

public class StackedBarChartSample extends Application {

final static String austria = "Austria";

final static String brazil = "Brazil";

final static String france = "France";

final static String italy = "Italy";

final static String usa = "USA";

final CategoryAxis xAxis = new CategoryAxis();

final NumberAxis yAxis = new NumberAxis();

final StackedBarChart sbc =

new StackedBarChart<>(xAxis, yAxis);

final XYChart.Series series1 =

new XYChart.Series<>();

final XYChart.Series series2 =

new XYChart.Series<>();

final XYChart.Series series3 =

new XYChart.Series<>();

@Override

public void start(Stage stage) {

stage.setTitle("Bar Chart Sample");

sbc.setTitle("Country Summary");

xAxis.setLabel("Country");

xAxis.setCategories(FXCollections.observableArrayList(

Arrays.asList(austria, brazil, france, italy, usa)));

yAxis.setLabel("Value");

series1.setName("2003");

series1.getData().add(new XYChart.Data<>(austria, 25601.34));

series1.getData().add(new XYChart.Data<>(brazil, 20148.82));

series1.getData().add(new XYChart.Data<>(france, 10000));

series1.getData().add(new XYChart.Data<>(italy, 35407.15));

series1.getData().add(new XYChart.Data<>(usa, 12000));

series2.setName("2004");

series2.getData().add(new XYChart.Data<>(austria, 57401.85));

series2.getData().add(new XYChart.Data<>(brazil, 41941.19));

series2.getData().add(new XYChart.Data<>(france, 45263.37));

series2.getData().add(new XYChart.Data<>(italy, 117320.16));

series2.getData().add(new XYChart.Data<>(usa, 14845.27));

series3.setName("2005");

series3.getData().add(new XYChart.Data<>(austria, 45000.65));

series3.getData().add(new XYChart.Data<>(brazil, 44835.76));

series3.getData().add(new XYChart.Data<>(france, 18722.18));

series3.getData().add(new XYChart.Data<>(italy, 17557.31));

series3.getData().add(new XYChart.Data<>(usa, 92633.68));

Scene scene = new Scene(sbc, 800, 600);

sbc.getData().addAll(series1, series2, series3);

stage.setScene(scene);

stage.show();

}

public static void main(String[] args) {

launch(args);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

importjava.util.Arrays;

importjavafx.application.Application;

importjavafx.collections.FXCollections;

importjavafx.scene.Scene;

importjavafx.scene.chart.CategoryAxis;

importjavafx.scene.chart.NumberAxis;

importjavafx.scene.chart.StackedBarChart;

importjavafx.scene.chart.XYChart;

importjavafx.stage.Stage;

publicclassStackedBarChartSampleextendsApplication{

finalstaticStringaustria="Austria";

finalstaticStringbrazil="Brazil";

finalstaticStringfrance="France";

finalstaticStringitaly="Italy";

finalstaticStringusa="USA";

finalCategoryAxisxAxis=newCategoryAxis();

finalNumberAxisyAxis=newNumberAxis();

finalStackedBarChartsbc=

newStackedBarChart<>(xAxis,yAxis);

finalXYChart.Seriesseries1=

newXYChart.Series<>();

finalXYChart.Seriesseries2=

newXYChart.Series<>();

finalXYChart.Seriesseries3=

newXYChart.Series<>();

@Override

publicvoidstart(Stagestage){

stage.setTitle("Bar Chart Sample");

sbc.setTitle("Country Summary");

xAxis.setLabel("Country");

xAxis.setCategories(FXCollections.observableArrayList(

Arrays.asList(austria,brazil,france,italy,usa)));

yAxis.setLabel("Value");

series1.setName("2003");

series1.getData().add(newXYChart.Data<>(austria,25601.34));

series1.getData().add(newXYChart.Data<>(brazil,20148.82));

series1.getData().add(newXYChart.Data<>(france,10000));

series1.getData().add(newXYChart.Data<>(italy,35407.15));

series1.getData().add(newXYChart.Data<>(usa,12000));

series2.setName("2004");

series2.getData().add(newXYChart.Data<>(austria,57401.85));

series2.getData().add(newXYChart.Data<>(brazil,41941.19));

series2.getData().add(newXYChart.Data<>(france,45263.37));

series2.getData().add(newXYChart.Data<>(italy,117320.16));

series2.getData().add(newXYChart.Data<>(usa,14845.27));

series3.setName("2005");

series3.getData().add(newXYChart.Data<>(austria,45000.65));

series3.getData().add(newXYChart.Data<>(brazil,44835.76));

series3.getData().add(newXYChart.Data<>(france,18722.18));

series3.getData().add(newXYChart.Data<>(italy,17557.31));

series3.getData().add(newXYChart.Data<>(usa,92633.68));

Scenescene=newScene(sbc,800,600);

sbc.getData().addAll(series1,series2,series3);

stage.setScene(scene);

stage.show();

}

publicstaticvoidmain(String[]args){

launch(args);

}

}

在程序中给Stacked Bar Chart定义坐标轴时,你必须要明确地把数据Category指定给某一个坐标轴。例36-4中,通过使用setCategories方法将Category指定给横轴。上例中的程序运行结果如图36-4所示。

图36-4有5组数据的Stacked Bar Chart

cfc8bb2c418fac8c25a0b15434c58bfc.png

比较图36-3和36-4中同样的数据。Stacked Bar Chart中的区域展示了横轴上任意点在纵轴上的累加值。例如,图36-4的纵轴上澳大利亚2004年的数据范围大概是25000到85000。但例36-4中澳大利亚2004年的数据是57401.85。图26-4中2004年的最高值85000表示澳大利亚2003和2004两年的累加值。

当你在程序中使用Bar Chart时,请记住BarChart和StackedBarChart中纵轴上的数据表示的含义是不一样的。要根应用据程序需求来选择最恰当的图表类型。

你可以通过调用setCategoryGap方法来指定两个Stacked Category之间的距离。例如,可以为Country Summary程序中的Bar Chart将该距离设置为50像素:sbc.setCategoryGap(50)。在例36-4中调用该方法以后,程序运行结果如图36-5所示。

图36-5指定Category的间距后的Stacked Bar Chart

ef48d5f42ff5832ef794319c6470137f.png

让图表中的数据动起来

你可以实现动画图表来说明金融活动的动态特性。例36-5定义了动画时间线并且创建了Key Frames来随机为Bar Chart的数据设置X值。时间线在程序开始时开始,并且在auto-reverse模式中无限的继续下去。

例36-5 Bar Chart中的动画数据

Java

Timeline tl = new Timeline();

tl.getKeyFrames().add(new KeyFrame(Duration.millis(500),

(ActionEvent actionEvent) -> {

bc.getData().stream().forEach((series) -> {

series.getData().stream().forEach((data) -> {

data.setXValue(Math.random() * 1000);

});

});

}

));

tl.setCycleCount(Animation.INDEFINITE);

tl.setAutoReverse(true);

tl.play();

1

2

3

4

5

6

7

8

9

10

11

12

13

14

Timelinetl=newTimeline();

tl.getKeyFrames().add(newKeyFrame(Duration.millis(500),

(ActionEventactionEvent)->{

bc.getData().stream().forEach((series)->{

series.getData().stream().forEach((data)->{

data.setXValue(Math.random()*1000);

});

});

}

));

tl.setCycleCount(Animation.INDEFINITE);

tl.setAutoReverse(true);

tl.play();

将上述代码片段加到例36-3中的Country Summary应用程序中,再次编译运行程序,你将看到坐标轴和绘制区域都会平滑地变化来适应Bar新的范围和长度。这是由Chart和Axis类的animated属性所致。该属性值默认为true来使任何数据改变都以动画形式展现。

在Country Summary应用程序中,当纵轴上的数据是以Category的形式表示并且不会改变时,你可以禁止该轴上的数据动画,以此来避免Country Lbel的闪烁。使用例36-6中所示的setAnimated方法。

例36-6管理数据变化的动画

Java

yAxis.setAnimated(false);

1

yAxis.setAnimated(false);

查看API文档来获取更多关于JavaFX图表特性的信息。

相关的API文档

· BarChart

· Chart

· XYChart

· Data

· Series

· Axis

· NumberAxis

· CategoryAxis

· Timeline

· KeyFrame

打赏一下

支付宝

微信

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值