[ABAP] Vertikaler Tabstrip-Container für Controls (CL_GUI_CONTAINER_BAR_XT, CL_GUI_CONTAINER_BAR_2, CL_GUI_CONTAINER_BAR)

Variante 1 (CL_GUI_CONTAINER_BAR_XT)

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      on_clicked FOR EVENT clicked OF cl_gui_container_bar_xt
        IMPORTING
            id
            container
            sender.
    CLASS-METHODS:
      on_empty FOR EVENT empty OF cl_gui_container_bar_xt
        IMPORTING
            sender.
    CLASS-METHODS:
      on_closed FOR EVENT closed OF cl_gui_container_bar_xt
        IMPORTING
            id
            sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Eintrag angeklickt
  METHOD on_clicked.
    MESSAGE |Property: { id } { container->get_container_type( ) }| TYPE 'S'.
  ENDMETHOD.
* wenn keine Einträge mehr vorhanden (z.B. alle durch Klick auf die Schließen-Kreuze geschlossen)
  METHOD on_empty.
    BREAK-POINT.
  ENDMETHOD.
* wenn Schließen-Kreuz eines Eintrages geklickt
  METHOD on_closed.
    BREAK-POINT.
  ENDMETHOD.
ENDCLASS.

INITIALIZATION.
  TRY.
* Vertikalen Splitter erzeugen
      DATA(o_splitter) = NEW cl_gui_splitter_container( parent                  = cl_gui_container=>default_screen
                                                        no_autodef_progid_dynnr = abap_true
                                                        rows                    = 1
                                                        columns                 = 2 ).

* 10% / 90% Teilung
      o_splitter->set_column_width( id = 1 width = 10 ).

      DATA(o_container_left) = o_splitter->get_container( row = 1 column = 1 ).
      DATA(o_container_right) = o_splitter->get_container( row = 1 column = 2 ).

* Zwei Einträge im cl_gui_container_bar_xt
      DATA(it_captions) = VALUE sbptcaptns( ( caption      = 'ABAP'
                                              icon         = icon_abap
                                              no_close     = abap_false
                                              name         = 'CAP1'
                                              invisible    = abap_false
                                              pre_inst     = abap_false
                                              reuse_cnt_of = '' )
                                            ( caption      = 'ABC'
                                              icon         = icon_abc
                                              no_close     = abap_false
                                              name         = 'CAP2'
                                              invisible    = abap_false
                                              pre_inst     = abap_false
                                              reuse_cnt_of = '' ) ).

* cl_gui_container_bar_xt im linken Splitter erzeugen
      DATA(o_toolbar_xt) = NEW cl_gui_container_bar_xt( active_id     = 1                                    " Nr. des aktiven Eintrages
                                                        parent        = o_container_left                     " Einbettung in linken Container
                                                        captions      = it_captions                          " Einträge
                                                        style         = cl_gui_container_bar_xt=>c_style_fix " Style: Fix = Feste Anordnung, Outlook = Anordnung klappt
                                                        close_buttons = abap_true ).                         " Schließen Kreuze anzeigen

* einen weiterer Eintrag im cl_gui_container_bar_xt hinzufügen
      DATA(lv_caption) = VALUE sbptcaptn( caption      = 'Activate'
                                          icon         = icon_activate
                                          no_close     = abap_false
                                          name         = 'CAP3'
                                          invisible    = abap_false
                                          pre_inst     = abap_false
                                          reuse_cnt_of = '' ).

* Eintrag einfügen und Id holen
      DATA(lv_id) = 0.
      o_toolbar_xt->add_cell( EXPORTING caption = lv_caption
                              CHANGING  id      = lv_id ).

* Testweise Container zum Eintrag ermitteln
      DATA(o_cont) = o_toolbar_xt->get_container( id = lv_id ).

* letzen Eintrag im cl_gui_container_bar_xt aktiv (ausgewählt) setzen
      o_toolbar_xt->set_active( id = lv_id ).

* Eventhandler registrieren
      SET HANDLER lcl_events=>on_clicked FOR o_toolbar_xt.
      SET HANDLER lcl_events=>on_empty FOR o_toolbar_xt.
      SET HANDLER lcl_events=>on_closed FOR o_toolbar_xt.

* im rechten Splitter Beispieldaten anzeigen
      DATA: it_sflight TYPE STANDARD TABLE OF sflight.

      SELECT * FROM sflight INTO TABLE @it_sflight.

      DATA: o_salv TYPE REF TO cl_salv_table.

      cl_salv_table=>factory( EXPORTING
                                r_container    = o_container_right
                              IMPORTING
                                r_salv_table   = o_salv
                              CHANGING
                                t_table        = it_sflight ).

      o_salv->get_functions( )->set_all( ).
      o_salv->display( ).

* leere Standard-Toolbar ausblenden
      cl_abap_list_layout=>suppress_toolbar( ).

* Ausgabe von cl_gui_container=>default_screen erzwingen
      WRITE: space.
    CATCH cx_root INTO DATA(e_txt).
  ENDTRY.

