Business Graphics can be easily customized at design time, but sometimes customizing parameters are not known until runtime. For example, graph title that includes selection criteria. This is where Business Graphics runtime customization come into play.
During runtime further customizing setting can be made in addition to ones made at design time. This is done using IF_WD_BUSIN_GRAPHICS_MTD_HNDL Business Graphics method handler.
I created a demo application that compares number of occupied and empty seats across airlines for selected flight date range (SAP Flight data model is used). Flight date selection is displayed in graph title
Define flight date range and click on Copy
Voilà
Below are step by step instructions of the demo application implementation:
1. Create ZCL_BUS_GR_DEMO class that implements data retrieval logic
CLASS zcl_bus_gr_rt_cust DEFINITION
PUBLIC
INHERITING FROM cl_wd_component_assistance
FINAL
CREATE PUBLIC .
*"* public components of class ZCL_BUS_GR_RT_CUST
*"* do not include other source files here!!!
PUBLIC SECTION.
TYPES:
BEGIN OF s_sflight,
carrid TYPE s_carr_id,
carrname TYPE s_carrname,
seatsmax TYPE s_seatsmax,
seatsocc TYPE s_seatsocc,
seatsocc_tooltip TYPE string,
seatsempty TYPE i,
seatsempty_tooltip TYPE string,
END OF s_sflight .
TYPES:
t_sflight TYPE STANDARD TABLE OF s_sflight WITH DEFAULT KEY .
TYPES:
t_fldate TYPE RANGE OF s_date .
TYPES:
BEGIN OF s_selection,
fldate TYPE t_fldate,
END OF s_selection .
CLASS-METHODS get_t_sflight
IMPORTING
!it_fldate TYPE t_fldate OPTIONAL
RETURNING
VALUE(rt_sflight) TYPE t_sflight .
*"* protected components of class ZCL_BUS_GR_DEMO
*"* do not include other source files here!!!
PROTECTED SECTION.
*"* private components of class ZCL_BUS_GR_DEMO
*"* do not include other source files here!!!
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_bus_gr_rt_cust IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_BUS_GR_RT_CUST=>GET_T_SFLIGHT
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_FLDATE TYPE T_FLDATE(optional)
* | [<-()] RT_SFLIGHT TYPE T_SFLIGHT
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD get_t_sflight.
DATA: w_percent(3) TYPE p DECIMALS 1.
DATA: w_i(13) TYPE c.
DATA: wa_sflight TYPE s_sflight.
SELECT carrid SUM( seatsmax ) AS seatsmax SUM( seatsocc ) AS seatsocc
INTO CORRESPONDING FIELDS OF TABLE rt_sflight
FROM sflight
WHERE fldate IN it_fldate
GROUP BY carrid.
LOOP AT rt_sflight INTO wa_sflight.
wa_sflight-seatsempty = wa_sflight-seatsmax - wa_sflight-seatsocc.
*
SELECT SINGLE carrname
INTO wa_sflight-carrname
FROM scarr
WHERE carrid = wa_sflight-carrid.
IF sy-subrc <> 0.
CLEAR: wa_sflight-carrname.
ENDIF.
*
wa_sflight-seatsocc_tooltip = w_percent = wa_sflight-seatsocc * 100 / wa_sflight-seatsmax.
WRITE: wa_sflight-seatsocc TO w_i.
SHIFT w_i LEFT DELETING LEADING SPACE.
CONCATENATE wa_sflight-carrname cl_abap_char_utilities=>cr_lf 'Occupied' w_i ' (' wa_sflight-seatsocc_tooltip '%)' INTO wa_sflight-seatsocc_tooltip.
REPLACE: 'Occupied' WITH 'Occupied ' INTO wa_sflight-seatsocc_tooltip,
'( ' WITH '(' INTO wa_sflight-seatsocc_tooltip,
' %)' WITH '%)' INTO wa_sflight-seatsocc_tooltip.
*
wa_sflight-seatsempty_tooltip = w_percent = wa_sflight-seatsempty * 100 / wa_sflight-seatsmax.
WRITE: wa_sflight-seatsempty TO w_i.
SHIFT w_i LEFT DELETING LEADING SPACE.
CONCATENATE wa_sflight-carrname cl_abap_char_utilities=>cr_lf 'Empty' w_i ' (' wa_sflight-seatsempty_tooltip '%)' INTO wa_sflight-seatsempty_tooltip.
REPLACE: 'Empty' WITH 'Empty ' INTO wa_sflight-seatsempty_tooltip,
'( ' WITH '(' INTO wa_sflight-seatsempty_tooltip,
' %)' WITH '%)' INTO wa_sflight-seatsempty_tooltip.
*
MODIFY rt_sflight FROM wa_sflight TRANSPORTING seatsocc_tooltip carrname seatsempty seatsempty_tooltip.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
2.1. Create ZBUS_GR_RT_CUST component
2.2. Add ZCL_BUS_GR_RT_CUST assistance class and SELECT_OPTIONS usage of WDR_SELECT_OPTIONS component
3.1. Add SFLIGHT context node to MAIN view with cardinatlity 0..n
3.2. Add CARRID, CARRNAME, SEATSMAX, SEATSOCC, SEATSOCC_TOOLTIP, SEATSEMPTY and SEATSEMPTY_TOOLTIP attributes to SFLIGHT node of types S_CARR_ID, S_CARRNAME, S_SEATSMAX, S_SEATSOCC, STRING, S_SEATSFRE and STRING respectively
4.1. Add CUSTOMIZING node to MAIN view context with cardinality 1..1
4.2. Add XML attribute of type XSTRING to CUSTOMIZING node
5. Define MAIN view layout
5.1. Create 2 trays to arrange screen elements: one for flight date selection and another one for chart.
Set caption texts for the trays to Selection and Business Graphics respectively. Set layout of ROOTUIELEMENTCONTAINER to MatrixLayout. Set Layout Data for both trays to MatrixLayout
5.2. Add VIEWCONTAINER ViewContainerUIElement under TRAY_SELECT_OPTIONS tray
5.3. Add BusinessGraphics element under Business Graphics tray. Map SeriesSource property, set height and width
5.3.1. Add Category element under BusinessGraphics element. Map Description and Tooltip properties of category element.
5.3.2 Add Series element under BusinessGraphics element. Set Label and map pointSource
5.3.3 Update Occupied Point element mapping Label, Tooltip, ValueSource properties
5.3.4. Add Occupied NumericValue element and map its Value property
5.3.5. Add Series element under BusinessGraphics element. Set Label and map pointSource
5.3.6. Update Empty Point element mapping Label, Tooltip, ValueSource properties
5.3.7. Add Empty NumericValue element and map its Value property
5.4. Customize BusinessGraphics element to set chart type to Stacked_Column and show series labels
6. Add SELECT_OPTIONS Componet Use to MAIN view
7. Add SHOW_SELECTION attribute of type STRING to MAIN view
8. Define MAIN view methods
8.1. Define SET_SELECTION method that set default flight date selection
METHOD set_selection.
DATA: field TYPE REF TO data.
DATA: interface TYPE REF TO iwci_wdr_select_options.
DATA select_optionsTYPE ref to if_wd_select_options.
FIELD-SYMBOLS: <field> TYPE ANY.
interface = wd_this->wd_cpifc_select_options( ).
select_options= interface->init_selection_screen( ).
select_options->set_global_options( i_display_btn_cancel = abap_false ).
* Delete Fields
select_options->remove_selection_screen_item( 'FLDATE' ).
* Create Fields
field = select_options->create_range_table( 'S_DATE' ).
ASSIGN field->* TO <field>.
<field> = is_selection-fldate.
select_options->add_selection_field( i_id = 'FLDATE' it_result = field ).
ENDMETHOD.
8.2. Define GET_SELECTION method that reads flight date selection
METHOD get_selection.
DATA: w_fieldnameTYPE fieldname.
DATA: wa_selection_screen_item TYPE if_wd_select_options=>t_selection_screen_item,
wt_selection_screen_item TYPE if_wd_select_options=>tt_selection_screen_item.
DATA: interface_select_options TYPE REF TO iwci_wdr_select_options.
DATA: select_optionsTYPE ref to if_wd_select_options.
DATA: node TYPE REF TO if_wd_context_node.
DATA: component TYPE REF TO if_wd_component_usage.
DATA: interface_alvTYPE REF TO iwci_salv_wd_table.
FIELD-SYMBOLS: <f1> TYPE ANY,
<f2> TYPE ANY.
interface_select_options ?= wd_this->wd_cpifc_select_options( ).
select_options = interface_select_options->init_selection_screen( ).
select_options->get_selection_screen_items(
IMPORTING et_selection_screen_items = wt_selection_screen_item ).
LOOP AT wt_selection_screen_item INTO wa_selection_screen_item.
CONCATENATE 'RS_SELECTION-' wa_selection_screen_item-m_id INTO w_fieldname.
ASSIGN (w_fieldname) TO <f1>.
ASSIGN wa_selection_screen_item-mt_range_table->* TO <f2>.
<f1> = <f2>.
ENDLOOP.
ENDMETHOD.
8.3. Define INITIALIZE_SELECT_OPTIONS method that creates SELECT_OPTIONS component use and set default flight date selection
METHOD initialize_select_options.
DATA: ws_fldate TYPE LINE OF wd_assist->t_fldate.
DATA: ws_selection TYPE wd_assist->s_selection.
DATA: component_usage TYPE REF TO if_wd_component_usage,
interface TYPE REF TO iwci_wdr_select_options.
component_usage = wd_this->wd_cpuse_select_options( ).
IF component_usage->has_active_component( ) IS INITIAL.
component_usage->create_component( ).
ENDIF.
*
interface = wd_this->wd_cpifc_select_options( ).
*
ws_fldate-sign = 'I'.
ws_fldate-option = 'EQ'.
ws_fldate-high = sy-datum.
ws_fldate-low = ws_fldate-high - 365.
APPEND ws_fldate TO ws_selection-fldate.
set_selection( ws_selection ).
ENDMETHOD.
8.4. Define EXECUTE event handler method for ON_EXECUTE event of SELECT_OPTIONS component use. Purpose of this method to get data when user execute the program for specified flight date selection
METHOD execute.
DATA: ws_selection TYPE wd_assist->s_selection.
DATA: wt_sflight TYPE wd_this->elements_sflight.
DATA: node_sflight TYPE REF TO if_wd_context_node.
wd_this->show_selection = abap_true.
ws_selection = get_selection( ).
*
node_sflight = wd_context->get_child_node( wd_this->wdctx_sflight ).
wt_sflight = wd_assist->get_t_sflight( ws_selection-fldate ).
node_sflight->bind_table( wt_sflight ).
ENDMETHOD.
8.5. Define CUSTOMIZE_BUSINESS_GRAPHICS method. What this code is doing:
- Gets IF_WD_BUSIN_GRAPHICS_MTD_HNDL Business Graphics method handler
- Changes Business Graphics customizing XML template adding title caption
- Assings it CUSTOMIZING.XML context attribute
- Calls ADD_DIRECT_CUSTOMIZING method passing CUSTOMIZING.XML context attribute
METHOD customize_business_graphics.
DATA: w_selectionTYPE string.
DATA: w_fldate(10) TYPE c.
DATA: wa_fldateTYPE LINE OF wd_assist->t_fldate.
DATA: ws_selectionTYPE wd_assist->s_selection.
DATA: w_titleTYPE string.
DATA: business_graphicsTYPE REF TO cl_wd_business_graphics.
DATA: busin_graphics_mtd_hndl TYPE REF TO if_wd_busin_graphics_mtd_hndl.
DATA: w_customizing TYPE string VALUE
'<?xml version="1.0" encoding="utf-8" ?>' &
'<SAPChartCustomizing version="2.0">' &
'<Elements>' &
'<ChartElements>' &
'<Title>' &
'<Caption></Caption>' &
'</Title>' &
'</ChartElements>' &
'</Elements>' &
'</SAPChartCustomizing>',
w_customizing_x TYPE xstring.
DATA: out_convTYPE REF TO cl_abap_conv_out_ce.
DATA: node_customizingTYPE REF TO if_wd_context_node.
* Get Selecton
node_customizing = wd_context->get_child_node( wd_this->wdctx_customizing ).
ws_selection = get_selection( ).
IF wd_this->show_selection= abap_true.
IF NOT ws_selection-fldate[] IS INITIAL.
READ TABLE ws_selection-fldateINTO wa_fldateINDEX 1.
WRITE: wa_fldate-low TO w_fldate.
CONCATENATE 'from' w_fldate INTO w_selection SEPARATED BY SPACE.
WRITE: wa_fldate-high TO w_fldate.
CONCATENATE w_selection 'to' w_fldate INTO w_selection SEPARATED BY SPACE.
ENDIF.
wd_this->show_selection= abap_false.
ENDIF.
* Customize Business Graphics
business_graphics ?= ir_view->get_element( 'BUSINESSGRAPHICS' ).
busin_graphics_mtd_hndl ?= business_graphics->_method_handler.
w_title = 'Occupied vs Empty Seats by Airline'.
CONCATENATE w_title cl_abap_char_utilities=>cr_lf w_selection INTO w_title.
CONCATENATE '<Caption>' w_title'</Caption>' INTO w_title.
REPLACE REGEX '<Caption><\/Caption>' IN w_customizing WITH w_title.
out_conv = cl_abap_conv_out_ce=>create( encoding = 'UTF-8' ).
out_conv->convert( exporting data = w_customizing
importing buffer = w_customizing_x).
node_customizing->set_attribute( name = 'XML'
value = w_customizing_x).
busin_graphics_mtd_hndl->clear_direct_customizing( ).
busin_graphics_mtd_hndl->add_direct_customizing(
i_customizing_ctx_path = 'CUSTOMIZING.XML'
i_customizing_ctx_type = if_wd_busin_graphics_mtd_hndl=>mc_add_cust_xml_xstring ).
ENDMETHOD.
Hint: to get customizing XML string template just customize Business Graphic element at design time and look at customizing XML for the component
8.6. Implement WDDOINIT method calling INITIALIZE_SELECT_OPTIONS method
METHOD wddoinit .
initialize_select_options( ).
ENDMETHOD.
8.7. Implement WDDOMODIFVIEW method calling CUSTOMIZE_BUSINESS_GRAPHICS method
METHOD wddomodifyview.
customize_business_graphics( view ).
ENDMETHOD.
9. Embed WND_SELECTION_SCREEN view of SELECT_OPTIONS component use into VIEWCONTAINER element of MAIN view
10. Create ZBUS_GR_RT_CUST application