如何通过垂直分隔将图表系列堆叠在一起?
How to stack the chart series on top of each other with vertical separation?
我想制作一个在折线图中的系列上垂直分隔的碧玉报告。
我检查了所有报告元素,但没有找到任何匹配元素。我附上我想要的示例图片
该图表由 jfreechart 库生成,AFIK 没有允许您自动实现此功能的设置。
解决方案是在每个系列上生成多个图表(一个在另一个之上)并对图表应用定制器,以便每个图表都可以根据它的位置。
csv 数据示例
+----------+--------+--------+
| Category | Serie1 | Serie2 |
+----------+--------+--------+
| A | 1 | 0.3 |
| B | 0.5 | 0.2 |
| C | 0.7 | 0.6 |
+----------+--------+--------+
jrxml 示例 有两个图表(一个用于系列 1,另一个用于系列 2)
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="chartTest" pageWidth="595" pageHeight="842" whenNoDataType="BlankPage" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="597c0716-df6b-42ec-a7c8-863eb1b7174a">
<queryString>
<![CDATA[]]>
</queryString>
<field name="Category" class="java.lang.String"/>
<field name="Serie1" class="java.lang.Double"/>
<field name="Serie2" class="java.lang.Double"/>
<summary>
<band height="205" splitType="Stretch">
<lineChart>
<chart customizerClass="ChartCustomizer">
<reportElement x="171" y="0" width="200" height="100" uuid="245c4678-0cad-4342-8e54-6355c23a3c72"/>
<chartTitle/>
<chartSubtitle/>
<chartLegend position="Right"/>
</chart>
<categoryDataset>
<categorySeries>
<seriesExpression><![CDATA["Serie 1"]]></seriesExpression>
<categoryExpression><![CDATA[$F{Category}]]></categoryExpression>
<valueExpression><![CDATA[$F{Serie1}]]></valueExpression>
</categorySeries>
</categoryDataset>
<linePlot isShowShapes="false">
<plot/>
<categoryAxisFormat>
<axisFormat verticalTickLabels="false"/>
</categoryAxisFormat>
<valueAxisFormat>
<axisFormat tickLabelColor="#FF0033"/>
</valueAxisFormat>
</linePlot>
</lineChart>
<lineChart>
<chart>
<reportElement x="171" y="93" width="200" height="111" uuid="b53cb5dc-09cd-448d-93ea-0719c239eafe"/>
<chartTitle/>
<chartSubtitle/>
<chartLegend position="Right"/>
</chart>
<categoryDataset>
<categorySeries>
<seriesExpression><![CDATA["Serie 2"]]></seriesExpression>
<categoryExpression><![CDATA[$F{Category}]]></categoryExpression>
<valueExpression><![CDATA[$F{Serie2}]]></valueExpression>
</categorySeries>
</categoryDataset>
<linePlot isShowShapes="false">
<plot>
<seriesColor seriesOrder="0" color="#000000"/>
</plot>
<categoryAxisFormat>
<axisFormat verticalTickLabels="true"/>
</categoryAxisFormat>
<valueAxisFormat>
<axisFormat/>
</valueAxisFormat>
<rangeAxisMinValueExpression><![CDATA[0]]></rangeAxisMinValueExpression>
<rangeAxisMaxValueExpression><![CDATA[2]]></rangeAxisMaxValueExpression>
</linePlot>
</lineChart>
</band>
</summary>
</jasperReport>
java class 包括图表 1 的 ChartCustomizer
和 运行 报告的 main
方法
public class ChartCustomizer implements JRChartCustomizer {
@Override
public void customize(JFreeChart jfchart, JRChart jrchart) {
CategoryPlot plot = (CategoryPlot) jfchart.getPlot();
CategoryAxis range = plot.getDomainAxis();
//Don't show the range axis
range.setVisible(false);
//Lets remove the 0, in your case you can do a customizer to remove the 2 on the other chart
NumberAxis rangeAxis = new NumberAxis() {
private static final long serialVersionUID = 3744076016723532336L;
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public List refreshTicks(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge) {
List allTicks = super.refreshTicks(g2, state, dataArea, edge);
NumberTick t0 = new NumberTick(TickType.MAJOR, 0, "", TextAnchor.CENTER_RIGHT, TextAnchor.CENTER_RIGHT, 0);
allTicks.set(0, t0);
return allTicks;
}
};
//Set range and paint, since we replace the rangeAxis
rangeAxis.setRange(0, 2);
rangeAxis.setTickLabelPaint(Color.RED);
plot.setRangeAxis(rangeAxis);
}
public static void main(String[] args) throws Exception {
JasperReport report = JasperCompileManager.compileReport("ChartTest.jrxml");
JRCsvDataSource ds = new JRCsvDataSource(new File("ChartData.csv"));
ds.setNumberFormat(NumberFormat.getInstance(Locale.US)); //. as decimal separator
ds.setFieldDelimiter(';');
ds.setUseFirstRowAsHeader(true);
Map<String, Object> paramMap = new HashMap<String, Object>();
JasperPrint jasperPrint = JasperFillManager.fillReport(report, paramMap, ds);
JRPdfExporter exporter = new JRPdfExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput("ChartTest.pdf"));
SimplePdfExporterConfiguration configuration = new SimplePdfExporterConfiguration();
configuration.setCreatingBatchModeBookmarks(true);
configuration.setMetadataAuthor("Petter");
exporter.setConfiguration(configuration);
exporter.exportReport();
}
}
结果
如您所见,它还不够完善,对于图例,您可以将其从图表中删除并直接在 jasper 报告中创建,此外,您可以删除第二张图表上的 2.0 而不是 0在第一个图表中,但我将留给您进一步实施。
我想制作一个在折线图中的系列上垂直分隔的碧玉报告。
我检查了所有报告元素,但没有找到任何匹配元素。我附上我想要的示例图片
该图表由 jfreechart 库生成,AFIK 没有允许您自动实现此功能的设置。
解决方案是在每个系列上生成多个图表(一个在另一个之上)并对图表应用定制器,以便每个图表都可以根据它的位置。
csv 数据示例
+----------+--------+--------+
| Category | Serie1 | Serie2 |
+----------+--------+--------+
| A | 1 | 0.3 |
| B | 0.5 | 0.2 |
| C | 0.7 | 0.6 |
+----------+--------+--------+
jrxml 示例 有两个图表(一个用于系列 1,另一个用于系列 2)
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="chartTest" pageWidth="595" pageHeight="842" whenNoDataType="BlankPage" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="597c0716-df6b-42ec-a7c8-863eb1b7174a">
<queryString>
<![CDATA[]]>
</queryString>
<field name="Category" class="java.lang.String"/>
<field name="Serie1" class="java.lang.Double"/>
<field name="Serie2" class="java.lang.Double"/>
<summary>
<band height="205" splitType="Stretch">
<lineChart>
<chart customizerClass="ChartCustomizer">
<reportElement x="171" y="0" width="200" height="100" uuid="245c4678-0cad-4342-8e54-6355c23a3c72"/>
<chartTitle/>
<chartSubtitle/>
<chartLegend position="Right"/>
</chart>
<categoryDataset>
<categorySeries>
<seriesExpression><![CDATA["Serie 1"]]></seriesExpression>
<categoryExpression><![CDATA[$F{Category}]]></categoryExpression>
<valueExpression><![CDATA[$F{Serie1}]]></valueExpression>
</categorySeries>
</categoryDataset>
<linePlot isShowShapes="false">
<plot/>
<categoryAxisFormat>
<axisFormat verticalTickLabels="false"/>
</categoryAxisFormat>
<valueAxisFormat>
<axisFormat tickLabelColor="#FF0033"/>
</valueAxisFormat>
</linePlot>
</lineChart>
<lineChart>
<chart>
<reportElement x="171" y="93" width="200" height="111" uuid="b53cb5dc-09cd-448d-93ea-0719c239eafe"/>
<chartTitle/>
<chartSubtitle/>
<chartLegend position="Right"/>
</chart>
<categoryDataset>
<categorySeries>
<seriesExpression><![CDATA["Serie 2"]]></seriesExpression>
<categoryExpression><![CDATA[$F{Category}]]></categoryExpression>
<valueExpression><![CDATA[$F{Serie2}]]></valueExpression>
</categorySeries>
</categoryDataset>
<linePlot isShowShapes="false">
<plot>
<seriesColor seriesOrder="0" color="#000000"/>
</plot>
<categoryAxisFormat>
<axisFormat verticalTickLabels="true"/>
</categoryAxisFormat>
<valueAxisFormat>
<axisFormat/>
</valueAxisFormat>
<rangeAxisMinValueExpression><![CDATA[0]]></rangeAxisMinValueExpression>
<rangeAxisMaxValueExpression><![CDATA[2]]></rangeAxisMaxValueExpression>
</linePlot>
</lineChart>
</band>
</summary>
</jasperReport>
java class 包括图表 1 的 ChartCustomizer
和 运行 报告的 main
方法
public class ChartCustomizer implements JRChartCustomizer {
@Override
public void customize(JFreeChart jfchart, JRChart jrchart) {
CategoryPlot plot = (CategoryPlot) jfchart.getPlot();
CategoryAxis range = plot.getDomainAxis();
//Don't show the range axis
range.setVisible(false);
//Lets remove the 0, in your case you can do a customizer to remove the 2 on the other chart
NumberAxis rangeAxis = new NumberAxis() {
private static final long serialVersionUID = 3744076016723532336L;
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public List refreshTicks(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge) {
List allTicks = super.refreshTicks(g2, state, dataArea, edge);
NumberTick t0 = new NumberTick(TickType.MAJOR, 0, "", TextAnchor.CENTER_RIGHT, TextAnchor.CENTER_RIGHT, 0);
allTicks.set(0, t0);
return allTicks;
}
};
//Set range and paint, since we replace the rangeAxis
rangeAxis.setRange(0, 2);
rangeAxis.setTickLabelPaint(Color.RED);
plot.setRangeAxis(rangeAxis);
}
public static void main(String[] args) throws Exception {
JasperReport report = JasperCompileManager.compileReport("ChartTest.jrxml");
JRCsvDataSource ds = new JRCsvDataSource(new File("ChartData.csv"));
ds.setNumberFormat(NumberFormat.getInstance(Locale.US)); //. as decimal separator
ds.setFieldDelimiter(';');
ds.setUseFirstRowAsHeader(true);
Map<String, Object> paramMap = new HashMap<String, Object>();
JasperPrint jasperPrint = JasperFillManager.fillReport(report, paramMap, ds);
JRPdfExporter exporter = new JRPdfExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput("ChartTest.pdf"));
SimplePdfExporterConfiguration configuration = new SimplePdfExporterConfiguration();
configuration.setCreatingBatchModeBookmarks(true);
configuration.setMetadataAuthor("Petter");
exporter.setConfiguration(configuration);
exporter.exportReport();
}
}
结果
如您所见,它还不够完善,对于图例,您可以将其从图表中删除并直接在 jasper 报告中创建,此外,您可以删除第二张图表上的 2.0 而不是 0在第一个图表中,但我将留给您进一步实施。