文档



JavaFX:使用JavaFX UI组件

38 使用CSS样式化图表

本章介绍如何通过应用层叠样式表(CSS)来更改JavaFX图表的默认外观。了解如何更改图表的颜色方案,修改其图例或坐标轴,并改变图表符号。

JavaFX图表的所有可视元素都由modena样式表定义。JavaFX API具有有限的一组方法和属性来修改这些可视元素。Oracle建议您使用图表特定的CSS属性来为JavaFX应用程序中的图表实现替代的外观和感觉。

您可以在JavaFX CSS参考指南中找到完整的图表特定属性列表。当您将CSS样式应用于您的图表时,请参考使用CSS为JavaFX应用程序设计皮肤以获取实现细节。

修改基本图表元素

所有的JavaFX图表都有一些共同的属性,可以通过.chart.chart-content.chart-title.chart-legend CSS类来设置。图38-1显示了图表的相应区域。

图38-1 图表的可视元素

图38-1的描述如下
"图38-1 图表的可视元素"的描述

您可以更改和设置这些元素的以下可视特性:

  • 填充和插入

  • 背景颜色和图像

  • 字体

  • 文本填充颜色

默认情况下,任何图表都有5像素的填充,其内容有10像素的填充。您可以使用.chart.chart-content CSS类的-fx-padding属性来更改这些值,如示例38-1所示。

示例38-1 设置图表填充

.chart {
    -fx-padding: 10px;
}
.chart-content {
    -fx-padding: 30px;
}

图38-2显示了应用这些样式后的折线图的视图。

图38-2 设置图表顶级CSS属性

图38-2的描述如下
"图38-2 设置图表顶级CSS属性"的描述

您可以为图表定义背景颜色或背景图像。添加-fx-background-image属性,如示例38-2所示。

示例38-2 设置背景图像

.chart {
    -fx-padding: 10px;
    -fx-background-image: url("icon.png");
}
.chart-content {
    -fx-padding: 30px;
}

因为图标比折线图小,所以图像会重复填充剩余区域。在图38-3中展示了应用背景图像的折线图。

图38-3 带有背景图像的折线图

图38-3的描述如下
"图38-3 带有背景图像的折线图"的描述

图38-3中展示的折线图的图例具有默认的外观。您可以通过修改.chart-legend CSS类中定义的属性来改变其外观,如示例38-3所示。

示例38-3 设置图例

.chart {
    -fx-padding: 10px;
    -fx-background-image: url("icon.png");
}
.chart-content {
    -fx-padding: 30px;
    
}
.chart-legend {
   -fx-background-color:  transparent;
   -fx-padding: 20px;
}
 
.chart-legend-item-symbol{
   -fx-background-radius: 0;
}
 
.chart-legend-item{
    -fx-text-fill: #191970;
}

当您应用这些样式时,图例将以透明背景渲染,标签将以深蓝色绘制,并且图例符号变为正方形,如图38-4所示。

图38-4 改变图例

图38-4的描述如下
"图38-4 改变图例"的描述

默认情况下,图例符号看起来像圆圈,因为它们被声明为带有5像素高度、5像素宽度和5像素半径的圆角矩形。当您将半径明确设置为0时,圆圈变成了正方形。您还可以使用-fx-shape属性来定义图例符号。例如,以下行通过指定其SVG路径来创建一个三角形:-fx-shape: "M5,0 L10,8 L0,8 Z."

要修改图表文本元素,您应该使用示例38-4中显示的相应样式。 .chart-title 类设置图表标题的填充颜色和字体大小。 .axis-label 类定义了轴标签的填充颜色。

示例38-4 修改文本元素的颜色

.chart {
    -fx-padding: 10px;
    -fx-background-image: url("icon.png");   
}
.chart-content {
    -fx-padding: 30px;    
}
 
.chart-title {
  -fx-text-fill: #4682b4;
  -fx-font-size: 1.6em;
}
 
.axis-label {
  -fx-text-fill: #4682b4;
}
 
.chart-legend {
   -fx-background-color:  transparent;
   -fx-padding: 20px;
}
 
.chart-legend-item-symbol{
   -fx-background-radius: 0;
}
 
.chart-legend-item{
    -fx-text-fill: #191970;
}

这些修改会导致如图38-5所示的外观。

图38-5 修改文本元素的折线图

图38-5的描述如下
"图38-5 修改文本元素的折线图"的描述

修改图表绘图区的颜色