Variante 2 (CL_GUI_CONTAINER_BAR_2)

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      on_clicked FOR EVENT clicked OF cl_gui_container_bar_2
        IMPORTING
            id
            container
            sender.
    CLASS-METHODS:
      on_empty FOR EVENT empty OF cl_gui_container_bar_2
        IMPORTING
            sender.
    CLASS-METHODS:
      on_closed FOR EVENT closed OF cl_gui_container_bar_2
        IMPORTING
            id
            sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Eintrag angeklickt
  METHOD on_clicked.
    MESSAGE |Property: { id } { container->get_container_type( ) }| TYPE 'S'.
  ENDMETHOD.
* wenn keine Einträge mehr vorhanden (z.B. alle durch Klick auf die Schließen-Kreuze geschlossen)
  METHOD on_empty.
    BREAK-POINT.
  ENDMETHOD.
* wenn Schließen-Kreuz eines Eintrages geklickt
  METHOD on_closed.
    BREAK-POINT.
  ENDMETHOD.
ENDCLASS.

INITIALIZATION.
  TRY.
* Vertikalen Splitter erzeugen
      DATA(o_splitter) = NEW cl_gui_splitter_container( parent                  = cl_gui_container=>default_screen
                                                        no_autodef_progid_dynnr = abap_true
                                                        rows                    = 1
                                                        columns                 = 2 ).

* 10% / 90% Teilung
      o_splitter->set_column_width( id = 1 width = 10 ).

      DATA(o_container_left) = o_splitter->get_container( row = 1 column = 1 ).
      DATA(o_container_right) = o_splitter->get_container( row = 1 column = 2 ).

* Zwei Einträge im cl_gui_container_bar_2
      DATA(it_captions) = VALUE sbptcaptns( ( caption      = 'ABAP'
                                              icon         = icon_abap
                                              no_close     = abap_false
                                              name         = 'CAP1'
                                              invisible    = abap_false
                                              pre_inst     = abap_false
                                              reuse_cnt_of = '' )
                                            ( caption      = 'ABC'
                                              icon         = icon_abc
                                              no_close     = abap_false
                                              name         = 'CAP2'
                                              invisible    = abap_false
                                              pre_inst     = abap_false
                                              reuse_cnt_of = '' ) ).

* cl_gui_container_bar_2 im linken Splitter erzeugen
      DATA(o_toolbar) = NEW cl_gui_container_bar_2( active_id     = 1                                    " Nr. des aktiven Eintrages
                                                    parent        = o_container_left                     " Einbettung in linken Container
                                                    captions      = it_captions                          " Einträge
                                                    style         = cl_gui_container_bar_2=>c_style_tile " Style: Fix = Feste Anordnung, tile = Menü, Outlook = Anordnung klappt
                                                    close_buttons = abap_false ).                        " Schließen Kreuze anzeigen

* einen weiterer Eintrag im cl_gui_container_bar_2 hinzufügen
      DATA(lv_caption) = VALUE sbptcaptn( caption      = 'Activate'
                                          icon         = icon_activate
                                          no_close     = abap_false
                                          name         = 'CAP3'
                                          invisible    = abap_false
                                          pre_inst     = abap_false
                                          reuse_cnt_of = '' ).

* Eintrag einfügen und Id holen
      DATA(lv_id) = 0.
      o_toolbar->add_cell( EXPORTING caption = lv_caption
                           CHANGING  id      = lv_id ).

* Testweise Container zum Eintrag ermitteln
      DATA(o_cont) = o_toolbar->get_container( id = lv_id ).

* letzen Eintrag im cl_gui_container_bar_2 aktiv (ausgewählt) setzen
      o_toolbar->set_active( id = lv_id ).

* Eventhandler registrieren
      SET HANDLER lcl_events=>on_clicked FOR o_toolbar.
      SET HANDLER lcl_events=>on_empty FOR o_toolbar.
      SET HANDLER lcl_events=>on_closed FOR o_toolbar.

* im rechten Splitter Beispieldaten anzeigen
      DATA: it_sflight TYPE STANDARD TABLE OF sflight.

      SELECT * FROM sflight INTO TABLE @it_sflight.

      DATA: o_salv TYPE REF TO cl_salv_table.

      cl_salv_table=>factory( EXPORTING
                                r_container    = o_container_right
                              IMPORTING
                                r_salv_table   = o_salv
                              CHANGING
                                t_table        = it_sflight ).

      o_salv->get_functions( )->set_all( ).
      o_salv->display( ).

* leere Standard-Toolbar ausblenden
      cl_abap_list_layout=>suppress_toolbar( ).

* Ausgabe von cl_gui_container=>default_screen erzwingen
      WRITE: space.
    CATCH cx_root INTO DATA(e_txt).
  ENDTRY.

Variante 3 (CL_GUI_CONTAINER_BAR)

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      on_clicked FOR EVENT clicked OF cl_gui_container_bar
        IMPORTING
            id
            container
            sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Eintrag angeklickt
  METHOD on_clicked.
    MESSAGE |Property: { id } { container->get_container_type( ) }| TYPE 'S'.
  ENDMETHOD.
ENDCLASS.

INITIALIZATION.
  TRY.
