In last two posts related to D3.js integration, we have seen a Sneak Pick at d3.js and RESTful WebService Step-by-Step guide. In this post, I will show you how we will put all these pieces together for a full blown working solution on exposing the data and generating graphics using D3.js.
I have divided this tutorial in 3 parts, so be sure to check both previous posts before moving further.
Lets use the RESTful web service created in the previous step. You need to implement below logic to prepare the entire HTML with Data and D3.js JavaScript code and send it as request.
Parse the URL
Get the value from the URL. You can use the method GET_HEADER_FIELD of object SERVER attribute REQUEST. For the Demo, I would pass an integer as the URI parameter. I’ll use this integer to create number of required bars.
* get the request attributes lv_path = server->request->get_header_field( name = '~path_info' ). SHIFT lv_path LEFT BY 1 PLACES. SPLIT lv_path AT '/' INTO TABLE lt_request. READ TABLE lt_request INTO lv_param INDEX 1.
HTML template
First all you need to load the HTML template. Creating an HTML tag from scratch in ABAP would need lot of concatenation. Instead you load the file in SMW0. Get this HTML content to make up full output HTML. You place some place holder in the template file. You would need to replace this placeholder with your JSON data. The template file has everything – CSS, JavaScript to load D3.js, API calls to D3.js. So, if any change is required to HTML output other than data needs to be done in HTML. You can definitely create this from scratch or put more place holders to make it more dynamic.
Load the template d3_bar_chart using transaction code SMW0. Use the option “HTML templates for WebRFC application”. Use FM WWW_GET_SCRIPT_AND_HTML to get the HTML template content.
Exposing Data as JSON
For demo purpose, I would just create some random data. But you can definitely prepare actual data and convert that to JSON. To build a json, I have used a utility json4abap. Download the class include as a local class in the HTTP request handler. Prepare your data and convert the data to json.
Build Final HTML
Replace the placeholder with the JSON data in the HTML template. You would need to convert the JSON data to the table compatible to the HTML data. After that, FIND and REPLACE the placeholder with JSON data. Generate the HTML string and send it back to the request.
Code Snippet
Method IF_HTTP_EXTENSION~HANDLE_REQUEST of the class ZCL_TEST_D3_DEMO_HANDLER
method HANDLE_REQUEST
METHOD if_http_extension~handle_request. DATA: lv_path TYPE string, lv_cdata TYPE string, lv_param TYPE string. DATA: lt_request TYPE STANDARD TABLE OF string. DATA: lv_times TYPE i. * get the request attributes lv_path = server->request->get_header_field( name = '~path_info' ). SHIFT lv_path LEFT BY 1 PLACES. SPLIT lv_path AT '/' INTO TABLE lt_request. READ TABLE lt_request INTO lv_param INDEX 1. * convert to number TRY. lv_times = lv_param. CATCH cx_root. lv_times = 5. ENDTRY. * Get HTML data lv_cdata = me->prepare_html( lv_times ). * * Send the response back server->response->set_cdata( data = lv_cdata ). ENDMETHOD.
Method PREPARE_HTML of the class PREPARE_HTML
method PREPARE_HTML
METHOD prepare_html. TYPE-POOLS: swww. TYPES: BEGIN OF ty_data, label TYPE char5, value TYPE i, END OF ty_data. DATA: ls_data TYPE ty_data, lt_data TYPE TABLE OF ty_data. DATA: lr_json TYPE REF TO json4abap, l_json TYPE string. DATA: lt_json TYPE soli_tab. DATA: template TYPE swww_t_template_name, html_table TYPE TABLE OF w3html. DATA: ls_result TYPE match_result. DATA: lt_html_final TYPE TABLE OF w3html. DATA: lv_to_index TYPE i. DATA: lv_total TYPE i. DATA: ls_html LIKE LINE OF lt_html_final. * Some dummy data. This can be real data based on the parameters * added in the URL CALL FUNCTION 'RANDOM_INITIALIZE'. DO 3 TIMES. CALL FUNCTION 'RANDOM_I4' EXPORTING rnd_min = 0 rnd_max = 20. ENDDO. DO iv_times TIMES. ls_data-label = sy-index + 70. CONDENSE ls_data-label. CALL FUNCTION 'RANDOM_I4' EXPORTING rnd_min = 0 rnd_max = 20 IMPORTING rnd_value = ls_data-value. APPEND ls_data TO lt_data. ENDDO. * Create JSON CREATE OBJECT lr_json. l_json = lr_json->json( abapdata = lt_data name = 'cdata' ). * convert string to 255 lt_json = cl_bcs_convert=>string_to_soli( l_json ). * Get template data from the SMW0 template = 'ZDEMO_D3_BAR_CHART'. CALL FUNCTION 'WWW_GET_SCRIPT_AND_HTML' EXPORTING obj_name = template TABLES html = html_table EXCEPTIONS object_not_found = 1. * Merge data into output table FIND FIRST OCCURRENCE OF '&json_data_holder&' IN TABLE html_table RESULTS ls_result. lv_to_index = ls_result-line - 1. lv_total = LINES( html_table ). APPEND LINES OF html_table FROM 1 TO lv_to_index TO lt_html_final. APPEND LINES OF lt_json TO lt_html_final. ls_result-line = ls_result-line + 1. APPEND LINES OF html_table FROM ls_result-line TO lv_total TO lt_html_final. LOOP AT lt_html_final INTO ls_html. CONCATENATE rv_html_string ls_html-line INTO rv_html_string. ENDLOOP. ENDMETHOD.
Output
When you execute the URL with any integer value, you will get output like this. Doesn’t it look great?
Also published at: Bring Data to Life – Integrating D3.js in SAP via RESTful Web Service on SCN.
[…] Full Working Solution integrating D3.js […]
[…] Full Working Solution integrating D3.js […]