JFreeChart| 多轴和数据源图表(Multi Axis and Dataset)

前言

JFreeChart在CategoryPlot和XYPlot类中支持多轴和数据源显示。 我们利用这个特征可以在一个图表上显示两个或多个数据源数据,但对于数据包含的数据有巨大差距时留有一定的余地。

典型的,使用JFreeChart构建图表时,图表有一个单数据源、 单renderer、 单X/Y轴的图区最为常见。 然而,在一个图区上添加多个数据源、 多个renderer和多个轴也是可能的。 在本文实例中,展示了如何在一个图区上显示其他额外的数据源、 renderer和轴。

建议
当我们使用多轴图表时,我们需要为系列对应的轴提供一些可视化的建议。 比如在例子DualAxisDemo -Yves中轴标签的颜色与系列颜色是相匹配的,这样是为了能够区分每个图的X轴与对应图表渲染结果之间的关系.


一.多轴图效果图

多轴图是支持同种类型的图不同种类型的图的.(主要是共用x轴,通过添加Y轴的方式来实现的,多余不同类型的图表的多轴图,需要指定底部的图例显示,不然默认不显示图例),下面是两种不同的显示效果.
这里写图片描述

这里写图片描述


二.多轴图示例

建立多轴图表可以设置的项目

  • 创建一个主图表
  • 添加一个额外的轴
  • 添加一个额外的数据源
  • 添加一个额外的renderer
  • 设置图例显示

1.创建一个图表

创建一个具有多轴、 多数据源、 多renderer的图表,我们首先要创建一个常规的图表(例如使用ChartFactory类创建)。 在本实例中,创建了一个时序图,代码如下:

XYDataset dataset1 = createDataset("Series 1", 100.0, new Minute(), 200);
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Multiple Axis Demo -Yves",
"Time of Day",
"Primary Range Axis",
dataset1,
true,
true,
false
);

2.添加额外的轴

如果在图区上添加额外的轴,我们使用setRangeAxis()方法来添加:

NumberAxis numberaxis = new NumberAxis("Range Axis 2"); 
xyplot.setRangeAxis(1, numberaxis);
xyplot.setRangeAxisLocation(1, AxisLocation.BOTTOM_OR_LEFT);

方法setRangeAxis()是用来添加图区的轴,注意轴的索引1已经被使用——我们添加其他轴时,通过增加该索引来添加新轴。(我们可以理解成主轴是从0开始,添加的额外的轴索引从1开始,一次递增1)

方法setRangeAxisLocation()允许我们指定轴出现的位置(使用AxisLocation类)。 我们添加的轴可以跟主坐标轴同一边,或者在对立边。
例如:如果指定的是AxisLocation.BOTTOM_OR_LEFT,这意味着如果图区的方向是垂直的话,将在右边添加了一个Y轴,如果图区的方向是水平的话,将在底部添加一个Y轴。

值得注意的是:

  • 如果我们没有使用setRangeAxis将额外的轴添加到plot上,即使设置了数据源原也是不会显示该图表的.
  • 如果我们使用setRangeAxis将额外的轴添加到plot上,即使数据源没有数据,添加的坐标轴也是会显示的.

3.添加一个额外的数据源

在图区上添加一个额外的数据源,使用setDataset()方法:

XYDataset xydataset_0_ = createDataset("Series 2", 1000.0,
new Minute(), 170);
xyplot.setDataset(1, xydataset_0_);

缺省的,数据源将使用主轴来显示数据。 如果使数据源在另外的轴上显示数据,需使用方法mapDatasetToRangeAxis(int index, int axisIndex)mapDatasetToDomainAxis(int index, int axisIndex)。 这两个方法接受两个参数,第一个参数是数据源的索引,第二个是轴的索引.