* Vertikalen Splitter erzeugen
      DATA(o_splitter) = NEW cl_gui_splitter_container( parent                  = cl_gui_container=>default_screen
                                                        no_autodef_progid_dynnr = abap_true
                                                        rows                    = 1
                                                        columns                 = 2 ).

* 10% / 90% Teilung
      o_splitter->set_column_width( id = 1 width = 10 ).

      DATA(o_container_left) = o_splitter->get_container( row = 1 column = 1 ).
      DATA(o_container_right) = o_splitter->get_container( row = 1 column = 2 ).

* Drei Einträge im cl_gui_container_bar
      DATA(it_captions) = VALUE sbptcaptns( ( caption      = 'ABAP'
                                              icon         = icon_abap
                                              no_close     = abap_false
                                              name         = 'CAP1'
                                              invisible    = abap_false
                                              pre_inst     = abap_false
                                              reuse_cnt_of = '' )
                                            ( caption      = 'ABC'
                                              icon         = icon_abc
                                              no_close     = abap_false
                                              name         = 'CAP2'
                                              invisible    = abap_false
                                              pre_inst     = abap_false
                                              reuse_cnt_of = '' )
                                            ( caption      = 'Activate'
                                              icon         = icon_activate
                                              no_close     = abap_false
                                              name         = 'CAP3'
                                              invisible    = abap_false
                                              pre_inst     = abap_false
                                              reuse_cnt_of = '' ) ).

* cl_gui_container_bar im linken Splitter erzeugen
      DATA(o_toolbar) = NEW cl_gui_container_bar( active_id     = 1                " Nr. des aktiven Eintrages
                                                  parent        = o_container_left " Einbettung in linken Container
                                                  captions      = it_captions ).   " Einträge

* Eventhandler registrieren
      SET HANDLER lcl_events=>on_clicked FOR o_toolbar.

* im rechten Splitter Beispieldaten anzeigen
      DATA: it_sflight TYPE STANDARD TABLE OF sflight.

      SELECT * FROM sflight INTO TABLE @it_sflight.

      DATA: o_salv TYPE REF TO cl_salv_table.

      cl_salv_table=>factory( EXPORTING
                                r_container    = o_container_right
                              IMPORTING
                                r_salv_table   = o_salv
                              CHANGING
                                t_table        = it_sflight ).

      o_salv->get_functions( )->set_all( ).
      o_salv->display( ).

* leere Standard-Toolbar ausblenden
      cl_abap_list_layout=>suppress_toolbar( ).

* Ausgabe von cl_gui_container=>default_screen erzwingen
      WRITE: space.
    CATCH cx_root INTO DATA(e_txt).
  ENDTRY.

[ABAP] Zwei SALV-Grids in einem Splittercontainer anzeigen

* Daten für SALV-Grid oben
SELECT *
  INTO TABLE @DATA(it_scarr)
  FROM scarr.

* Daten für SALV-Grid unten
SELECT *
  INTO TABLE @DATA(it_sflight)
  FROM sflight.

* Referenzen auf GUI-Objekte
* Splitter
DATA: o_splitter_main TYPE REF TO cl_gui_splitter_container.
* Splitter-Container oben
DATA: o_container_o   TYPE REF TO cl_gui_container.
* Splitter-Container unten
DATA: o_container_u   TYPE REF TO cl_gui_container.

* Splitter auf default_screen erzeugen
o_splitter_main = NEW #( parent                  = cl_gui_container=>default_screen
                         no_autodef_progid_dynnr = abap_true       " wichtig
                         rows                    = 2
                         columns                 = 1 ).

* Höhe oberer Splitter in %
o_splitter_main->set_row_height( id = 1 height = 40 ).

* REF auf oberen und unteren Splitcontainer holen
o_container_o = o_splitter_main->get_container( row = 1 column = 1 ).
o_container_u = o_splitter_main->get_container( row = 2 column = 1 ).

* SALV-Table oben mit Fluggesellschaften
DATA: o_salv_o TYPE REF TO cl_salv_table.

cl_salv_table=>factory( EXPORTING
                          r_container  = o_container_o
                        IMPORTING
                          r_salv_table = o_salv_o
                        CHANGING
                          t_table      = it_scarr ).

* Grundeinstellungen
o_salv_o->get_functions( )->set_all( abap_true ).
o_salv_o->get_columns( )->set_optimize( abap_true ).
o_salv_o->get_display_settings( )->set_list_header( 'Fluggesellschaften' ).
o_salv_o->get_display_settings( )->set_striped_pattern( abap_true ).
o_salv_o->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).

* Spaltenüberschriften: technischer Name und Beschreibungstexte
LOOP AT o_salv_o->get_columns( )->get( ) ASSIGNING FIELD-SYMBOL(<so>).
  DATA(o_col_o) = <so>-r_column.
  o_col_o->set_short_text( || ).
  o_col_o->set_medium_text( || ).
  o_col_o->set_long_text( |{ o_col_o->get_columnname( ) }| ).
ENDLOOP.

* SALV-Grid anzeigen
o_salv_o->display( ).

* SALV-Table unten mit Flügen
DATA: o_salv_u TYPE REF TO cl_salv_table.

