gpt4 book ai didi

jasper-reports - 我们可以在分组堆积条形图上绘制折线图吗

转载 作者:行者123 更新时间:2023-12-01 03:58:52 26 4
gpt4 key购买 nike

我正在尝试创建一个 GroupedStackBar图表显示每个客户过去三个月每个产品的收入,并添加描述每个时期与客户进行的 session 的折线图。我正在使用 JasperReports 创建一个 PDF 报告,使用常用的图表定制器来准备它。

下面的快照推测了我正在尝试创建的图表:

chart image .

该报告需要描述每个客户的月收入和 session 。如,显示 Client1提供给 X百万收入并拥有 M十一月 session ,Y百万收入和 N 12 月的 session 等等..

所以,我的 X 轴有两个分组 - 上个季度的客户和月份。此外,收入与产品进一步叠加。所以,我有点合并两个不同的数据集 - 每个客户的收入度量,月份,产品对每个客户的 session 度量,月份来构建图表。

我为生成图表而创建的示例程序:

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.SubCategoryAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.GroupedStackedBarRenderer;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.KeyToGroupMap;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

public class GroupedStackedBarLineChart extends ApplicationFrame {

public GroupedStackedBarLineChart(final String title) {
super(title);
// final JFreeChart chart = constructBarOverLineChart();
final JFreeChart chart = constructLineOverBarChart();
final ChartPanel panel = new ChartPanel(chart);
setContentPane(panel);
}

private JFreeChart constructLineOverBarChart() {
final JFreeChart chart = ChartFactory.createLineChart(
"Stacked Grouped Bar Line Chart", "Products/Month",
"Meetings/Month", fetchMeetingDataSet(),
PlotOrientation.VERTICAL, true, true, false);


final KeyToGroupMap map = new KeyToGroupMap("Jan13");
map.mapKeyToGroup("Jan13 (Product1)", "Jan13");
map.mapKeyToGroup("Jan13 (Product2)", "Jan13");
map.mapKeyToGroup("Jan13 (Product3)", "Jan13");

map.mapKeyToGroup("Feb13 (Product1)", "Feb13");
map.mapKeyToGroup("Feb13 (Product2)", "Feb13");
map.mapKeyToGroup("Feb13 (Product3)", "Feb13");

map.mapKeyToGroup("Mar13 (Product1)", "Mar13");
map.mapKeyToGroup("Mar13 (Product2)", "Mar13");
map.mapKeyToGroup("Mar13 (Product3)", "Mar13");

final GroupedStackedBarRenderer renderer = new GroupedStackedBarRenderer();
renderer.setSeriesToGroupMap(map);
renderer.setItemMargin(0.076);

final SubCategoryAxis domainAxis = new SubCategoryAxis("Products/Month");
domainAxis.addSubCategory("Jan13");
domainAxis.addSubCategory("Feb13");
domainAxis.addSubCategory("Mar13");

domainAxis.setCategoryMargin(0.28);

final CategoryPlot subPlot1 = (CategoryPlot) chart.getPlot();
subPlot1.setDataset(1, fetchRevenueDataSet());
subPlot1.setDomainAxis(domainAxis);
final ValueAxis revenueAxis = new NumberAxis("Revenue");
subPlot1.setRangeAxis(1, revenueAxis);
subPlot1.setRenderer(1, renderer);

return chart;
}

private JFreeChart constructBarOverLineChart() {
final JFreeChart chart = ChartFactory.createStackedBarChart(
"Stacked Grouped Bar Line Chart", "Clients", "Revenue",
fetchRevenueDataSet(), PlotOrientation.VERTICAL, true, true,
false);

final KeyToGroupMap map = new KeyToGroupMap("Jan13");
map.mapKeyToGroup("Jan13 (Product1)", "Jan13");
map.mapKeyToGroup("Jan13 (Product2)", "Jan13");
map.mapKeyToGroup("Jan13 (Product3)", "Jan13");

map.mapKeyToGroup("Feb13 (Product1)", "Feb13");
map.mapKeyToGroup("Feb13 (Product2)", "Feb13");
map.mapKeyToGroup("Feb13 (Product3)", "Feb13");

map.mapKeyToGroup("Mar13 (Product1)", "Mar13");
map.mapKeyToGroup("Mar13 (Product2)", "Mar13");
map.mapKeyToGroup("Mar13 (Product3)", "Mar13");

final GroupedStackedBarRenderer renderer = new GroupedStackedBarRenderer();
renderer.setSeriesToGroupMap(map);
renderer.setItemMargin(0.076);

final SubCategoryAxis domainAxis = new SubCategoryAxis("Products/Month");
domainAxis.addSubCategory("Jan13");
domainAxis.addSubCategory("Feb13");
domainAxis.addSubCategory("Mar13");

domainAxis.setCategoryMargin(0.28);

final CategoryPlot subPlot1 = (CategoryPlot) chart.getPlot();
subPlot1.setDomainAxis(domainAxis);
subPlot1.setRenderer(renderer);

final ValueAxis meetingAxis = new NumberAxis("Meetings");
subPlot1.setDataset(1, fetchMeetingDataSet());
// subPlot1.mapDatasetToDomainAxis(1, 1);
subPlot1.setRangeAxis(1, meetingAxis);
subPlot1.setRangeAxisLocation(0, AxisLocation.BOTTOM_OR_LEFT);
subPlot1.setRangeAxisLocation(1, AxisLocation.TOP_OR_RIGHT);
subPlot1.setRenderer(1, new LineAndShapeRenderer(true, false));


return chart;
}

private CategoryDataset fetchRevenueDataSet() {

final DefaultCategoryDataset revenueDataSet = new DefaultCategoryDataset();

revenueDataSet.addValue(20.3, "Jan13 (Product1)", "Client1");
revenueDataSet.addValue(27.2, "Jan13 (Product2)", "Client1");
revenueDataSet.addValue(19.7, "Jan13 (Product3)", "Client1");

revenueDataSet.addValue(19.4, "Feb13 (Product1)", "Client1");
revenueDataSet.addValue(10.9, "Feb13 (Product2)", "Client1");
revenueDataSet.addValue(18.4, "Feb13 (Product3)", "Client1");

revenueDataSet.addValue(16.5, "Mar13 (Product1)", "Client1");
revenueDataSet.addValue(15.9, "Mar13 (Product2)", "Client1");
revenueDataSet.addValue(16.1, "Mar13 (Product3)", "Client1");

revenueDataSet.addValue(23.3, "Jan13 (Product1)", "Client2");
revenueDataSet.addValue(16.2, "Jan13 (Product2)", "Client2");
revenueDataSet.addValue(28.7, "Jan13 (Product3)", "Client2");

revenueDataSet.addValue(12.7, "Feb13 (Product1)", "Client2");
revenueDataSet.addValue(17.9, "Feb13 (Product2)", "Client2");
revenueDataSet.addValue(12.6, "Feb13 (Product3)", "Client2");

revenueDataSet.addValue(15.4, "Mar13 (Product1)", "Client2");
revenueDataSet.addValue(21.0, "Mar13 (Product2)", "Client2");
revenueDataSet.addValue(11.1, "Mar13 (Product3)", "Client2");

revenueDataSet.addValue(23.8, "Jan13 (Product1)", "Client3");
revenueDataSet.addValue(23.4, "Jan13 (Product2)", "Client3");
revenueDataSet.addValue(19.3, "Jan13 (Product3)", "Client3");

revenueDataSet.addValue(11.9, "Feb13 (Product1)", "Client3");
revenueDataSet.addValue(31.0, "Feb13 (Product2)", "Client3");
revenueDataSet.addValue(22.7, "Feb13 (Product3)", "Client3");

revenueDataSet.addValue(15.3, "Mar13 (Product1)", "Client3");
revenueDataSet.addValue(14.4, "Mar13 (Product2)", "Client3");
revenueDataSet.addValue(25.3, "Mar13 (Product3)", "Client3");

return revenueDataSet;
}

private CategoryDataset fetchMeetingDataSet() {
final DefaultCategoryDataset meetingDataSet = new DefaultCategoryDataset();

meetingDataSet.addValue(20, "Jan13", "Client1");
meetingDataSet.addValue(8, "Feb13", "Client1");
meetingDataSet.addValue(35, "Mar13", "Client1");

meetingDataSet.addValue(7, "Jan13", "Client2");
meetingDataSet.addValue(20, "Feb13", "Client2");
meetingDataSet.addValue(12, "Mar13", "Client2");

meetingDataSet.addValue(25, "Jan13", "Client3");
meetingDataSet.addValue(17, "Feb13", "Client3");
meetingDataSet.addValue(7, "Mar13", "Client3");

return meetingDataSet;
}

public static void main(String[] args) {
GroupedStackedBarLineChart demo = new GroupedStackedBarLineChart(
"Client Revenue and Meetings");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
}

上述程序的输出没有按要求显示图表。相反,折线图显示 P Jan13 与 Client1 的 session , Q Jan13 与 Client2 的 session , R Jan13 与 Client3 的 session 和 X 2 月 13 日与 Client2 的 session , Y 2 月 13 日与 Client2 的 session 等等..也就是说,不尊重客户端的分组。我尝试改变折线图数据集中的行键/列键,但没有 yield 。

你能指点我正确地得到折线图吗?

谢谢。

最佳答案

我的第一个想法是实现自定义渲染器 - GroupStackedBarRenderer 和 LineAndShapeRenderer 的混合 - 但下面的假分组更容易;)

