Как расположить ряды диаграмм друг над другом с вертикальным разделением?

Я хочу сделать отчет о яшме с вертикальным разделением на ряды в линейном графике.

Я проверил все элементы отчета, но не нашел ни одного соответствующего элемента. Я прилагаю образец изображения, что я хочу

Ожидаемый результат

1 ответ

Решение

Диаграмма генерируется библиотекой jfreechart, и в AFIK нет настроек, которые позволят вам достичь этого автоматически.

Решением будет создание нескольких диаграмм (одна поверх другой) для каждой серии и применение настройщика к диаграмме, чтобы каждая диаграмма могла быть адаптирована в зависимости от ее положения.

Пример данных CSV

+----------+--------+--------+
| Category | Serie1 | Serie2 |
+----------+--------+--------+
| A        | 1      | 0.3    |
| B        | 0.5    | 0.2    |
| C        | 0.7    | 0.6    |
+----------+--------+--------+

Пример jrxml с двумя графиками (1 для серии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, включая ChartCustomizer для диаграммы 1 и 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 на первом графике, но дальнейшую реализацию я оставлю тебе.

Другие вопросы по тегам