cl_salv_table=>factory( EXPORTING
                          r_container  = o_container_u
                        IMPORTING
                          r_salv_table = o_salv_u
                        CHANGING
                          t_table      = it_sflight ).

* Grundeinstellungen
o_salv_u->get_functions( )->set_all( abap_true ).
o_salv_u->get_columns( )->set_optimize( abap_true ).
o_salv_u->get_display_settings( )->set_list_header( 'Flüge' ).
o_salv_u->get_display_settings( )->set_striped_pattern( abap_true ).
o_salv_u->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).

* Spaltenüberschriften: technischer Name und Beschreibungstexte
LOOP AT o_salv_u->get_columns( )->get( ) ASSIGNING FIELD-SYMBOL(<su>).
  DATA(o_col_u) = <su>-r_column.
  o_col_u->set_short_text( || ).
  o_col_u->set_medium_text( || ).
  o_col_u->set_long_text( |{ o_col_u->get_columnname( ) }| ).
ENDLOOP.

* SALV-Grid anzeigen
o_salv_u->display( ).

* leere Toolbar ausblenden
cl_abap_list_layout=>suppress_toolbar( ).

* Erzwingen von cl_gui_container=>default_screen
WRITE: space.

[ABAP] Charts mit cl_gui_chart_engine / cl_gui_chart_engine_win anzeigen, ändern, laden und speichern (XML), Beispiel-Charts

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

[ABAP] Selektionsbild mit HTML-Elementen, Dateneingabe, SALV-Grid, CSS, Eventhandling

**********************************************************************
*
* Datentypen, Variablen, Konstanten
*
**********************************************************************
TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.

CONSTANTS: co_carrid TYPE string VALUE 'carrid'.
CONSTANTS: co_airpto TYPE string VALUE 'airpto'.

DATA: o_splitter_main TYPE REF TO cl_gui_splitter_container.
DATA: o_container_l   TYPE REF TO cl_gui_container.
DATA: o_container_r   TYPE REF TO cl_gui_container.
DATA: o_html TYPE REF TO cl_gui_html_viewer.
DATA: o_salv TYPE REF TO cl_salv_table.

DATA: it_spfli TYPE STANDARD TABLE OF spfli WITH DEFAULT KEY.
DATA: it_salv_spfli TYPE STANDARD TABLE OF spfli WITH DEFAULT KEY.
DATA: it_sairport TYPE STANDARD TABLE OF sairport WITH DEFAULT KEY.

DATA: it_html TYPE html_table.
**********************************************************************
*
* Eventhandler
*
**********************************************************************
CLASS lcl_html_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      on_sapevent FOR EVENT sapevent OF cl_gui_html_viewer
        IMPORTING
            action
            frame
            getdata
            postdata
            query_table
            sender.
ENDCLASS.

CLASS lcl_html_events IMPLEMENTATION.
* Link- oder Button-Klick
  METHOD on_sapevent.
    IF o_salv IS BOUND.
      TRY.
* Element in der Nodes-Tabelle lesen
          ASSIGN query_table[ name = co_carrid ] TO FIELD-SYMBOL(<carrid>).
          ASSIGN query_table[ name = co_airpto ] TO FIELD-SYMBOL(<airpto>).

          IF <carrid> IS ASSIGNED AND <airpto> IS ASSIGNED.
* iTab für SALV-Table neu aufbauen, abhängig von der Eingabe in den Formularfeldern
            it_salv_spfli = VALUE #( FOR <f> IN it_spfli WHERE ( ( carrid = <carrid>-value ) AND ( airpto = <airpto>-value ) )
                                     ( <f> )
                                   ).

          ENDIF.

* SALV-Table neu anzeigen
          o_salv->refresh( ).
        CATCH cx_root INTO DATA(e_txt).
          MESSAGE e_txt->get_text( ) TYPE 'S'.
      ENDTRY.
    ENDIF.
  ENDMETHOD.
ENDCLASS.
**********************************************************************
*
* SELECTION-SCREEN
*
**********************************************************************
* leeres Selektionsbild als Dummy für die Container-Objekte (o_splitter_main ...)
SELECTION-SCREEN BEGIN OF SCREEN 2000.
SELECTION-SCREEN END OF SCREEN 2000.
**********************************************************************
*
* INITIALIZATION
*
**********************************************************************
INITIALIZATION.
* Daten holen
  SELECT * INTO TABLE it_spfli FROM spfli.
  SELECT * INTO TABLE it_sairport FROM sairport.

