Registration

Dear SAP Community Member,
In order to fully benefit from what the SAP Community has to offer, please register at:
http://scn.sap.com
Thank you,
The SAP Community team.
Skip to end of metadata
Go to start of metadata

Author: https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/com.sap.sdn.businesscard.SDNBusinessCard?u=a8fZzxbWgJE%3D
Submitted: 19 May 2009
Related Links:

Introduction

Few days back I got a requirement to display a set of data in the form of a Bar Chart just below an ALV grid in an ABAP report. Now had it been old R/3 days then it would have been difficult to achieve this as all the GRAPH* function modules available in those days would only display these charts in a separate window with it's own controls. But now SAP has provided us special classes which allow us to display our charts or graphs on the same window. These classes ( CL_GUI_CHART_ENGINE ) are part of chart engine.It's very easy to use this class and they need input in the form of XML files. Now to create these XML files there are different options :

  1. Use Call Transformation command to create the XML files based on the contents of your internal table. Refer to following blog for more details about this method : https://www.sdn.sap.com/irj/scn/weblogs?blog=/pub/wlg/13313
  2. Create the XML file using the Chart Designer and then use this XML in the ABAP program.
  3. Create the XML file directly in the abap program passing value of each node from an internal table.

We will look at the 3rd approach in detail. It is very simple to program and gives the required output: 

Requirement:

    We want to display the flight capacity and number of seats occupied for each flight number in the form of a bar chart. This need to be done for an online report.

Solution:

 I have written below a simple code to cater this requirement. This report will fetch data from SFLIGHT table and display the required information in the form of Bar Chart.

Let's start by creating a demo program and declare the following data in it.

Error rendering macro 'code': Invalid value specified for parameter 'lang'
REPORT  zat_ce_demo.
* Global Data Portion
DATA: g_t_sflight TYPE STANDARD TABLE OF sflight.
DATA: wa_sflight  LIKE LINE OF g_t_sflight.
DATA: g_graph_container TYPE REF TO cl_gui_custom_container.
DATA: g_ce_viewer TYPE REF TO cl_gui_chart_engine.
DATA: g_ixml        TYPE REF TO if_ixml.
DATA: g_ixml_sf     TYPE REF TO if_ixml_stream_factory.
DATA: okcode        LIKE sy-ucomm.
*---------------------------------------------------------------------*
*      Start Of Selection
*---------------------------------------------------------------------*
START-OF-SELECTION.
* Get Data to be displayed on the Chart
  SELECT * FROM sflight INTO TABLE g_t_sflight.
* create global objects
  g_ixml = cl_ixml=>create( ).
  g_ixml_sf = g_ixml->create_stream_factory( ).
* Call the screen to display the chart
  CALL SCREEN '100'.

Don't forget to create a dynpro screen having a custom controller using the screen painter. The ID of this custom controller should be 'GRAPH_CONTAINER'. In the PBO of this screen write the code given below :

Error rendering macro 'code': Invalid value specified for parameter 'lang'
*---------------------------------------------------------------------*
*      Module  STATUS_0100  OUTPUT
*---------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
  DATA: l_ixml_data_doc   TYPE REF TO if_ixml_document,
        l_ixml_custom_doc TYPE REF TO if_ixml_document,
        l_ostream         TYPE REF TO if_ixml_ostream,
        l_xstr            TYPE xstring.
  SET PF-STATUS '100'.
* For initial display of graph data.
  IF g_graph_container IS INITIAL.
* Create the object for container.
    CREATE OBJECT g_graph_container
      EXPORTING
        container_name = 'GRAPH_CONTAINER'.
* Bind the container to the object.
    CREATE OBJECT g_ce_viewer
      EXPORTING
        parent = g_graph_container.
* Create XML data using data in internal table.
    PERFORM create_xml_data USING l_ixml_data_doc.
    l_ostream = g_ixml_sf->create_ostream_xstring( l_xstr ).
* Render Chart Data
    CALL METHOD l_ixml_data_doc->render
      EXPORTING
        ostream = l_ostream.
    g_ce_viewer->set_data( xdata = l_xstr ).
    CLEAR l_xstr.
