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