* HTML-Code mit Buttons und Forms
  it_html = VALUE #(
                     ( |<html>| )
                     ( |  <head>| )
                     ( |    <meta http-equiv="content-type" content="text/html; charset=utf-8">| )
                     ( |    <script type="text/javascript">| )
                     ( |      function onKeyDown(f)| )
                     ( |      \{ if(event.keyCode == 13)| )
                     ( |         \{ document[f.name].submit();| )
                     ( |         \}| )
                     ( |      \}| )
                     ( |    </script>| )
                     ( |    <style type="text/css">| )
                     ( |       body \{| )
                     ( |         font-family: Courier New;| )
                     ( |         font-size: 13px;| )
                     ( |         font-style: normal;| )
                     ( |         font-variant: normal;| )
                     ( |         font-weight: 400;| )
                     ( |         line-height: 13px;| )
                     ( |       \}| )
                     ( |       form \{| )
                     ( |         background: lightblue;| )
                     ( |       \}| )
                     ( |       label \{| )
                     ( |         text-align: right;| )
                     ( |         line-height: 1.5;| )
                     ( |         float: left;| )
                     ( |         width: 40%;| )
                     ( |       \}| )
                     ( |       input \{| )
                     ( |         margin: 0 0 1em .2em;| )
                     ( |         padding: .2em .5em;| )
                     ( |         background-color: #fffbf0;| )
                     ( |         border: 1px solid #e7c157;| )
                     ( |         float: left;| )
                     ( |         width: 40%;| )
                     ( |         font-family: Courier New;| )
                     ( |         font-size: 13px;| )
                     ( |         font-style: normal;| )
                     ( |         font-variant: normal;| )
                     ( |         font-weight: 400;| )
                     ( |         line-height: 13px;| )
                     ( |       \}| )
                     ( |       select \{| )
                     ( |         margin: 0 0 1em .2em;| )
                     ( |         padding: .2em .5em;| )
                     ( |         background-color: #fffbf0;| )
                     ( |         border: 1px solid #e7c157;| )
                     ( |         float: left;| )
                     ( |         width: 40%;| )
                     ( |         font-family: Courier New;| )
                     ( |         font-size: 13px;| )
                     ( |         font-style: normal;| )
                     ( |         font-variant: normal;| )
                     ( |         font-weight: 400;| )
                     ( |         line-height: 13px;| )
                     ( |       \}| )
                     ( |       button \{| )
                     ( |         margin-top: 1.5em;| )
                     ( |         float: right;| )
                     ( |       \}| )
                     ( |      </style>| )
                     ( |  </head>| )
                     ( |  <body>| )
                     ( |    <form name="INPUT" accept-charset="utf-8" method="post" action="SAPEVENT:INPUT_FIELDS">| )
                     ( |      <br>| )
                     ( |      <label for="{ co_carrid }">Fluggesellschaft:</label>| )
                     ( |      <input type="text" name="{ co_carrid }" value="LH" onKeyDown="onKeyDown(this.form);">| )
                     ( |      <br>| )
                     ( |      <label for="{ co_airpto }">Zielflughafen:</label>| )
                     ( |      <select name="{ co_airpto }" value="JFK">| )
                   ).

  LOOP AT it_sairport ASSIGNING FIELD-SYMBOL(<a>).
    IF <a>-id = 'JFK'.
      APPEND |        <option selected>{ <a>-id }</option>| TO it_html.
    ELSE.
      APPEND |        <option>{ <a>-id }</option>| TO it_html.
    ENDIF.
  ENDLOOP.

  it_html = VALUE #( BASE it_html
                     ( |      </select>| )
                     ( |      <br>| )
                     ( |      <button type="submit" title="Anzeigen">Anzeigen</button>| )
                     ( |      <br>| )
                     ( |      <br>| )
                     ( |      <br>| )
                     ( |      <br>| )
                     ( |    </form>| )
                     ( |  </body>| )
                     ( |</html>| )
                   ).

**********************************************************************
*
* AT SELECTION-SCREEN OUTPUT
*
**********************************************************************
AT SELECTION-SCREEN OUTPUT.
* Doppelte Objekterzeugung unterbinden
  IF NOT o_splitter_main IS BOUND.
* Splitter auf default_screen (SELECTION-SCREEN 2000) erzeugen
    o_splitter_main = NEW #( parent  = cl_gui_container=>default_screen
                             rows    = 1
                             columns = 2 ).

* Breite in % (linke Spalte für den Tree)
    o_splitter_main->set_column_width( id = 1 width = 20 ).

* linken und rechten Splitcontainer holen
    o_container_l = o_splitter_main->get_container( row = 1 column = 1 ).
    o_container_r = o_splitter_main->get_container( row = 1 column = 2 ).

* HTML-Viewer
    o_html = NEW cl_gui_html_viewer( parent = o_container_l ).

* Eventtypten müssen gesondert registriert werden
    DATA(it_events) = VALUE ty_it_events( ( eventid    = cl_gui_html_viewer=>m_id_sapevent
                                            appl_event = abap_true ) ).

    o_html->set_registered_events( events = it_events ).

* Eventhandler registrieren
    SET HANDLER lcl_html_events=>on_sapevent FOR o_html.

* URL zu HTML holen
    DATA: lv_url TYPE skwf_url.

    o_html->load_data( IMPORTING
                         assigned_url = lv_url
                       CHANGING
                         data_table   = it_html ).

* HTML anzeigen
    o_html->show_url( url = lv_url ).

    it_salv_spfli = it_spfli.

* SALV-Table für Anzeige der Daten
    cl_salv_table=>factory( EXPORTING
                              r_container    = o_container_r
                            IMPORTING
                              r_salv_table   = o_salv
                            CHANGING
                              t_table        = it_salv_spfli ).

    o_salv->get_display_settings( )->set_striped_pattern( abap_true ).
    o_salv->get_columns( )->set_optimize( abap_true ).
    o_salv->get_functions( )->set_all( ).
    o_salv->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).
    o_salv->display( ).
  ENDIF.