* Create the customizing data for the chart
    PERFORM create_customizing_data USING l_ixml_custom_doc.
    l_ostream = g_ixml_sf->create_ostream_xstring( l_xstr ).
* Render Customizing Data
    CALL METHOD l_ixml_custom_doc->render
      EXPORTING
        ostream = l_ostream.
    g_ce_viewer->set_customizing( xdata = l_xstr ).
  ENDIF.
* Render the Graph Object.
  CALL METHOD g_ce_viewer->render.
ENDMODULE.                 " STATUS_0100  OUTPUT
*---------------------------------------------------------------------*
*      Form  CREATE_XML_DATA
*---------------------------------------------------------------------*
*      -->P_L_IXML_DOC  text
*----------------------------------------------------------------------*
FORM create_xml_data  USING p_ixml_doc TYPE REF TO if_ixml_document.
  DATA: l_simplechartdata    TYPE REF TO if_ixml_element,
        l_categories         TYPE REF TO if_ixml_element,
        l_series             TYPE REF TO if_ixml_element,
        l_element            TYPE REF TO if_ixml_element,
        l_encoding           TYPE REF TO if_ixml_encoding,
        l_value              TYPE string.
  p_ixml_doc = g_ixml->create_document( ).
* Set encoding to UTF-8
  l_encoding = g_ixml->create_encoding(
                byte_order = if_ixml_encoding=>co_little_endian
                character_set = 'utf-8' ).
  p_ixml_doc->set_encoding( l_encoding ).
* Populate Chart Data
  l_simplechartdata = p_ixml_doc->create_simple_element(
               name = 'SimpleChartData' parent = p_ixml_doc ).
* Populate X-Axis Values i.e. Categories and Series
  l_categories = p_ixml_doc->create_simple_element(
            name = 'Categories' parent = l_simplechartdata ).
* Here you can populate the category labels. First you need
* to create all the labels and only then you can populate
* values for these labels.
  LOOP AT g_t_sflight INTO wa_sflight.
    l_element = p_ixml_doc->create_simple_element(
                name = 'C' parent = l_categories ).
    CONCATENATE wa_sflight-carrid wa_sflight-connid INTO l_value.
* Populate the category value which you want to display here.
* This will appear in the X-axis.
    l_element->if_ixml_node~set_value( l_value ).
    CLEAR l_value.
  ENDLOOP.
* Create an element for Series and then populate it's values.
  l_series = p_ixml_doc->create_simple_element(
            name = 'Series' parent = l_simplechartdata ).
* You can set your own label for X-Axis here e.g. Airline
  l_series->set_attribute( name = 'label' value = 'Price' ).
  LOOP AT g_t_sflight INTO wa_sflight.
    l_element = p_ixml_doc->create_simple_element(
                name = 'S' parent = l_series ).
* Populate the Value for each category you want to display from
* your internal table.
    l_value = wa_sflight-price.
    l_element->if_ixml_node~set_value( l_value ).
    CLEAR l_value.
  ENDLOOP.
* Similarly you can have number of Categories and values for each category
* based on your requirement
  l_series = p_ixml_doc->create_simple_element(
            name = 'Series' parent = l_simplechartdata ).
  l_series->set_attribute( name = 'label' value = 'Max Capacity' ).
  LOOP AT g_t_sflight INTO wa_sflight.
    l_element = p_ixml_doc->create_simple_element(
              name = 'S' parent = l_series ).
* Populate value for another category here.
    l_value = wa_sflight-seatsmax.
    l_element->if_ixml_node~set_value( l_value ).
    CLEAR l_value.
  ENDLOOP.
ENDFORM.                    " CREATE_XML_DATA

After setting up the data we need to pass the customizing data to the chart. Customizing data consists of various parameters which decide the look and feel of your chart. I have done in perform CREATE_CUSTOMIZING_DATA and the code for same is given below :