当您更改图表的默认背景颜色或将图像设置为图表背景时,这些更改不会影响图表本身。根据modena样式表的规定,双轴图表的图表绘图区具有浅灰色背景,其交替行为灰色。使用.chart-plot-background类的-fx-background-color-fx-background-image属性来设置图表绘图区的背景。 示例38-5定义了图表绘图区的背景颜色、交替行的填充颜色以及垂直和水平网格线的颜色。

示例38-5 设置图表绘图区的背景颜色

.chart {
    -fx-padding: 10px;
    -fx-background-image: url("icon.png");   
}
.chart-content {
    -fx-padding: 30px;    
}
 
.chart-title {
  -fx-text-fill: #4682b4;
  -fx-font-size: 1.6em;
}
 
.axis-label {
  -fx-text-fill: #4682b4;
}
 
.chart-legend {
   -fx-background-color:  transparent;
   -fx-padding: 20px;
}
 
.chart-legend-item-symbol{
   -fx-background-radius: 0;
}
 
.chart-legend-item{
    -fx-text-fill: #191970;
}
 
.chart-plot-background {
    -fx-background-color: #e2ecfe;
}
.chart-vertical-grid-lines {
    -fx-stroke: #3278fa;
}
.chart-horizontal-grid-lines {
    -fx-stroke: #3278fa;
}
.chart-alternative-row-fill {
    -fx-fill: #99bcfd;
    -fx-stroke: transparent;
    -fx-stroke-width: 0;
}

图38-6显示了具有修改后绘图区背景的折线图。

图38-6 具有替代绘图颜色的折线图

图38-6的描述
"图38-6 具有替代绘图颜色的折线图"的描述

当您设计图表时,使其绘图区与其他图表区域具有相同的背景时,请为绘图区和交替行设置透明背景,如示例38-6所示。

示例 38-6 设置图表绘图区的透明背景

.chart {
    -fx-padding: 10px;
    -fx-background-image: url("icon.png");   
}
.chart-content {
    -fx-padding: 30px;    
}
 
.chart-title {
  -fx-text-fill: #4682b4;
  -fx-font-size: 1.6em;
}
 
.axis-label {
  -fx-text-fill: #4682b4;
}
 
.chart-legend {
   -fx-background-color:  transparent;
   -fx-padding: 20px;
}
 
.chart-legend-item-symbol{
   -fx-background-radius: 0;
}
 
.chart-legend-item{
    -fx-text-fill: #191970;
}
 
.chart-plot-background {
    -fx-background-color: transparent;
}
.chart-vertical-grid-lines {
    -fx-stroke: #3278fa;
}
.chart-horizontal-grid-lines {
    -fx-stroke: #3278fa;
}
.chart-alternative-row-fill {
    -fx-fill: transparent;
    -fx-stroke: transparent;
    -fx-stroke-width: 0;
}

您可以通过在JavaFX应用程序中将setAlternativeRowFillVisible(false)方法应用于图表来使替代行不可见。

应用透明背景颜色后,图表将显示如图38-7所示。

图38-7 具有透明绘图区的折线图

图38-7的描述
"图38-7 具有透明绘图区的折线图"的描述

设置坐标轴

虽然Axis类提供了设置刻度线和标签的方法和属性,但是您可以使用相应的CSS类和属性来定义这些图表元素的外观。

考虑在气泡图章节中描述的气泡图示例。通过删除或注释掉示例34-4中的以下行来禁用刻度标签的颜色设置。

  • xAxis.setTickLabelFill(Color.CHOCOLATE);

  • yAxis.setTickLabelFill(Color.CHOCOLATE);

示例38-7中显示的代码片段添加到应用程序的CSS文件中。

示例38-7 定义图表坐标轴的样式

.axis {
    -fx-font-size: 1.4em;    
    -fx-tick-label-fill: #914800;
    -fx-font-family: Tahoma;
    -fx-tick-length: 20;
    -fx-minor-tick-length: 10;
}
 
.axis-label {
   -fx-text-fill: #462300; 
}

这个样式表定义了坐标轴标签和刻度标签的相对字体大小、字体族和填充颜色。它还设置了刻度线和次刻度线的长度。当这些样式应用到图表上时,它的外观如图38-8所示。

图38-8 修改坐标轴外观的气泡图

图38-8的描述
"图38-8 修改坐标轴外观的气泡图"的描述

示例38-7更改了刻度线和次刻度线的默认长度。您可以通过定义新的颜色方案继续改变它们的外观,如示例38-8所示。这个示例还为基本刻度线设置了3像素的宽度,使其看起来比次刻度线更粗。

示例38-8 改变刻度线和次刻度线的颜色

.axis {
    -fx-font-size: 1.4em;    
    -fx-tick-label-fill: #914800;
    -fx-font-family: Tahoma;
    -fx-tick-length: 20;
    -fx-minor-tick-length: 10;
}
 
