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显示了图表的相应区域。
您可以更改和设置这些元素的以下可视特性:
-
填充和插入
-
背景颜色和图像
-
字体
-
文本填充颜色
默认情况下,任何图表都有5像素的填充,其内容有10像素的填充。您可以使用.chart
和.chart-content
CSS类的-fx-padding
属性来更改这些值,如示例38-1所示。
图38-2显示了应用这些样式后的折线图的视图。
您可以为图表定义背景颜色或背景图像。添加-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中展示的折线图的图例具有默认的外观。您可以通过修改.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所示。
默认情况下,图例符号看起来像圆圈,因为它们被声明为带有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所示的外观。
修改图表绘图区的颜色
当您更改图表的默认背景颜色或将图像设置为图表背景时,这些更改不会影响图表本身。根据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 设置图表绘图区的透明背景
.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所示。
设置坐标轴
虽然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-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显示了当您修改图表刻度线的颜色和宽度时,坐标轴如何变化。
设置图表颜色
更改图表的默认颜色是为您的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 更改图表符号颜色
.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; }
当您更改面积图中的颜色时,请考虑三个图形组件:每个数据系列的面积,相应的边界线和图表符号。默认情况下,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展示了在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的外观。
在构建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中观察到新样式。
更改图表符号
尽管图表图例中显示的符号在modena样式表中定义,但您可以通过修改默认的颜色方案和符号形状来改变它们的外观。 示例38-11 改变了面积图符号的颜色。您可以添加以下行来将符号形状更改为正方形:.chart-area-symbol{-fx-background-radius: 0;}
。默认情况下,背景半径为5像素。将背景半径更改为0,将圆形变为正方形。此更改适用于所有数据系列,如图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所示,第二个系列的点将显示为勾号。其他系列的点将根据默认样式显示。
使用.chart-symbol
类为散点图中的所有数据系列设置新的图表符号,如示例38-18所示。
图38-17显示了一个包含七个数据系列的散点图。每个系列由不同颜色的勾号表示。每个系列的颜色来自modena样式表。
总之,当您需要为JavaFX应用程序中的图表设置样式时,请考虑以下步骤:
-
将一个 .css 文件添加到你的 JavaFX 应用程序中。
-
确定需要更改的图形元素。
-
确定相应的 CSS 类。
-
设置所选 CSS 类的属性,指定要达到所需外观的值。
有关如何使用 CSS 为你的 JavaFX 应用程序设置样式的更多信息,请参考使用 CSS 为 UI 控件设置样式。