Einleitung
Mit Hilfe der Klasse cl_gui_chart_engine können Charts generiert werden. Über XML-Dokumente kann die Anzeige konfiguriert bzw. Daten angezeigt werden. SAP liefert zur einfachen Konfiguration ein Tool namens Chart Designer. Die XML-Daten können aber auch manuell generiert werden, eine genaue Beschreibung findet man im Dokument „XML Format.pdf“ des Chart Designers.
Mit Hilfe des unten stehenden Demo-Programms können auch XML-Daten für das Customizing generiert, geladen und gespeichert sowie Plot-Daten im XML-Format eingeladen werden. Es sind auch zwei einfache Beispiele für einen Bar-Chart sowie einen Scatter-Plot implementiert.
ABAP-Demoprogramm
* Chart-Demoprogramme
* GRAPHICS_GUI_CE_DEMO
* GRAPHICS_IGS_CE_TEST
* RSORA_TCS_DEMO
* Chart-Klassen
* CL_GUI_CHART_ENGINE
* CL_IGS_CHART_ENGINE
* CL_TIME_CHART_SIMPLE
DATA: it_sflight TYPE STANDARD TABLE OF sflight.
* globales Chart-Objekt
DATA: o_chart TYPE REF TO cl_gui_chart_engine.
CLASS lcl_events DEFINITION.
PUBLIC SECTION.
TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.
* Buttons
CONSTANTS: co_btn_load_cust TYPE string VALUE 'BTN_LOAD_CUST'.
CONSTANTS: co_btn_load_data TYPE string VALUE 'BTN_LOAD_DATA'.
CONSTANTS: co_btn_save_cust TYPE string VALUE 'BTN_SAVE_CUST'.
CONSTANTS: co_btn_print TYPE string VALUE 'BTN_PRINT'.
CONSTANTS: co_btn_example_bar TYPE string VALUE 'BTN_EXAMPLE_BAR'.
CONSTANTS: co_btn_example_scatter TYPE string VALUE 'BTN_EXAMPLE_SCATTER'.
CONSTANTS: co_btn_clear TYPE string VALUE 'BTN_CLEAR'.
CLASS-METHODS: on_click FOR EVENT click OF cl_gui_chart_engine
IMPORTING
element
series
point
sender.
CLASS-METHODS: on_value_change FOR EVENT value_change OF cl_gui_chart_engine
IMPORTING
series
point
value
sender.
CLASS-METHODS: on_property_change FOR EVENT property_change OF cl_gui_chart_engine
IMPORTING
element
name
value
sender.
CLASS-METHODS:
on_function_selected FOR EVENT function_selected OF cl_gui_toolbar
IMPORTING
fcode
sender.
ENDCLASS.
CLASS lcl_events IMPLEMENTATION.
* Klick auf Chart
METHOD on_click.
MESSAGE |Klick: { element } { series } { point }| TYPE 'S'.
ENDMETHOD.
* Chart Wertänderung
METHOD on_value_change.
MESSAGE |Wert geändert: { series } { point } { value }| TYPE 'S'.
ENDMETHOD.
* Chart Property-Änderung
METHOD on_property_change.
MESSAGE |Property: { element } { name } { value }| TYPE 'S'.
ENDMETHOD.
* Toolbar Button geklickt
METHOD on_function_selected.
CASE fcode.
* Graph drucken
WHEN co_btn_print.
IF o_chart IS BOUND.
DATA(o_cewp) = CAST cl_gui_chart_engine_win( o_chart->get_control( ) ).
o_cewp->print( ).
ENDIF.
* Graph zurücksetzen
WHEN co_btn_clear.
IF o_chart IS BOUND.
* Initialdaten setzen
o_chart->set_data( data = '<?xml version="1.0" encoding="utf-8"?><SimpleChartData></SimpleChartData>' ).
* Initial-Customizing setzen
o_chart->set_customizing( data = '<?xml version="1.0" encoding="utf-8"?><SAPChartCustomizing version="2.0"></SAPChartCustomizing>' ).
ENDIF.
**********************************************************************
* Bargraph
* einfaches Balkendiagramm, bei dem jeweils 2 Punkte einer Series
* einer Kategorie zugeordnet werden
**********************************************************************
WHEN co_btn_example_bar.
IF o_chart IS BOUND.
* Initialdaten setzen
o_chart->set_data( data_table = VALUE w3htmltabtype( ( |<?xml version="1.0" encoding="utf-8"?>| )
( |<ChartData>| )
( | <Categories>| )
( | <Category>Category 1</Category>| )
( | <Category>Category 2</Category>| )
( | <Category>Category 3</Category>| )
( | </Categories>| )
( | <Series customizing="Series1" label="Series 1">| )
( | <Point>| )
( | <Value type="y">5</Value>| )
( | </Point>| )
( | <Point>| )
( | <Value type="y">10</Value>| )
( | </Point>| )
( | <Point>| )
( | <Value type="y">7</Value>| )
( | </Point>| )
( | </Series>| )
( | <Series customizing="Series2" label="Series 2">| )
( | <Point>| )
( | <Value type="y">7</Value>| )
( | </Point>| )
( | <Point>| )
( | <Value type="y">9</Value>| )
( | </Point>| )
( | <Point>| )
( | <Value type="y">23</Value>| )
( | </Point>| )
( | </Series>| )
( |</ChartData>| ) ) ).
* Initial-Customizing setzen
o_chart->set_customizing( data_table = VALUE w3htmltabtype( ( |<?xml version="1.0" encoding="utf-8"?>| )
( |<SAPChartCustomizing version="2.0">| )
( | <GlobalSettings>| )
( | <Defaults>| )
( | <ChartType>Columns</ChartType>| )
( | <FontFamily>Arial</FontFamily>| )
( | </Defaults>| )
( | </GlobalSettings>| )
( | <Elements>| )
( | <ChartElements>| )
( | <Title>| )
( | <Caption>Bargraph</Caption>| )
( | </Title>| )
( | </ChartElements>| )
( | </Elements>| )
( |</SAPChartCustomizing>| ) ) ).
ENDIF.
**********************************************************************
* Scatterplot
* x,y-Punkte-Diagramm mit zwei Linien (Series)
* Vorgabe von Achse (min, max), Punkteigenschaften, Farbe, Legende
**********************************************************************
WHEN co_btn_example_scatter.
IF o_chart IS BOUND.
* Initialdaten setzen
o_chart->set_data( data_table = VALUE w3htmltabtype( ( |<?xml version="1.0" encoding="utf-8"?>| )
( |<ChartData>| )
( | <Series customizing="Series1" label="y1">| )
( | <Point label="P1">| )
( | <Value type="x">-5.1</Value>| )
( | <Value type="y">-2.3</Value>| )
( | </Point>| )
( | <Point label="P2">| )
( | <Value type="x">1.2</Value>| )
( | <Value type="y">1.1</Value>| )
( | </Point>| )
( | <Point label="P3">| )
( | <Value type="x">6.2</Value>| )
( | <Value type="y">7.4</Value>| )
( | </Point>| )
( | </Series>| )
( | <Series customizing="Series2" label="y2">| )
( | <Point label="P1">| )
( | <Value type="x">-5.1</Value>| )
( | <Value type="y">0.3</Value>| )
( | </Point>| )
( | <Point label="P2">| )
( | <Value type="x">1.2</Value>| )
( | <Value type="y">3.5</Value>| )
( | </Point>| )
( | <Point label="P3">| )
( | <Value type="x">6.2</Value>| )
( | <Value type="y">8.9</Value>| )
( | </Point>| )
( | </Series>| )
( |</ChartData>| ) ) ).
* Initial-Customizing setzen
o_chart->set_customizing( data_table = VALUE w3htmltabtype( ( |<?xml version="1.0" encoding="utf-8"?>| )
( |<SAPChartCustomizing version="2.0">| )
( | <GlobalSettings>| )
( | <Dimension>Two</Dimension>| )
( | <ColorPalette>Tradeshow</ColorPalette>| )
( | <Defaults>| )
( | <ChartType>Scatter</ChartType>| )
( | <FontFamily>Arial</FontFamily>| )
( | </Defaults>| )
( | </GlobalSettings>| )
( | <Elements>| )
( | <ChartElements>| )
( | <Title>| )
( | <Caption>Scatterplot</Caption>| )
( | </Title>| )
( | <Subtitle>| )
( | <Caption>Daten und Settings</Caption>| )
( | </Subtitle>| )
( | <Legend>| )
( | <Alignment>ToPlotArea</Alignment>| )
( | <Position>TopRight</Position>| )
( | </Legend>| )
( | </ChartElements>| )
( | <ChartAxes>| )
( | <ValueAxis id="ValueAxis1">| )
( | <Visibility>true</Visibility>| )
( | <Minimum>-10</Minimum>| )
( | <MinimumCalculation>UserDefined</MinimumCalculation>| )
( | <Maximum>10</Maximum>| )
( | <MaximumCalculation>UserDefined</MaximumCalculation>| )
( | <ScalingType>Linear</ScalingType>| )
( | <Order>Ascending</Order>| )
( | <Position>Primary</Position>| )
( | <Title>| )
( | <Caption>x</Caption>| )
( | </Title>| )
( | </ValueAxis>| )
( | <ValueAxis id="ValueAxis2">| )
( | <Visibility>true</Visibility>| )
( | <Minimum>-10</Minimum>| )
( | <MinimumCalculation>UserDefined</MinimumCalculation>| )
( | <Maximum>10</Maximum>| )
( | <MaximumCalculation>UserDefined</MaximumCalculation>| )
( | <ScalingType>Linear</ScalingType>| )
( | <Order>Ascending</Order>| )
( | <Position>Primary</Position>| )
( | <Title>| )
( | <Caption>x</Caption>| )
( | </Title>| )
( | </ValueAxis>| )
( | </ChartAxes>| )
( | </Elements>| )
( | <Values>| )
( | <Series>| )
( | <ShowLabel>true</ShowLabel>| )
( | <LineColor>@20</LineColor>| )
( | </Series>| )
( | <Series id="Series1">| )
( | <ShowLabel>true</ShowLabel>| )
( | <LineColor>@20</LineColor>| )
( | <Color>@20</Color>| )
( | </Series>| )
( | <Series id="Series2">| )
( | <ShowLabel>true</ShowLabel>| )
( | <LineColor>@60</LineColor>| )
( | <Color>@60</Color>| )
( | </Series>| )
( | </Values>| )
( |</SAPChartCustomizing>| ) ) ).
ENDIF.
* XML Chart-Customizing speichern
WHEN co_btn_save_cust.
IF o_chart IS BOUND.
DATA: it_xml TYPE w3htmltabtype.
DATA(o_cew_save) = CAST cl_gui_chart_engine_win( o_chart->get_control( ) ).
o_cew_save->get_customizing( IMPORTING data_table = it_xml ).
DATA: lv_action TYPE i.
DATA: lv_filename TYPE string.
DATA: lv_fullpath TYPE string.
DATA: lv_path TYPE string.
TRY.
* Savedialog anzeigen
cl_gui_frontend_services=>file_save_dialog( EXPORTING
default_file_name = 'chart.xml'
default_extension = 'xml'
file_filter = |XML (*.xml)\|*.xml\|{ cl_gui_frontend_services=>filetype_all }|
CHANGING
filename = lv_filename
path = lv_path
fullpath = lv_fullpath
user_action = lv_action ).
IF lv_action EQ cl_gui_frontend_services=>action_ok.
* XML-Daten lokal speichern
cl_gui_frontend_services=>gui_download( EXPORTING
filename = lv_fullpath
filetype = 'BIN'
CHANGING
data_tab = it_xml ).
ENDIF.
CATCH cx_root INTO DATA(e_txt).
MESSAGE e_txt->get_text( ) TYPE 'E'.
ENDTRY.
ENDIF.
* XML Chart-Customizing laden
WHEN co_btn_load_cust.
IF o_chart IS BOUND.
DATA: lv_rc_cust TYPE i.
DATA: it_files_cust TYPE filetable.
DATA: lv_action_open_cust TYPE i.
* FileOpen-Dialog aufrufen
TRY.
cl_gui_frontend_services=>file_open_dialog( EXPORTING
file_filter = |XML (*.xml)\|*.xml\|{ cl_gui_frontend_services=>filetype_all }|
CHANGING
file_table = it_files_cust
rc = lv_rc_cust
user_action = lv_action_open_cust ).
IF lv_action_open_cust = cl_gui_frontend_services=>action_ok.
* wenn Datei ausgewählt wurde
IF lines( it_files_cust ) > 0.
DATA: lv_filesize_cust TYPE w3param-cont_len.
DATA: it_xml_cust_up TYPE w3htmltabtype.
cl_gui_frontend_services=>gui_upload( EXPORTING
filename = |{ it_files_cust[ 1 ]-filename }|
filetype = 'BIN'
IMPORTING
filelength = lv_filesize_cust
CHANGING
data_tab = it_xml_cust_up ).
* XML-Daten setzen
o_chart->set_customizing( data_table = it_xml_cust_up ).
ENDIF.
ENDIF.
CATCH cx_root INTO DATA(e_text_cust).
MESSAGE e_text_cust->get_text( ) TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.
ENDIF.
* XML Chart-Daten laden
WHEN co_btn_load_data.
IF o_chart IS BOUND.
DATA: lv_rc_data TYPE i.
DATA: it_files_data TYPE filetable.
DATA: lv_action_open_data TYPE i.
* FileOpen-Dialog aufrufen
TRY.
cl_gui_frontend_services=>file_open_dialog( EXPORTING
file_filter = |XML (*.xml)\|*.xml\|{ cl_gui_frontend_services=>filetype_all }|
CHANGING
file_table = it_files_data
rc = lv_rc_data
user_action = lv_action_open_data ).
IF lv_action_open_data = cl_gui_frontend_services=>action_ok.
* wenn Datei ausgewählt wurde
IF lines( it_files_data ) > 0.
DATA: lv_filesize_data TYPE w3param-cont_len.
DATA: it_xml_data_up TYPE w3htmltabtype.
cl_gui_frontend_services=>gui_upload( EXPORTING
filename = |{ it_files_data[ 1 ]-filename }|
filetype = 'BIN'
IMPORTING
filelength = lv_filesize_data
CHANGING
data_tab = it_xml_data_up ).
* XML-Daten setzen
o_chart->set_data( data_table = it_xml_data_up ).
ENDIF.
ENDIF.
CATCH cx_root INTO DATA(e_text_data).
MESSAGE e_text_data->get_text( ) TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.
ENDIF.
ENDCASE.
ENDMETHOD.
ENDCLASS.
INITIALIZATION.
**********************************************************************
* GUI
**********************************************************************
* Splitter erzeugen
DATA(o_splitter) = NEW cl_gui_splitter_container( parent = cl_gui_container=>default_screen
no_autodef_progid_dynnr = abap_true
rows = 2
columns = 1 ).
* absoluter Modus für Zeilenhöhe
o_splitter->set_row_mode( mode = cl_gui_splitter_container=>mode_absolute ).
* Höhe absolut 24 Pixel für Splitter oben
o_splitter->set_row_height( id = 1 height = 24 ).
* Splitter für oberen Container fest und verborgen
o_splitter->set_row_sash( id = 1
type = cl_gui_splitter_container=>type_movable
value = cl_gui_splitter_container=>false ).
o_splitter->set_row_sash( id = 1
type = cl_gui_splitter_container=>type_sashvisible
value = cl_gui_splitter_container=>false ).
* Top- und Bottom-Container holen
DATA(o_container_top) = o_splitter->get_container( row = 1 column = 1 ).
DATA(o_container_bottom) = o_splitter->get_container( row = 2 column = 1 ).
* Toolbar hoizontal
DATA(o_tool) = NEW cl_gui_toolbar( parent = o_container_top
display_mode = cl_gui_toolbar=>m_mode_horizontal ).
* Eventtypten müssen gesondert registriert werden
DATA(it_events) = VALUE lcl_events=>ty_it_events( ( eventid = cl_gui_toolbar=>m_id_function_selected
appl_event = abap_true ) ).
o_tool->set_registered_events( events = it_events ).
* Toolbar-Buttons hinzufügen
* Buttontypen sind in Typgruppe CNTB definiert
o_tool->add_button( fcode = CONV #( lcl_events=>co_btn_load_cust )
icon = icon_open
butn_type = cntb_btype_button
text = 'Load settings'
quickinfo = 'Load chart settings'
is_checked = abap_false
is_disabled = abap_false ).
o_tool->add_button( fcode = ''
icon = ''
butn_type = cntb_btype_sep
text = ''
quickinfo = ''
is_checked = abap_false
is_disabled = abap_false ).
o_tool->add_button( fcode = CONV #( lcl_events=>co_btn_save_cust )
icon = icon_system_save
butn_type = cntb_btype_button
text = 'Save settings'
quickinfo = 'Save chart settings'
is_checked = abap_false
is_disabled = abap_false ).
o_tool->add_button( fcode = ''
icon = ''
butn_type = cntb_btype_sep
text = ''
quickinfo = ''
is_checked = abap_false
is_disabled = abap_false ).
o_tool->add_button( fcode = CONV #( lcl_events=>co_btn_load_data )
icon = icon_open
butn_type = cntb_btype_button
text = 'Load data'
quickinfo = 'Load chart data'
is_checked = abap_false
is_disabled = abap_false ).
o_tool->add_button( fcode = ''
icon = ''
butn_type = cntb_btype_sep
text = ''
quickinfo = ''
is_checked = abap_false
is_disabled = abap_false ).
o_tool->add_button( fcode = CONV #( lcl_events=>co_btn_example_bar )
icon = icon_display
butn_type = cntb_btype_button
text = 'Beispiel Bargraph'
quickinfo = 'Beispieldaten + Settings'
is_checked = abap_false
is_disabled = abap_false ).
o_tool->add_button( fcode = ''
icon = ''
butn_type = cntb_btype_sep
text = ''
quickinfo = ''
is_checked = abap_false
is_disabled = abap_false ).
o_tool->add_button( fcode = CONV #( lcl_events=>co_btn_example_scatter )
icon = icon_display
butn_type = cntb_btype_button
text = 'Beispiel Scatterplot'
quickinfo = 'Beispieldaten + Settings'
is_checked = abap_false
is_disabled = abap_false ).
o_tool->add_button( fcode = ''
icon = ''
butn_type = cntb_btype_sep
text = ''
quickinfo = ''
is_checked = abap_false
is_disabled = abap_false ).
o_tool->add_button( fcode = CONV #( lcl_events=>co_btn_clear )
icon = icon_delete
butn_type = cntb_btype_button
text = 'Löschen'
quickinfo = 'Alles löschen'
is_checked = abap_false
is_disabled = abap_false ).
o_tool->add_button( fcode = ''
icon = ''
butn_type = cntb_btype_sep
text = ''
quickinfo = ''
is_checked = abap_false
is_disabled = abap_false ).
o_tool->add_button( fcode = CONV #( lcl_events=>co_btn_print )
icon = icon_print
butn_type = cntb_btype_button
text = 'Drucken'
quickinfo = 'Chart drucken'
is_checked = abap_false
is_disabled = abap_false ).
* Eventhandler registrieren
SET HANDLER lcl_events=>on_function_selected FOR o_tool.
**********************************************************************
* Chart
**********************************************************************
* Daten holen
SELECT * FROM sflight INTO TABLE it_sflight UP TO 10 ROWS.
* Chart in unteren GUI-Container einbetten
o_chart = NEW #( parent = o_container_bottom ).
**********************************************************************
* Chart-Daten generieren
**********************************************************************
* leere Defaultdaten übergeben
DATA(it_xml_data) = VALUE w3htmltabtype( ).
o_chart->set_data( data_table = it_xml_data ).
**********************************************************************
* Chart-Customizing generieren
**********************************************************************
* leere Defaultdaten übergeben
DATA(it_xml_customizing) = VALUE w3htmltabtype( ).
o_chart->set_customizing( data_table = it_xml_customizing ).
**********************************************************************
* zus. Einstellungen
**********************************************************************
* Einstellungsdialoge anzeigen
DATA(o_adj) = CAST cl_gui_chart_engine_win( o_chart->get_control( ) ).
* Design-Anpassungen ermöglichen
o_adj->set_design_mode( flag = abap_true event = abap_true ).
* Einstellmöglichkeiten beschränken
* o_adj->restrict_chart_types( charttypes = 'Columns|Lines' ).
* o_adj->restrict_property_events( events = 'ChartType' ).
* Wertänderungen ermöglichen
o_adj->enable_value_change( ).
* Event-Handler registrieren
SET HANDLER lcl_events=>on_click FOR o_chart.
SET HANDLER lcl_events=>on_value_change FOR o_chart.
SET HANDLER lcl_events=>on_property_change FOR o_chart.
* Graph anzeigen
o_chart->render( ).
* leere Toolbar ausblenden
cl_abap_list_layout=>suppress_toolbar( ).
* cl_gui_container=>default_screen erzingen
WRITE: / space.
Weitere XML-Beispiele
Customizing für Scatter-Plot
<?xml version="1.0" encoding="utf-8"?>
<SAPChartCustomizing version="2.0">
<GlobalSettings>
<Dimension>Two</Dimension>
<Defaults>
<ChartType>Scatter</ChartType>
<FontFamily>Arial</FontFamily>
</Defaults>
</GlobalSettings>
<Elements>
<ChartElements>
<Title>
<Caption>Beispiel-Titel</Caption>
</Title>
<Subtitle>
<Caption>Untertitel</Caption>
</Subtitle>
<Legend>
<Alignment>ToPlotArea</Alignment>
<Position>Right</Position>
</Legend>
</ChartElements>
<ChartAxes>
<ValueAxis id="ValueAxis1">
<Visibility>true</Visibility>
<MinimumCalculation>Automatic</MinimumCalculation>
<MaximumCalculation>Automatic</MaximumCalculation>
<ScalingType>Linear</ScalingType>
<Order>Ascending</Order>
<Position>Primary</Position>
<Title>
<Caption>x</Caption>
</Title>
</ValueAxis>
</ChartAxes>
</Elements>
</SAPChartCustomizing>
Daten für Scatter-Plot
<?xml version="1.0" encoding="utf-8"?>
<ChartData>
<Categories>
<Category>Category 1</Category>
</Categories>
<Series customizing="Series1" label="y">
<Point label="P1">
<Value type="x">0</Value>
<Value type="y">5</Value>
</Point>
<Point label="P2">
<Value type="x">1</Value>
<Value type="y">10</Value>
</Point>
<Point label="P3">
<Value type="x">2</Value>
<Value type="y">7</Value>
</Point>
</Series>
</ChartData>
Customizing für Bar-Chart
<?xml version="1.0" encoding="utf-8"?>
<SAPChartCustomizing version="2.0">
<GlobalSettings>
<Defaults>
<ChartType>Columns</ChartType>
<FontFamily>Arial</FontFamily>
</Defaults>
</GlobalSettings>
<Elements>
<ChartElements>
<Title>
<Visibility>true</Visibility>
<Caption>Caption1</Caption>
</Title>
</ChartElements>
</Elements>
</SAPChartCustomizing>
Daten für Bar-Chart
<?xml version="1.0" encoding="utf-8"?>
<ChartData>
<Categories>
<Category>Category 1</Category>
<Category>Category 2</Category>
<Category>Category 3</Category>
</Categories>
<Series customizing="Series1" label="Series 1">
<Point>
<Value type="y">5</Value>
</Point>
<Point>
<Value type="y">10</Value>
</Point>
<Point>
<Value type="y">7</Value>
</Point>
</Series>
<Series customizing="Series2" label="Series 2">
<Point>
<Value type="y">7</Value>
</Point>
<Point>
<Value type="y">9</Value>
</Point>
<Point>
<Value type="y">23</Value>
</Point>
</Series>
</ChartData>
Weiterführende Infos
Easy Charts
Creating Charts
abapblog.com
catmull rom
Custom Chart Creation