**********************************************************************
*
* AT SELECTION-SCREEN
*
**********************************************************************
AT SELECTION-SCREEN.
* wenn "Ausführen" (F8) geklickt wurde
  IF sy-ucomm = 'CRET'.
* Selektionbild 2000 wieder anzeigen
    CALL SELECTION-SCREEN 2000.
  ENDIF.
**********************************************************************
*
* START-OF-SELECTION
*
**********************************************************************
START-OF-SELECTION.
* leeres Selektionbild 2000 anzeigen
  CALL SELECTION-SCREEN 2000.

[ABAP] Tree und SALV-Grid auf dem Selektionsbild ohne zus. Dynpro anzeigen, Eventhandling

**********************************************************************
*
* Datentypen, Variablen, Konstanten
*
**********************************************************************
TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.
TYPES: ty_it_nodes TYPE STANDARD TABLE OF mtreesnode WITH DEFAULT KEY.

DATA: o_splitter_main TYPE REF TO cl_gui_splitter_container.
DATA: o_container_l   TYPE REF TO cl_gui_container.
DATA: o_container_r   TYPE REF TO cl_gui_container.
DATA: o_tree TYPE REF TO cl_gui_simple_tree.
DATA: o_salv TYPE REF TO cl_salv_table.

DATA: it_tree_spfli TYPE STANDARD TABLE OF spfli.
DATA: it_salv_spfli TYPE STANDARD TABLE OF spfli.
DATA: it_nodes TYPE ty_it_nodes.
**********************************************************************
*
* Eventhandler
*
**********************************************************************
CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: on_selection_changed FOR EVENT selection_changed OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Klick auf ein aktives Baumelement
  METHOD on_selection_changed.
    IF o_salv IS BOUND.
* Element in der Nodes-Tabelle lesen
      ASSIGN it_nodes[ node_key = node_key ] TO FIELD-SYMBOL(<fs_node>).

* iTab für SALV-Table neu aufbauen, abhängig vom gewählten Baumelement
      it_salv_spfli = VALUE #( FOR l IN it_tree_spfli WHERE ( carrid = <fs_node>-text )
                               ( mandt = l-mandt
                                 carrid = l-carrid
                                 connid = l-connid
                                 countryfr = l-countryfr
                                 cityfrom = l-cityfrom
                                 airpfrom = l-airpfrom
                                 countryto = l-countryto
                                 cityto = l-cityto
                                 airpto = l-airpto
                                 fltime = l-fltime
                                 deptime = l-deptime
                                 arrtime = l-arrtime
                                 distance = l-distance
                                 distid = l-distid
                                 fltype = l-fltype
                                 period = l-period ) ).

* SALV-Table neu anzeigen
      o_salv->refresh( ).
    ENDIF.
  ENDMETHOD.
ENDCLASS.
**********************************************************************
*
* SELECTION-SCREEN
*
**********************************************************************
* leeres Selektionsbild als Dummy für die Container-Objekte (o_splitter_main ...)
SELECTION-SCREEN BEGIN OF SCREEN 2000.
SELECTION-SCREEN END OF SCREEN 2000.
**********************************************************************
*
* INITIALIZATION
*
**********************************************************************
INITIALIZATION.
  SELECT * INTO TABLE it_tree_spfli FROM spfli.
**********************************************************************
*
* START-OF-SELECTION
*
**********************************************************************
START-OF-SELECTION.
* leeres Selektionbild 2000 anzeigen
  CALL SELECTION-SCREEN 2000.
**********************************************************************
*
* AT SELECTION-SCREEN OUTPUT
*
**********************************************************************
AT SELECTION-SCREEN OUTPUT.
* Doppelte Objekterzeugung unterbinden
  IF NOT o_splitter_main IS BOUND.
* Splitter auf default_screen (SELECTION-SCREEN 2000) erzeugen
    o_splitter_main = NEW #( parent  = cl_gui_container=>default_screen
                             rows    = 1
                             columns = 2 ).

* Breite in % (linke Spalte für den Tree)
    o_splitter_main->set_column_width( id = 1 width = 15 ).

* linken und rechten Splitcontainer holen
    o_container_l = o_splitter_main->get_container( row = 1 column = 1 ).
    o_container_r = o_splitter_main->get_container( row = 1 column = 2 ).

* Tree-Objekt erzeugen
    o_tree = NEW #( parent = o_container_l
                    node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single ).

* Eventtypten müssen gesondert registriert werden
    DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_simple_tree=>eventid_selection_changed
                                            appl_event = abap_true ) ).

    o_tree->set_registered_events( events = it_events ).

    SET HANDLER lcl_events=>on_selection_changed FOR o_tree.

* Root-Node einfügen
    it_nodes = VALUE #( ( node_key  = 'ROOT'           " Node-Bezeichner
                          relatship = cl_gui_simple_tree=>relat_last_child
                          disabled  = abap_true
                          isfolder  = abap_true        " Typ Ordner für Root-Element
                          n_image   = icon_folder      " Icon Ordner
                          exp_image = icon_open_folder " Icon geöffneter Ordner
                          style     = cl_gui_simple_tree=>style_default
                          text      = 'Airlines' ) ).