所以我用 StackeBarRenderer 替换了 GroupedStackedBarRenderer 并在组之间插入了一个虚拟列。
客户的分组类别标签由第二个域轴归档 -
幸运的是,无论使用多少个客户端/组,第二个类别轴的标签都集中在第一个轴的组内...

import java.awt.Graphics2D;
import org.apache.commons.beanutils.PropertyUtilsBean;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.StackedBarRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.text.G2TextMeasurer;
import org.jfree.text.TextBlock;
import org.jfree.text.TextUtilities;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RefineryUtilities;

public class GroupedStackedBarLineChart extends ApplicationFrame {

public GroupedStackedBarLineChart(final String title) {
super(title);
// final JFreeChart chart = constructBarOverLineChart();
final JFreeChart chart = constructLineOverBarChart();
final ChartPanel panel = new ChartPanel(chart);
setContentPane(panel);
}

private JFreeChart constructLineOverBarChart() {
final JFreeChart chart = ChartFactory.createLineChart(
"Stacked Grouped Bar Line Chart", "",
"Meetings/Month", fetchMeetingDataSet(),
PlotOrientation.VERTICAL, true, true, false);
final StackedBarRenderer renderer = new StackedBarRenderer();
renderer.setItemMargin(0.076);

final CategoryPlot cp = chart.getCategoryPlot();
cp.setDataset(1, fetchRevenueDataSet());
final ValueAxis revenueAxis = new NumberAxis("Revenue");
cp.setRangeAxis(1, revenueAxis);
cp.setRenderer(1, renderer);

chopCategoryLabels(cp);
insertFakeGrouping(cp);

CategoryAxis ca = new CategoryAxis("Products/Month");
cp.setDomainAxis(1, ca);
cp.setDataset(2, anotherDataSet());
cp.mapDatasetToDomainAxis(2, 1);
cp.setDomainAxisLocation(1, AxisLocation.BOTTOM_OR_LEFT);
ca.setAxisLineVisible(false);
ca.setTickMarksVisible(false);


return chart;
}

private void insertFakeGrouping(CategoryPlot cp) {
for (int i=0; i<cp.getDatasetCount(); i++) {
assert(cp.getDataset(i) instanceof DefaultCategoryDataset);
CategoryDataset cd = cp.getDataset(i);
Comparable<?> firstRow = cd.getRowKey(0);

DefaultCategoryDataset dcd = new DefaultCategoryDataset();
for (int col=0; col<cd.getColumnCount(); col++) {
if (col > 0) {
String c1 = cd.getColumnKey(col-1).toString();
c1 = c1.substring(c1.indexOf('_'));
String c2 = cd.getColumnKey(col).toString();
c2 = c2.substring(c2.indexOf('_'));
if (!c1.equals(c2)) {
dcd.addValue(null, firstRow, "dummy"+col);
}
}
for (int row=0; row<cd.getRowCount(); row++) {
Comparable<?> rowKey = cd.getRowKey(row);
Comparable<?> columnKey = cd.getColumnKey(col);
dcd.addValue(cd.getValue(rowKey, columnKey), rowKey, columnKey);
}
}

cp.setDataset(i, dcd);
}
}


private void chopCategoryLabels(CategoryPlot cp) {
CategoryAxis caOld = cp.getDomainAxis();
CategoryAxis caNew = new CategoryAxis(){
protected TextBlock createLabel(Comparable category, float width,
RectangleEdge edge, Graphics2D g2) {
String cat = category.toString();
cat = (cat.contains("_"))
? cat.substring(0, cat.indexOf('_'))
: "";
TextBlock label = TextUtilities.createTextBlock(cat,
getTickLabelFont(category), getTickLabelPaint(category), width,
getMaximumCategoryLabelLines(), new G2TextMeasurer(g2));
return label;
}
};

try {
new PropertyUtilsBean().copyProperties(caNew, caOld);
cp.setDomainAxis(0, caNew);
} catch (Exception e) {
throw new RuntimeException("not really?", e);
}
}

private CategoryDataset anotherDataSet() {
final DefaultCategoryDataset ds = new DefaultCategoryDataset();
ds.addValue(1, "1", "Client 1");
ds.addValue(1, "2", "Client 2");
ds.addValue(1, "3", "Client 3");
return ds;
}

private CategoryDataset fetchRevenueDataSet() {

final DefaultCategoryDataset revenueDataSet = new DefaultCategoryDataset();

revenueDataSet.addValue(20.3, "Product 1", "Jan13_1");
revenueDataSet.addValue(27.2, "Product 2", "Jan13_1");
revenueDataSet.addValue(19.7, "Product 3", "Jan13_1");

revenueDataSet.addValue(19.4, "Product 1", "Feb13_1");
revenueDataSet.addValue(10.9, "Product 2", "Feb13_1");
revenueDataSet.addValue(18.4, "Product 3", "Feb13_1");

revenueDataSet.addValue(16.5, "Product 1", "Mar13_1");
revenueDataSet.addValue(15.9, "Product 2", "Mar13_1");
revenueDataSet.addValue(16.1, "Product 3", "Mar13_1");

revenueDataSet.addValue(23.3, "Product 1", "Jan13_2");
revenueDataSet.addValue(16.2, "Product 2", "Jan13_2");
revenueDataSet.addValue(28.7, "Product 3", "Jan13_2");

revenueDataSet.addValue(12.7, "Product 1", "Feb13_2");
revenueDataSet.addValue(17.9, "Product 2", "Feb13_2");
revenueDataSet.addValue(12.6, "Product 3", "Feb13_2");

revenueDataSet.addValue(15.4, "Product 1", "Mar13_2");
revenueDataSet.addValue(21.0, "Product 2", "Mar13_2");
revenueDataSet.addValue(11.1, "Product 3", "Mar13_2");

revenueDataSet.addValue(23.8, "Product 1", "Jan13_3");
revenueDataSet.addValue(23.4, "Product 2", "Jan13_3");
revenueDataSet.addValue(19.3, "Product 3", "Jan13_3");

revenueDataSet.addValue(11.9, "Product 1", "Feb13_3");
revenueDataSet.addValue(31.0, "Product 2", "Feb13_3");
revenueDataSet.addValue(22.7, "Product 3", "Feb13_3");

revenueDataSet.addValue(15.3, "Product 1", "Mar13_3");
revenueDataSet.addValue(14.4, "Product 2", "Mar13_3");
revenueDataSet.addValue(25.3, "Product 3", "Mar13_3");

return revenueDataSet;
}

private CategoryDataset fetchMeetingDataSet() {
final DefaultCategoryDataset meetingDataSet = new DefaultCategoryDataset();

meetingDataSet.addValue(20, "Meetings", "Jan13_1");
meetingDataSet.addValue(8, "Meetings", "Feb13_1");
meetingDataSet.addValue(35, "Meetings", "Mar13_1");

meetingDataSet.addValue(7, "Meetings", "Jan13_2");
meetingDataSet.addValue(20, "Meetings", "Feb13_2");
meetingDataSet.addValue(12, "Meetings", "Mar13_2");

meetingDataSet.addValue(25, "Meetings", "Jan13_3");
meetingDataSet.addValue(17, "Meetings", "Feb13_3");
meetingDataSet.addValue(7, "Meetings", "Mar13_3");

return meetingDataSet;
}

public static void main(String[] args) {
GroupedStackedBarLineChart demo = new GroupedStackedBarLineChart(
"Client Revenue and Meetings");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
}

关于jasper-reports - 我们可以在分组堆积条形图上绘制折线图吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15025434/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com