Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
In many requirement graphical charts are required by the clients since a graph is much more appealing to the user. As graphs enables a better analysis of data to the user. It is however quite simple to provide the same functionality for building graphical charts in your ABAP report itself by using CL_IGS_CHART_ENGINE.

Recently I had the requirement of printing Charts on Smart forms. In Smart forms we can print the image if the image is already uploaded to the Form Graphics (SE78). I search through the SCN but doesn't find the solution of printing the charts on Smart forms. Then I had an idea of uploading the graphical image generated by CL_IGS_CHART_ENGINE dynamically to Form Graphics (SE78).  I have used the same functionality as used in Form Graphics (SE78) import to upload the image dynamically in Form Graphics.

Solution:

Create a Sample smart-Form to display the Graphical Chart generated by the custom function module.



TD_NAME is the name of the graphical chart generated dynamically by the custom function module YTESTCHART.



 

Delete the graphics after printing.


 

Print Preview of the Smart Form


 
FUNCTION ytestchart.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" REFERENCE(IM_TDNAME) TYPE STXBITMAPS-TDNAME
*" EXPORTING
*" VALUE(EX_STXBITMAPS) TYPE STXBITMAPS
*"----------------------------------------------------------------------

" IM_TDNAME Image name to be printed on smartforms
" EX_STXBITMAPS Image reference data generated dynamically

" Call This FM in the smartforms to generate image

DATA: xt_sflight TYPE flighttab,
g_ixml TYPE REF TO if_ixml,

x_ixml_data_doc TYPE REF TO if_ixml_document,
x_ixml_custom_doc TYPE REF TO if_ixml_document,
x_cl_igs_chart_engine TYPE REF TO cl_igs_chart_engine,
x_image_mime TYPE w3mimetabtype,
x_image_size TYPE w3param-cont_len,
x_image_type TYPE w3param-cont_type,

width_tw LIKE stxbitmaps-widthtw,
height_tw LIKE stxbitmaps-heighttw,
width_pix LIKE stxbitmaps-widthpix,
height_pix LIKE stxbitmaps-heightpix,
dpi LIKE stxbitmaps-resolution,
bds_bytecount TYPE i,
bitmap_file_bds TYPE sbdst_content,

lo_bds_object TYPE REF TO cl_bds_document_set,
xt_bds_components TYPE sbdst_components,
x_bds_components TYPE bapicompon,
xt_bds_signature TYPE sbdst_signature,
x_bds_signature TYPE bapisignat,
xt_bds_properties TYPE sbdst_properties,
x_bds_properties TYPE bapiproper,
x_stxbitmaps TYPE stxbitmaps,
x_object_key TYPE sbdst_object_key.



" Get Sample Data For the Chart/Graph

SELECT * FROM sflight INTO TABLE xt_sflight.

g_ixml = cl_ixml=>create( ).

" Generate XML for the chart

PERFORM create_data_demo USING x_ixml_data_doc xt_sflight
CHANGING g_ixml.

PERFORM create_custom_demo USING x_ixml_custom_doc
CHANGING g_ixml.

" Generate Image Using CL_IGS_CHART_ENGINE

x_cl_igs_chart_engine = NEW #( ).

CALL METHOD x_cl_igs_chart_engine->set_data
EXPORTING
data_doc = x_ixml_data_doc.
CALL METHOD x_cl_igs_chart_engine->set_customizing
EXPORTING
custom_doc = x_ixml_custom_doc.

CALL METHOD x_cl_igs_chart_engine->execute
EXCEPTIONS
OTHERS = 1.

IF sy-subrc IS INITIAL.

" Get Image to upload to SE78



CALL METHOD x_cl_igs_chart_engine->get_image
IMPORTING
image = x_image_mime
image_size = x_image_size
image_type = x_image_type.

CALL FUNCTION 'SAPSCRIPT_CONVERT_BITMAP_BDS'
EXPORTING
color = 'X'
format = 'BMP'
resident = ' '
bitmap_bytecount = x_image_size
compress_bitmap = ' '
IMPORTING
width_tw = width_tw
height_tw = height_tw
width_pix = width_pix
height_pix = height_pix
dpi = dpi
bds_bytecount = bds_bytecount
TABLES
bitmap_file = x_image_mime
bitmap_file_bds = bitmap_file_bds
EXCEPTIONS
format_not_supported = 1
no_bmp_file = 2
bmperr_invalid_format = 3
bmperr_no_colortable = 4
bmperr_unsup_compression = 5
bmperr_corrupt_rle_data = 6
OTHERS = 7.



* Save bitmap in BDS
lo_bds_object = NEW #( ).