Error rendering macro 'code': Invalid value specified for parameter 'lang'
*&---------------------------------------------------------------------*
*&      Form  CREATE_CUSTOMIZING_DATA
*&---------------------------------------------------------------------*
*      -->P_L_IXML_CUSTOM_DOC  text
*----------------------------------------------------------------------*
FORM create_customizing_data  USING p_ixml_doc TYPE REF TO if_ixml_document.
  DATA: l_root            TYPE REF TO if_ixml_element,
        l_globalsettings  TYPE REF TO if_ixml_element,
        l_default         TYPE REF TO if_ixml_element,
        l_elements        TYPE REF TO if_ixml_element,
        l_chartelements   TYPE REF TO if_ixml_element,
        l_title           TYPE REF TO if_ixml_element,
        l_element         TYPE REF TO if_ixml_element,
        l_encoding        TYPE REF TO if_ixml_encoding.
  p_ixml_doc = g_ixml->create_document( ).
  l_encoding = g_ixml->create_encoding(
    byte_order = if_ixml_encoding=>co_little_endian
    character_set = 'utf-8' ).
  p_ixml_doc->set_encoding( l_encoding ).
  l_root = p_ixml_doc->create_simple_element(
            name = 'SAPChartCustomizing' parent = p_ixml_doc ).
  l_root->set_attribute( name = 'version' value = '1.1' ).
  l_globalsettings = p_ixml_doc->create_simple_element(
            name = 'GlobalSettings' parent = l_root ).
  l_element = p_ixml_doc->create_simple_element(
              name = 'FileType' parent = l_globalsettings ).
  l_element->if_ixml_node~set_value( 'PNG' ).
* Here you can give the Chart Type i.e. 2D, 3D etc
  l_element = p_ixml_doc->create_simple_element(
            name = 'Dimension' parent = l_globalsettings ).
* For 2 Dimensional Graph write - PseudoTwo
* For 2 Dimensional Graph write - PseudoThree
  l_element->if_ixml_node~set_value( 'PseudoThree' ).
* Here you can give the chart type
  l_element = p_ixml_doc->create_simple_element(
              name = 'ChartType' parent = l_globalsettings ).
* For Bar Char write - Columns
* For Pie Chart write - Pie etc
  l_element->if_ixml_node~set_value( 'Speedometer' ).
  l_element = p_ixml_doc->create_simple_element(
            name = 'FontFamily' parent = l_default ).
  l_element->if_ixml_node~set_value( 'Arial' ).
  l_elements = p_ixml_doc->create_simple_element(
            name = 'Elements' parent = l_root ).
  l_chartelements = p_ixml_doc->create_simple_element(
            name = 'ChartElements' parent = l_elements ).
  l_title = p_ixml_doc->create_simple_element(
            name = 'Title' parent = l_chartelements ).
* Give the desired caption for the chart here
  l_element = p_ixml_doc->create_simple_element( name = 'Caption' parent = l_title ).
  l_element->if_ixml_node~set_value( 'Airline Details' ).
ENDFORM.                    " CREATE_CUSTOMIZING_DATA

You can use following Category base chart types :  Lines, StackedLines, Profiles, StackedProfiles, Bars, StackedBars, Columns, StackedColumns,

 Area, StackedArea, ProfileArea, StackedProfileArea, Pie,Doughnut, SplitPie, Polar, 
 Radar, StackedRadar, Speedometer.
Last but not the least we need to handle some buttons in our PAI.

Error rendering macro 'code': Invalid value specified for parameter 'lang'
*-------------------------------------------------------------------*
*      Module  USER_COMMAND_0100  INPUT
*-------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
  CASE okcode.
    WHEN 'EXIT'.
      LEAVE PROGRAM.
    WHEN 'BACK'.
      LEAVE PROGRAM.
  ENDCASE.
ENDMODULE.                 " USER_COMMAND_0100 INPUT

No more coding is required and when we execute the report we will get the output as shown below : 

 
In a similar way we can create different types of charts by changing the chart type in our source code. These types can be :

 

Conclusion:

Thus we have seen how easy it is to use the chart engine and to display your own set of data in the charts. feel free to use this approach and develop your own applications using various options available in Chart Engine.
 
 

4 Comments

  1. Former Member

    do you have the code to be able to print graphs? 

  2. to display the graph you need to define the CC "GRAPH_CONTAINER" in dynpro 0100.

    Thanks for the example!

  3. Former Member

    Hello,

    great example (wink)

  4. Hello,

    Great Example. 

    I used this example for my requirement but i wan to understand about Color Changes details.

    Please help me .