2013-02-22 4 views
4

Я пытаюсь создать график GroupedStackBar, который показывает доход для каждого клиента за последние три месяца для каждого продукта и добавляет линейные диаграммы, изображающие встречи, выполненные с клиентом в течение каждого периода. Я использую JasperReports для создания отчета в формате PDF с использованием обычных адаптеров диаграмм для его подготовки.Можем ли мы нарисовать линейный график по GroupedStackedBarChart

Ниже снимок догадывается диаграмму я пытаюсь создать:

chart image.

Отчет должен отображать ежемесячные доходы и собрания для каждого клиента. Как и в, показывает, что Client1 предусмотрена X млн доходов и имело M встречи в ноябре, Y млн доходов и N встречи в декабре и так далее ..

Итак, мой X-ось имеет две группировки - клиенты и месяц (ы) в последнем квартале. Кроме того, доход больше укладывается в продукты. Таким образом, я схожу с двух разных наборов данных - показатель выручки для каждого Клиента, месяцы, продукт против меры Мероприятий для каждого Клиента, месяц для построения диаграммы.

пример программы, которые я создал для создания диаграммы:

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, Q встречи для Jan13 с Client2, R встречи для Jan13 с Client3 и X встречи для Feb13 с Client2, Y встречи для Feb13 с Client2 и т. д. То есть группировка для клиента не соблюдается. Я попытался изменить ключ строки/столбца в наборе линейных диаграмм без урока.

Не могли бы вы указать мне правильную линию линейной диаграммы?

Спасибо.

+0

Я не могу загрузить простой jpg show-casing диаграмму, которую я разрабатываю, поскольку у меня нет еще 10 точек репутации :( – saiyyer

+0

Возможно, приведу [пример] (http://www.jfree.org/jfreechart /samples.html), по имени, разместите ссылку на картинку или отредактируйте свой вопрос, чтобы включить [sscce] (http://sscce.org/). – trashgod

+0

Вы можете создать многоосевую диаграмму с использованием Ireport, у меня было это Аналогичные требования. – Sharad

ответ

2

Моя первая мысль была реализовать пользовательский визуализатор - смесь из GroupStackedBarRenderer и LineAndShapeRenderer - но следующий поддельной группировка легче;)

Так я заменил GroupedStackedBarRenderer с StackeBarRenderer и вставить соску столбец между группами. Сгруппированные метки категорий для клиентов были заархивированы второй доменной осью - повезло, этикетки оси второй категории центрированы в пределах групп первой оси независимо от того, сколько клиентов/групп используется ...

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); 
    } 
} 
+0

Umm, Мы пересмотрели наш дизайн отчета и немного подстроили его, чтобы вписаться в доступные отчеты Jasper. но @kiwiwings, ваш хак работает отлично. Большое спасибо за ваше решение. – saiyyer

Смежные вопросы