* Childs an Root-Node anhängen
    LOOP AT it_tree_spfli ASSIGNING FIELD-SYMBOL(<fs_line>).
* bei Änderung der carrid neue carrid als Child anhängen
      AT NEW carrid.
        APPEND VALUE #( node_key  = |NODE{ sy-tabix }| " Node-Bezeichner
                        relatship = cl_gui_simple_tree=>relat_last_child
                        relatkey  = 'ROOT'             " an ROOT-Element anhängen
                        style     = cl_gui_simple_tree=>style_intensified
                        text      = |{ <fs_line>-carrid }| ) TO it_nodes.
      ENDAT.
    ENDLOOP.

* Nodes im Baum einfügen
    o_tree->add_nodes( table_structure_name = 'MTREESNODE' " Typ muss gleich mit Zeilentyp von ty_it_nodes sein
                       node_table           = it_nodes ).

* Root-Nodes des Trees expandieren
    o_tree->expand_root_nodes( ).

* leeres SALV-Grid erzeugen
    cl_salv_table=>factory( EXPORTING
                              r_container    = o_container_r
                            IMPORTING
                              r_salv_table   = o_salv
                            CHANGING
                              t_table        = it_salv_spfli ).

    o_salv->get_display_settings( )->set_striped_pattern( abap_true ).
    o_salv->get_columns( )->set_optimize( abap_true ).
    o_salv->get_functions( )->set_all( ).
    o_salv->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).
    o_salv->display( ).
  ENDIF.
**********************************************************************
*
* AT SELECTION-SCREEN
*
**********************************************************************
AT SELECTION-SCREEN.
* wenn "Ausführen" (F8) geklickt wurde
  IF sy-ucomm = 'CRET'.
* Selektionbild 2000 wieder anzeigen
    CALL SELECTION-SCREEN 2000.
  ENDIF.

[ABAP] GUI-Simple-Tree und SALV-Grid in Split-Container ohne Dynpro anzeigen, Eventhandling

TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.
TYPES: ty_it_nodes TYPE STANDARD TABLE OF mtreesnode WITH DEFAULT KEY.

DATA: o_salv TYPE REF TO cl_salv_table.
DATA: it_tree_spfli TYPE STANDARD TABLE OF spfli.
DATA: it_salv_spfli TYPE STANDARD TABLE OF spfli.
DATA: it_nodes TYPE ty_it_nodes.

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
* GUI Simple Tree
    CLASS-METHODS: on_keypress FOR EVENT node_keypress OF cl_gui_simple_tree
      IMPORTING
          node_key
          key
          sender.
    CLASS-METHODS: on_selection_changed FOR EVENT selection_changed OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
    CLASS-METHODS: on_expand_no_children FOR EVENT expand_no_children OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
* ALV-Events für das SALV-Grid
    CLASS-METHODS: on_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
      IMPORTING
          e_object
          sender.
    CLASS-METHODS: on_user_command FOR EVENT user_command OF cl_gui_alv_grid
      IMPORTING
          e_ucomm
          sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Tastendruck
  METHOD on_keypress.
    MESSAGE |Node: { node_key } Taste: { key }| TYPE 'S'.
  ENDMETHOD.
* Klick auf ein aktives Baumelement
  METHOD on_selection_changed.
* Element in der Nodes-Tabelle lesen
    ASSIGN it_nodes[ node_key = node_key ] TO FIELD-SYMBOL(<fs_node>).

* iTab für SALV-Table neu aufbauen
    CLEAR: it_salv_spfli.

    LOOP AT it_tree_spfli ASSIGNING FIELD-SYMBOL(<fs_line>) WHERE carrid = <fs_node>-text.
      APPEND <fs_line> TO it_salv_spfli.
    ENDLOOP.

* SALV-Table neu anzeigen
    o_salv->refresh( ).
  ENDMETHOD.
* bei Expandierung eines Baumelements ohne Unterelemente
  METHOD on_expand_no_children.
    MESSAGE |Node: { node_key }| TYPE 'S'.
  ENDMETHOD.

* Toolbar-Buttons hinzufügen:
* butn_type   Bezeichung
* 0           Button (normal)
* 1           Menü + Defaultbutton
* 2           Menü
* 3           Separator
* 4           Radiobutton
* 5           Auswahlknopf (Checkbox)
* 6           Menüeintrag
  METHOD on_toolbar.
* Separator hinzufügen
    APPEND VALUE #( butn_type = 3 ) TO e_object->mt_toolbar.
* Edit-Button hinzufügen
    APPEND VALUE #( butn_type = 5 text = 'Daten anzeigen' icon = icon_icon_list function = 'SHOW_DATA' quickinfo = 'Daten anzeigen' disabled = ' ' ) TO e_object->mt_toolbar.
  ENDMETHOD.