.axis-label {
   -fx-text-fill: #462300; 
}
 
.axis-tick-mark {
    -fx-stroke: #637040;
    -fx-stroke-width: 3; 
}
.axis-minor-tick-mark {
    -fx-stroke: #859656;
}

图38-9显示了当您修改图表刻度线的颜色和宽度时,坐标轴如何变化。

图38-9 刻度线的替代颜色方案和宽度

图38-9的描述如下
"图38-9 刻度线的替代颜色方案和宽度"的描述

设置图表颜色

更改图表的默认颜色是为您的JavaFX应用程序提供独特样式的简单方法。本节介绍了设置基本类型图表的替代颜色的一些方面。

默认情况下,modena样式表定义了八种与前八个数据系列对应的线条颜色。当添加到线图中的数据系列数量超过八个时,额外线条的颜色在.chart-series-line CSS类中定义。

使用.chart-series-line类和.default-color<x>.chart-series-line类来更改线条的样式。在示例38-9中定义的样式设置了三个数据系列的新颜色,移除了默认效果,并指定了2像素的宽度。

示例38-9 在线图中设置三个系列的替代颜色

.chart-series-line {    
    -fx-stroke-width: 2px;
    -fx-effect: null;
}
 
.default-color0.chart-series-line { -fx-stroke: #e9967a; }
.default-color1.chart-series-line { -fx-stroke: #f0e68c; }
.default-color2.chart-series-line { -fx-stroke: #dda0dd; }

图38-10显示了应用此样式后的线图。

图38-10 修改后的线图

图38-10的描述
"图38-10 修改后的线图的描述"

请注意,图例仍显示图表系列的默认颜色。这是因为相应的更改未应用于图表符号。示例38-10展示了如何更改图例中系列的颜色。

示例38-10 更改图表符号颜色

.chart-series-line {    
    -fx-stroke-width: 2px;
    -fx-effect: null;
}
 
.default-color0.chart-series-line { -fx-stroke: #e9967a; }
.default-color1.chart-series-line { -fx-stroke: #f0e68c; }
.default-color2.chart-series-line { -fx-stroke: #dda0dd; }
 
.default-color0.chart-line-symbol { -fx-background-color: #e9967a, white; }
.default-color1.chart-line-symbol { -fx-background-color: #f0e68c, white; }
.default-color2.chart-line-symbol { -fx-background-color: #dda0dd, white; }

比较图38-10图38-11以观察图例的变化。

图38-11 带有修改颜色的线图和适当的图例符号

图38-11的描述如下
"图38-11 带有修改颜色的线图和适当的图例符号"的描述

当您更改面积图中的颜色时,请考虑三个图形组件:每个数据系列的面积,相应的边界线和图表符号。默认情况下,modena样式表为八个数据系列定义了一个颜色方案,包括它们的面积、线条和符号的颜色。默认样式还为额外的系列设置了面积、线条和符号的基本颜色。

示例38-11展示了如何更改与三个数据系列对应的默认颜色方案。

示例38-11 创建一个新的面积图颜色方案

.default-color0.chart-area-symbol { -fx-background-color: #e9967a, #ffa07a; }
.default-color1.chart-area-symbol { -fx-background-color: #f0e68c, #fffacd; }
.default-color2.chart-area-symbol { -fx-background-color: #dda0dd, #d8bfd8; }
 
.default-color0.chart-series-area-line { -fx-stroke: #e9967a; }
.default-color1.chart-series-area-line { -fx-stroke: #f0e68c; }
.default-color2.chart-series-area-line { -fx-stroke: #dda0dd; }
 
.default-color0.chart-series-area-fill { -fx-fill: #ffa07aaa}
.default-color1.chart-series-area-fill { -fx-fill: #fffacd77; }
.default-color2.chart-series-area-fill { -fx-fill: #d8bfd833; }

请注意加粗的值。这些加粗字符为面积的不透明度设置了新值。默认情况下,所有面积的不透明度级别为0.17。 示例38-11重新分配了面积的不透明度,使第一个面积具有最低的不透明度级别,第三个面积具有最高的不透明度级别。请注意,带有alpha的十六进制颜色语法不是标准的W3C CSS格式。为了符合W3C的要求,请使用带有第四个参数作为alpha值的rgba CSS函数。当应用这些样式时,图38-12展示了图表外观的变化。

图38-12 具有替代颜色方案的面积图

图38-12的描述如下
"图38-12 具有替代颜色方案的面积图"的描述

示例38-12展示了在modena样式表中定义的条形图中所有条形的基本样式。该样式为背景颜色创建了一个线性渐变,并设置了半径,使得所有条形的边缘看起来都是圆角的。

示例38-12 条形图的默认样式

.chart-bar {
    -fx-bar-fill: #22bad9;
    -fx-background-color: linear (0%,0%) to (0%,100%) 
        stops (0%, derive(-fx-bar-fill,-30%)) 
        (100%, derive(-fx-bar-fill,-40%)),
        linear (0%,0%) to (0%,100%) 
        stops (0%, derive(-fx-bar-fill,80%)) 
        (100%, derive(-fx-bar-fill, 0%)),
        linear (0%,0%) to (0%,100%) 
        stops (0%, derive(-fx-bar-fill,30%)) 
        (100%, derive(-fx-bar-fill,-10%));
    -fx-background-insets: 0,1,2;
    -fx-background-radius: 5 5 0 0, 4 4 0 0, 3 3 0 0;
}

背景设置不仅限于颜色、渐变和效果。您还可以为每个数据系列设置背景图像。要实现这种方法,首先按照示例38-13中所示简化BarChartSample应用程序。

示例38-13 简化的条形图示例

package barchartsample;
 
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 = "奥地利";
    final static String brazil = "巴西";
    final static String france = "法国";
    final static String italy = "意大利";
    final static String usa = "美国";
 
    @Override
    public void start(Stage stage) {
        stage.setTitle("条形图示例");
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
        final BarChart<String, Number> bc =
                new BarChart<String, Number>(xAxis, yAxis);
        bc.setTitle("国家摘要");
        xAxis.setLabel("国家");
        xAxis.setTickLabelRotation(90);
        yAxis.setLabel("值");
 
        XYChart.Series series1 = new XYChart.Series();
        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, 11000));
 
        Scene scene = new Scene(bc, 400, 600);
        bc.getData().add(series1);
        bc.setLegendVisible(false);
        stage.setScene(scene);
        scene.getStylesheets().add("barchartsample/Chart.css");
        stage.show();
    }
 
    public static void main(String[] args) {
        launch(args);
    }
}

现在按照示例38-14中所示定义图表样式表。

示例38-14 向柱状图背景添加图片

.chart-bar {
    -fx-background-color: rgba(0,168,355,0.05);
    -fx-border-color: rgba(0,168,355,0.3) rgba(0,168,355,0.3) 
        transparent rgba(0,168,355,0.3);
    -fx-background-radius: 0;
    -fx-background-position: left center;
}
 
.data0.chart-bar {
    -fx-background-image: url("austria.png");
}
.data1.chart-bar {
    -fx-background-image: url("brazil.png");
}
.data2.chart-bar {
    -fx-background-image: url("france.png");
}
.data3.chart-bar {
    -fx-background-image: url("italy.png");
}
.data4.chart-bar {
    -fx-background-image: url("usa.png");
}

这个样式为每个数据系列设置了一个背景图片,并定义了图片在柱状图中的位置。在应用新样式后,图38-13显示了BarChartSample的外观。

图38-13 使用图片填充柱状图

图38-13的描述
"图38-13 使用图片填充柱状图"的描述

在构建JavaFX应用程序中的饼图时,通常需要为饼图的扇区设置替代颜色。您可以通过设置.default-color<x>.chart-pie CSS类来重新定义默认颜色方案。示例38-15实现了这个任务。

示例38-15 设置饼图的颜色

.default-color0.chart-pie { -fx-pie-color: #ffd700; }
.default-color1.chart-pie { -fx-pie-color: #ffa500; }
.default-color2.chart-pie { -fx-pie-color: #860061; }
.default-color3.chart-pie { -fx-pie-color: #adff2f; }
.default-color4.chart-pie { -fx-pie-color: #ff5700; }
 
.chart-pie-label-line {
    -fx-stroke: #8b4513;
    -fx-fill: #8b4513;
}
 
.chart-pie-label {
    -fx-fill: #8b4513;
    -fx-font-size: 1em;
} 
.chart-legend {
   -fx-background-color:  #fafad2;
   -fx-stroke: #daa520;
}

现在饼图的颜色与它们所代表的水果的颜色相似。此外,示例38-15中的样式表为标签和图例设置了替代颜色。您可以在图38-14中观察到新样式。

图38-14 重新定义颜色的饼图

图38-14的描述如下
"图38-14 重新定义颜色的饼图"的描述

更改图表符号

尽管图表图例中显示的符号在modena样式表中定义,但您可以通过修改默认的颜色方案和符号形状来改变它们的外观。 示例38-11 改变了面积图符号的颜色。您可以添加以下行来将符号形状更改为正方形:.chart-area-symbol{-fx-background-radius: 0;}。默认情况下,背景半径为5像素。将背景半径更改为0,将圆形变为正方形。此更改适用于所有数据系列,如图38-15所示。

图38-15 修改后的面积图符号

图38-15的描述
"图38-15 修改后的面积图符号"的描述

在散点图中,所有数据都由一组点表示。每个数据系列都有其特殊的符号。默认情况下,modena样式为七个数据系列定义了七个符号,并为其他数据系列使用基本符号。 示例38-16 显示了散点图的默认样式。

示例38-16 在Modena样式表中定义的散点图样式

.chart-symbol { /* 实心圆 */
    -fx-background-color: CHART_COLOR_1;
    -fx-background-radius: 5px;
    -fx-padding: 5px;
}
.default-color1.chart-symbol { /* 实心正方形 */
    -fx-background-color: CHART_COLOR_2;
    -fx-background-radius: 0;
}
.default-color2.chart-symbol { /* 实心菱形 */
    -fx-background-color: CHART_COLOR_3;
    -fx-background-radius: 0;
    -fx-padding: 7px 5px 7px 5px;
    -fx-shape: "M5,0 L10,9 L5,18 L0,9 Z";
}
.default-color3.chart-symbol { /* 十字 */
    -fx-background-color: CHART_COLOR_4;
    -fx-background-radius: 0;
    -fx-background-insets: 0;
    -fx-shape: "M2,0 L5,4 L8,0 L10,0 L10,2 L6,5 L10,8 L10,10 L8,10 L5,6 L2,10 L0,10 L0,8 L4,5 L0,2 L0,0 Z";
}
.default-color4.chart-symbol { /* 实心三角形 */
    -fx-background-color: CHART_COLOR_5;
    -fx-background-radius: 0;
    -fx-background-insets: 0;
    -fx-shape: "M5,0 L10,8 L0,8 Z";
}
.default-color5.chart-symbol { /* 空心圆 */
    -fx-background-color: CHART_COLOR_6, white;
    -fx-background-insets: 0, 2;
    -fx-background-radius: 5px;
    -fx-padding: 5px;
}
.default-color6.chart-symbol { /* 空心正方形 */
    -fx-background-color: CHART_COLOR_7, white;
    -fx-background-insets: 0, 2;
    -fx-background-radius: 0;
}
.default-color7.chart-symbol { /* 空心菱形 */
    -fx-background-color: CHART_COLOR_8, white;
    -fx-background-radius: 0;
    -fx-background-insets: 0, 2.5;
    -fx-padding: 7px 5px 7px 5px;
    -fx-shape: "M5,0 L10,9 L5,18 L0,9 Z";
}

您可以使用这些CSS类和可用的CSS属性来更改散点图的符号,或者您可以自己发明符号来表示数据。

使用.default-color1.chart-symbol CSS类来更改第二个数据系列的符号的默认颜色和形状,如示例38-17所示。

示例38-17 重新定义第二个数据系列的形状

.default-color1.chart-symbol {
    -fx-background-color: #a9e200;
    -fx-shape: "M0,4 L2,4 L4,8 L7,0 L9,0 L4,11 Z";
}

当将此样式应用于散点图时,如图38-16所示,第二个系列的点将显示为勾号。其他系列的点将根据默认样式显示。

图38-16 使用新的勾号符号标识第二个数据系列的散点图

图38-16的描述如下
"图38-16 使用新的勾号符号标识第二个数据系列"的描述

使用.chart-symbol类为散点图中的所有数据系列设置新的图表符号,如示例38-18所示。

示例38-18 为散点图定义替代符号

.chart-symbol{ 
    -fx-shape: "M0,4 L2,4 L4,8 L7,0 L9,0 L4,11 Z";
}

图38-17显示了一个包含七个数据系列的散点图。每个系列由不同颜色的勾号表示。每个系列的颜色来自modena样式表。

图38-17 使用勾号作为图表符号的散点图

图38-17的描述如下
"图38-17 使用勾号作为图表符号的散点图"的描述

总之,当您需要为JavaFX应用程序中的图表设置样式时,请考虑以下步骤:

  • 将一个 .css 文件添加到你的 JavaFX 应用程序中。

  • 确定需要更改的图形元素。

  • 确定相应的 CSS 类。

  • 设置所选 CSS 类的属性,指定要达到所需外观的值。

有关如何使用 CSS 为你的 JavaFX 应用程序设置样式的更多信息,请参考使用 CSS 为 UI 控件设置样式

关闭窗口

目录

JavaFX:使用JavaFX UI组件

展开 折叠