In the method provided bellow I firstly create custom container object (cl_gui_custom_container) to place the chart in it, then I create chart engine (cl_gui_chart_engine), then using if_xml I create an xml data container which in fact can be written using simple concatenate statement but it's not nice to change and easy to mess.
So after we receive an xml with data then I will pass it to chart engine, then I will run the method prepared in previous part (Create a nice looking chart with CL_GUI_CHART_ENGINE - Part 2 - Customization ) to read the customization of the chart and I will pass it also to engine. Finally I will render the chart.
I_CONTAINER_NAME TYPE CSEQUENCE -> custom container's name
CO_CHART_ENGINE TYPE REF TO CL_GUI_CHART_ENGINE
CO_CONTAINER TYPE REF TO CL_GUI_CUSTOM_CONTAINER
method create_and_init_chart.
*This is the code from http://abapblog.com.
data: f_lenght type i.
data: f_xstring type xstring.
data: fo_ixml_mf type ref to if_ixml.
data: fo_ixml_sf type ref to if_ixml_stream_factory.
data: f_ixml_data_doc type ref to if_ixml_document.
data: f_ostream type ref to if_ixml_ostream.
data: f_encoding type ref to if_ixml_encoding.
* chart data elements:
data: f_chartdata type ref to if_ixml_element,
f_categories type ref to if_ixml_element,
f_category type ref to if_ixml_element,
f_series type ref to if_ixml_element,
f_point type ref to if_ixml_element,
f_value type ref to if_ixml_element.
if co_container is initial.
"create container
create object co_container
exporting
container_name = i_container_name.
"create an engine assigned to our container
create object co_chart_engine
exporting
parent = co_container.
endif.
* processing data
fo_ixml_mf = cl_ixml=>create( ).
fo_ixml_sf = fo_ixml_mf->create_stream_factory( ).
* create an empty document and set encoding
f_ixml_data_doc = fo_ixml_mf->create_document( ).
f_encoding = fo_ixml_mf->create_encoding(
byte_order = if_ixml_encoding=>co_little_endian
character_set = 'utf-8' ).
f_ixml_data_doc->set_encoding( f_encoding ).
* Now build a DOM, representing an XML document with chart data
f_chartdata = f_ixml_data_doc->create_simple_element(
name = 'ChartData'
parent = f_ixml_data_doc ).
* Categories (parent)
f_categories = f_ixml_data_doc->create_simple_element(
name = 'Categories'
parent = f_chartdata ).
* Categories (children)
f_category = f_ixml_data_doc->create_simple_element(
name = 'Category'
parent = f_categories ).
f_category->if_ixml_node~set_value( 'My first category' ).
f_category = f_ixml_data_doc->create_simple_element(
name = 'Category'
parent = f_categories ).
f_category->if_ixml_node~set_value( 'My second category' ).
f_category = f_ixml_data_doc->create_simple_element(
name = 'Category'
parent = f_categories ).
f_category->if_ixml_node~set_value( 'My third category' ).
* Build series (we need only 1)
f_series = f_ixml_data_doc->create_simple_element(
name = 'Series'
parent = f_chartdata ).
f_series->set_attribute( name = 'customizing'
value = 'Series1' ).
*1st category
f_point = f_ixml_data_doc->create_simple_element(
name = 'Point'
parent = f_series ).
f_point->set_attribute( name = 'customizing'
value = 'Category1' ).
f_point->set_attribute( name = 'label'
value = 'Best one' ).
f_value = f_ixml_data_doc->create_simple_element(
name = 'Value'
parent = f_point ).
f_value->if_ixml_node~set_value( '50' ).
*2nd category
f_point = f_ixml_data_doc->create_simple_element(
name = 'Point'
parent = f_series ).
f_point->set_attribute( name = 'customizing'
value = 'Category2' ).
f_point->set_attribute( name = 'label'
value = 'Not so bad' ).
f_value = f_ixml_data_doc->create_simple_element(
name = 'Value'
parent = f_point ).
f_value->if_ixml_node~set_value( '35' ).
*3rd category
f_point = f_ixml_data_doc->create_simple_element(
name = 'Point'
parent = f_series ).
f_point->set_attribute( name = 'customizing'
value = 'Category3' ).
f_point->set_attribute( name = 'label'
value = 'Worst one' ).
f_value = f_ixml_data_doc->create_simple_element(
name = 'Value'
parent = f_point ).
f_value->if_ixml_node~set_value( '15' ).
* create ostream (into string variable) and render document into stream
f_ostream = fo_ixml_sf->create_ostream_xstring( f_xstring ).
f_ixml_data_doc->render( f_ostream ). "here f_xstring is filled
"set data to chart
co_chart_engine->set_data( xdata = f_xstring ).
"get customizing from Standard text - method found here
f_xstring = chart_customizing(
i_textname = 'Z_MY_CHART_CUSTOMIZING'
i_title = 'My nice chart'
i_subtitle = 'http://abapblog.com').
"set customizing
co_chart_engine->set_customizing( xdata = f_xstring ).
"render chart
co_chart_engine->render( ).
endmethod.
To be able to use the method we should firstly create a screen with custom control and call it CHART_SAMPLE. Remember about allowing of resizing of the control so the chart can change it size together with window size change.
report zab_chart_pie.
data: g_okcode type sy-ucomm.
data: go_abapblog type ref to zcl_abapblog_com. "our class with chart methods
data: go_chart type ref to cl_gui_chart_engine.
data: go_container type ref to cl_gui_custom_container.
call screen 0100.
*----------------------------------------------------------------------*
* MODULE pbo OUTPUT
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
module pbo output.
set pf-status 'STATUS_0100'.
if go_abapblog is initial.
create object go_abapblog.
"render chart
go_abapblog->create_and_init_chart(
exporting
i_container_name = 'CHART_SAMPLE'
changing
co_chart_engine = go_chart
co_container = go_container
).
endif.
endmodule. "pbo OUTPUT
*----------------------------------------------------------------------*
* MODULE pai INPUT
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
module pai input.
if g_okcode eq 'END'.
leave to screen 0.
endif.
endmodule. "pai INPUT