* Benutzerkommando (Button-Klick)
  METHOD on_user_command.
    CASE e_ucomm.
      WHEN 'SHOW_DATA'.
        DATA: lv_row TYPE i. " Zeile auf Grid
        DATA: lv_value TYPE char255. " Wert
        DATA: lv_col TYPE i. " Spalte auf Grid
        DATA: lv_row_id TYPE lvc_s_row. " Zeilen-Id
        DATA: lv_col_id TYPE lvc_s_col. " Spalten-Id
        DATA: lv_row_no TYPE lvc_s_roid. " Numerische Zeilen ID

        sender->get_current_cell( IMPORTING
                                    e_row = lv_row
                                    e_value = lv_value
                                    e_col = lv_col
                                    es_row_id = lv_row_id
                                    es_col_id = lv_col_id
                                    es_row_no = lv_row_no ).

        MESSAGE |Zeile: { lv_row }, Spalte: { lv_col }, Wert: { lv_value }, Spaltenname: { lv_col_id-fieldname }| TYPE 'S'.
    ENDCASE.
  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

  SELECT * INTO TABLE it_tree_spfli FROM spfli.

* Splitter auf screen0 erzeugen
  DATA(o_split) = NEW cl_gui_splitter_container( parent = cl_gui_container=>screen0
                                                 no_autodef_progid_dynnr = abap_true
                                                 rows = 1
                                                 columns = 2 ).

* Breite in % (linke Spalte für den Tree)
  o_split->set_column_width( id = 1 width = 15 ).

* linken und rechten Splitcontainer holen
  DATA(o_spl_left) = o_split->get_container( row = 1 column = 1 ).
  DATA(o_spl_right) = o_split->get_container( row = 1 column = 2 ).

  TRY.
* Tree-Objekt erzeugen
      DATA(o_tree) = NEW cl_gui_simple_tree( parent = o_spl_left
                                             node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single ).


* Eventtypten müssen gesondert registriert werden
      DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_simple_tree=>eventid_node_keypress
                                              appl_event = abap_true )
                                            ( eventid = cl_gui_simple_tree=>eventid_selection_changed
                                              appl_event = abap_true )
                                            ( eventid = cl_gui_simple_tree=>eventid_expand_no_children
                                              appl_event = abap_true ) ).

      o_tree->set_registered_events( events = it_events ).

      o_tree->add_key_stroke( cl_gui_simple_tree=>key_enter ).

* Events registrieren
      SET HANDLER lcl_events=>on_keypress FOR o_tree.
      SET HANDLER lcl_events=>on_selection_changed FOR o_tree.
      SET HANDLER lcl_events=>on_expand_no_children FOR o_tree.

* Root-Node einfügen
      it_nodes = VALUE #( ( node_key  = 'ROOT'           " Node-Bezeichner
                            relatship = cl_gui_simple_tree=>relat_last_child
                            disabled  = abap_true
                            isfolder  = abap_true        " Typ Ordner für Root-Element
                            n_image   = icon_folder      " Icon Ordner
                            exp_image = icon_open_folder " Icon geöffneter Ordner
                            style     = cl_gui_simple_tree=>style_default
                            text      = 'Airlines' ) ).

* Childs an Root-Node anhängen
      LOOP AT it_tree_spfli ASSIGNING FIELD-SYMBOL(<fs_line>).
* bei Änderung der carrid neue carrid als Child anhängen
        AT NEW carrid.
          APPEND VALUE #( node_key  = |NODE{ sy-tabix }| " eindeutiger Node-Bezeichner
                          relatship = cl_gui_simple_tree=>relat_last_child
                          relatkey  = 'ROOT'             " an ROOT-Element anhängen
                          style     = cl_gui_simple_tree=>style_intensified
                          text      = |{ <fs_line>-carrid }| ) TO it_nodes.
        ENDAT.
      ENDLOOP.

* Nodes im Baum einfügen
      o_tree->add_nodes( table_structure_name = 'MTREESNODE' " Typ muss gleich mit Zeilentyp von ty_it_nodes sein
                         node_table           = it_nodes ).

* Root-Nodes des Trees expandieren
      o_tree->expand_root_nodes( ).

* leeres SALV-Grid erzeugen
      cl_salv_table=>factory( EXPORTING
                                r_container    = o_spl_right
                              IMPORTING
                                r_salv_table   = o_salv
                              CHANGING
                                t_table        = it_salv_spfli ).

      o_salv->get_display_settings( )->set_striped_pattern( abap_true ).
      o_salv->get_columns( )->set_optimize( abap_true ).
      o_salv->get_functions( )->set_all( ).
      o_salv->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).
      o_salv->display( ).

* Trick: Aus dem Split-Container rechts das Grid-Objekt holen und nach cl_gui_alv_grid casten
      READ TABLE o_spl_right->children INDEX 1 ASSIGNING FIELD-SYMBOL(<child>).
      IF <child> IS ASSIGNED.
        DATA(o_alv_grid) = CAST cl_gui_alv_grid( <child> ).

* Eventhandler registrieren
        SET HANDLER lcl_events=>on_toolbar FOR o_alv_grid.
        SET HANDLER lcl_events=>on_user_command FOR o_alv_grid.
      ENDIF.

    CATCH cx_root INTO DATA(e_text).
      WRITE: / e_text->get_text( ).
  ENDTRY.

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

* cl_gui_container=>screen0 erzwingen
  WRITE space.