I am trying to create a GroupedStackBar chart that shows the revenue for each customer for the last three months for each product and adds a line chart (s) showing the meetings made with the customer during each period. I use JasperReports to create a PDF report using the usual chart adapters to prepare it.
The following snapshot suggests the chart I'm trying to create:
.
The report should display monthly income and meetings for each client. As with the case, show that Client1 provided X mn in revenue and had meetings M in November, Y mn in revenue and N meetings in December, etc.
So, my X axis has two groups - customers and the month in the last quarter. In addition, income fits more into products. Thus, Iām going to merge two different data sets: an income indicator for each client, months, a product versus Meetings measure for each client, a month to build a chart.
An example program that I created to create a chart:
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); } }
The above program does not display the graph as required. Instead, the line diagram shows P meetings for January 13 with Client1 , Q meetings for January 13 with Client2 , R meetings for January 13 with Client3 and X meetings for February 13 with Client2 , Y for February 13 with Client2 , etc. That is, the grouping for the client is not respected. I tried changing the row / column key in a line chart set without a lesson.
Could you please point me to the correct line chart?
Thanks.