x_bds_components-doc_count = '1'.
x_bds_components-comp_count = '1'.
x_bds_components-mimetype = 'application/octet-stream'.
x_bds_components-comp_size = bds_bytecount.
APPEND x_bds_components TO xt_bds_components.

x_bds_signature-doc_count = '1'.
APPEND x_bds_signature TO xt_bds_signature.

CALL METHOD lo_bds_object->create_with_table
EXPORTING
classname = 'DEVC_STXD_BITMAP'
classtype = 'OT'
components = xt_bds_components
content = bitmap_file_bds
CHANGING
signature = xt_bds_signature
object_key = x_object_key
EXCEPTIONS
OTHERS = 1.

* Save bitmap header in Database Table STXBITPMAPS
x_stxbitmaps-tdname = im_tdname.
x_stxbitmaps-tdobject = 'GRAPHICS'.
x_stxbitmaps-tdid = 'BMAP'.
x_stxbitmaps-tdbtype = 'BCOL'.
x_stxbitmaps-docid = xt_bds_signature[ 1 ]-doc_id.
x_stxbitmaps-widthpix = width_pix. " Width and hights can be changed
x_stxbitmaps-heightpix = height_pix.
x_stxbitmaps-widthtw = width_tw.
x_stxbitmaps-heighttw = height_tw.
x_stxbitmaps-resolution = '075'.
* x_stxbitmaps-resident = 'X'.
x_stxbitmaps-autoheight = 'X'.
* x_stxbitmaps-bmcomp = 'X'.
INSERT INTO stxbitmaps VALUES x_stxbitmaps.
IF sy-subrc <> 0.
UPDATE stxbitmaps FROM x_stxbitmaps.
ENDIF.

ex_stxbitmaps = x_stxbitmaps.

x_bds_properties-prop_name = 'DESCRIPTION'.
x_bds_properties-prop_value = 'Charts'.
APPEND x_bds_properties TO xt_bds_properties.

CALL METHOD lo_bds_object->change_properties
EXPORTING
classname = 'DEVC_STXD_BITMAP'
classtype = 'OT'
object_key = x_object_key
doc_id = xt_bds_signature[ 1 ]-doc_id
doc_ver_no = '1'
doc_var_id = '1'
CHANGING
properties = xt_bds_properties
EXCEPTIONS
OTHERS = 1.

ENDIF.

ENDFUNCTION.

**----------------------------------------------------------------------*
****INCLUDE LYTESTCHARTF01.
**----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Form CREATE_DATA_DEMO
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_X_IXML_DATA_DOC text
* -->P_XT_SFLIGHT text
* <--P_G_IXML text
*----------------------------------------------------------------------*
FORM create_data_demo USING p_ixml_doc TYPE REF TO if_ixml_document
pt_sflight TYPE flighttab
CHANGING p_ixml TYPE REF TO if_ixml.

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 = p_ixml->create_document( ).
* Set encoding to UTF-8
l_encoding = p_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 pt_sflight ASSIGNING FIELD-SYMBOL(<sflight>).
l_element = p_ixml_doc->create_simple_element(
name = 'C' parent = l_categories ).
CONCATENATE <sflight>-carrid <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 pt_sflight ASSIGNING <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 = <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 pt_sflight ASSIGNING <sflight>.
l_element = p_ixml_doc->create_simple_element(
name = 'S' parent = l_series ).
* Populate value for another category here.
l_value = <sflight>-seatsmax.
l_element->if_ixml_node~set_value( l_value ).
CLEAR l_value.
ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form CREATE_CUSTOM_DEMO
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_L_IXML_CUSTOM_DOC text
*----------------------------------------------------------------------*
FORM create_custom_demo USING p_ixml_doc TYPE REF TO if_ixml_document
CHANGING p_ixml TYPE REF TO if_ixml.
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_text TYPE REF TO if_ixml_element,
l_element TYPE REF TO if_ixml_element,
l_chartaxes TYPE REF TO if_ixml_element,
l_categoryaxis TYPE REF TO if_ixml_element,
l_line TYPE REF TO if_ixml_element,
l_encoding TYPE REF TO if_ixml_encoding.

p_ixml_doc = p_ixml->create_document( ).
l_encoding = p_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( 'BMP' ).
* 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('Columns'). "( '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.

 

Conclusion: -

Now we can print any type of charts using CL_IGS_CHART_ENGINE on smart-forms dynamically. we just need to change the XML for changing the chart.

I hope that makes drawing graphs/charts with ABAP complete and easily achievable.

Thanks for reading this blog post. I would like to see your comments and would like to answer questions which u can post at Q&A tag area: https://answers.sap.com/tags/66233466-fcd6-45d2-a9ae-2cba38c72e19

 
6 Comments
Labels in this area