针对plot.setOrientation(PlotOrientation.VERTICAL);垂直显示的图表,我们使用mapDatasetToRangeAxis(int index, int axisIndex)``,反之用 mapDatasetToDomainAxis(int index, int axisIndex)`

4.添加一个额外的renderer

当我们添加一个数据源时,通常为该数据源添加一个附加的renderer也是非常有意义的。 使用方法setRenderer():

StandardXYItemRenderer standardxyitemrenderer = new StandardXYItemRenderer();
xyplot.setRenderer(1, standardxyitemrenderer);

方法的第一个参数为xyplot.setDataset(1, xydataset_0_);中添加的数据源的索引。 注意:如果我们不想为数据源指定一个附加的rendere,系统将默认使用主renderer,这样系列的颜色就会在主数据源和附加数据源之间共享。


附录

    private static JFreeChart createChart() {
        XYDataset dataset = createDataset("Series 1", 100.0D, new Minute(), 200);

        JFreeChart chart = ChartFactory.createTimeSeriesChart("Multiple Axis Demo -Yves", "Time of Day", "Primary Range Axis", dataset, true, true, false);
        chart.addSubtitle(new TextTitle("Four datasets and four range axes."));// 子标题

        /** chart主题立即生效 **/
        // 将当前主题应用于指定的图表。 提供此方法是为了方便,主题本身存储在ChartFactory类中。
        // 可以理解流程主题中有对Renderer修饰的一系列属性,会覆盖之前以前的设置
        ChartUtilities.applyCurrentTheme(chart);

        XYPlot plot = (XYPlot) chart.getPlot();
        plot.setOrientation(PlotOrientation.VERTICAL);
        plot.setDomainPannable(true);// x轴自动增长
        plot.setRangePannable(true);// y轴自动增长
        plot.getRenderer().setSeriesPaint(0, Color.BLACK);// 设置主plot为黑色

        // 主Plot是从0开始,其他的Plot从1开始
        // 1
        NumberAxis axis1 = new NumberAxis("Range Axis 2");
        axis1.setAutoRangeIncludesZero(false);
        plot.setRangeAxis(1, axis1);// 添加到Y轴上
        plot.setRangeAxisLocation(1, AxisLocation.BOTTOM_OR_LEFT);// 设置坐标轴位置
        XYDataset dataset2 = createDataset("Series 2", 1000.0D, new Minute(), 170);
        plot.setDataset(1, dataset2);
        plot.mapDatasetToRangeAxis(1, 1);
        StandardXYItemRenderer renderer1 = new StandardXYItemRenderer();
        plot.setRenderer(1, renderer1);

        renderer1.setSeriesPaint(0, Color.red);
        axis1.setLabelPaint(Color.red);
        axis1.setTickLabelPaint(Color.red);

        // 2
        NumberAxis axis2 = new NumberAxis("Range Axis 3");
        plot.setRangeAxis(2, axis2);
        XYDataset dataset3 = createDataset("Series 3", 10000.0D, new Minute(), 170);
        plot.setDataset(2, dataset3);
        plot.mapDatasetToRangeAxis(2, 2);
        StandardXYItemRenderer renderer2 = new StandardXYItemRenderer();
        plot.setRenderer(2, renderer2);

        renderer2.setSeriesPaint(0, Color.blue);
        axis2.setLabelPaint(Color.blue);
        axis2.setTickLabelPaint(Color.blue);

        // 3
        NumberAxis axis3 = new NumberAxis("Range Axis 4");
        plot.setRangeAxis(3, axis3);
        XYDataset dataset4 = createDataset("Series 4", 25.0D, new Minute(), 200);
        plot.setDataset(3, dataset4);
        plot.mapDatasetToRangeAxis(3, 3);
        StandardXYItemRenderer renderer3 = new StandardXYItemRenderer();
        plot.setRenderer(3, renderer3);

        renderer3.setSeriesPaint(0, Color.green);
        axis3.setLabelPaint(Color.green);
        axis3.setTickLabelPaint(Color.green);

        return chart;
    }
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值