abap实现大数据-echar调用
前言
最近做了个bw+smart bi项目,smartbi虽然好,但感觉不是sap系列,总有非我族者其心必异的感觉。考虑smart bi软件原理也是使用echart h5的技术,所以找些网上的资料研究下abap能否直接使用echart,这里分享个demo
一、echart代码获取
https://echarts.apache.org/examples/zh/index.html,官网范例,我们需要看的是:完整代码
这个代码结构是:
//1.导入echart js类
import * as echarts from 'echars';//echarts.js
//2.获取html元素,用于放置echart图表
var chartDom = document.getElementById('main');
//3.初始化echart(作为html元素上的控件)
var myChart = echarts.init(chartDom);
//4.设置echarts.js里面的option参数(就是echart的各项设置)
var option;
option = {
xAxis: { //x轴
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: { //y轴
type: 'value'
},
series: [{ //数据和图表类型
data: [120, 200, 150, 80, 70, 110, 130],
type: 'bar', //图表类型
showBackground: true,
backgroundStyle: {
color: 'rgba(180, 180, 180, 0.2)'
}
}]
};
//5.通过setOption来设置HTML上echart控件的option
option && myChart.setOption(option);
二、abap实现
1.定义HTML控件
布局采取cl_gui_splitter_container——cl_gui_container——cl_gui_html_viewer,即分隔布局里面设置自定义容器,把htmlview控件放到自定义容器上面,最后echart显示在htmlview上对吧。
代码请见后面的所有代码,这里不重复贴出来
2.构建option
个人感觉根据不同的echart类型会有不同的option,所以用表形式维护吧
其实就是把echart范例的代码逐行分解到透明表,然后逐行append到内表
var myChart = echarts.init(document.getElementById("main"));
var option = {
title: {
text: "ECharts 入门示例"
},
tooltip: {},
legend: {
data:["销量"]
},
xAxis: {
data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
},
yAxis: {},
series: [{
name: "销量",
type: "bar",
data: [5, 20, 36, 10, 10, 20]
}]
};
myChart.setOption(option);
然后通过htmlview 的set_text方法带进去:
g_editor->set_text_as_r3table(
table = g_mytable
).
3.完整ABAP代码
贴上完整的代码,不解释,自己看:
*&---------------------------------------------------------------------*
*& Report ZECHART_DEMO
*&---------------------------------------------------------------------*
*& Echarts Demo
*& Creator Tangzhen
*& Description Echats效果展示
*&---------------------------------------------------------------------*
REPORT zechart_demo.
TABLES: sscrfields.
DATA: functxt TYPE smp_dyntxt.
DATA:
* Docking Container
docking TYPE REF TO cl_gui_docking_container,
fcode LIKE sy-ucomm,
myevent_tab TYPE cntl_simple_events,
myevent TYPE cntl_simple_event,
edurl(2048),
alignment TYPE i.
DATA script TYPE string.
CONSTANTS: line_length TYPE i VALUE 255."89
DATA:
splitter TYPE REF TO cl_gui_splitter_container, "分隔布局
container_1 TYPE REF TO cl_gui_container, "自定义容器
container_2 TYPE REF TO cl_gui_container,
* reference to wrapper class of control
g_editor TYPE REF TO cl_gui_textedit, "文本编辑框
* reference to custom container: necessary to bind TextEdit Control
g_repid LIKE sy-repid,
g_ok_code LIKE sy-ucomm, " return code from screen
g_mytable(line_length) TYPE c OCCURS 0.
CLASS lcl_html DEFINITION INHERITING FROM cl_gui_html_viewer. "定义派生类cl_gui_html_viewer类(接口)
PUBLIC SECTION.
METHODS constructor "重新
IMPORTING
!parent TYPE REF TO cl_gui_container.
METHODS execute_a_script."执行js 新起
ENDCLASS.
*
CLASS lcl_html IMPLEMENTATION. "实现和集成class/interface
METHOD constructor.
CALL METHOD super->constructor
EXPORTING
parent = parent
EXCEPTIONS
OTHERS = 1.
ENDMETHOD.
METHOD execute_a_script.
DATA scripttab TYPE soli_tab.
scripttab = cl_bcs_convert=>string_to_soli( script ).
set_script( script = scripttab ). "都是cl_gui_html_viewer里面定义的method
execute_script( EXCEPTIONS dp_error = 1 cntl_error = 2 ).
ENDMETHOD.
ENDCLASS.
DATA: html_control TYPE REF TO lcl_html.
SELECTION-SCREEN PUSHBUTTON 1(10) gen USER-COMMAND gen.
INITIALIZATION.
gen = '转换为echar'.
AT SELECTION-SCREEN.
IF sy-ucomm = 'GEN'. "定义按键的方法
PERFORM frm_execute.
ENDIF.
AT SELECTION-SCREEN OUTPUT.
PERFORM init_control. "初始化html的控件
*&---------------------------------------------------------------------*
*& Form init_control
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
FORM init_control.
DATA rc TYPE i.
IF docking IS INITIAL. "cl_gui_docking_container 停靠容器(布局)
CREATE OBJECT docking
EXPORTING
repid = sy-repid
dynnr = sy-dynnr
side = docking->dock_at_bottom "停靠在底部(上下形式分隔)
* extension = 1000
ratio = 95. "比例
CREATE OBJECT splitter "间隔位置
EXPORTING
parent = docking
rows = 1
columns = 2.
CALL METHOD splitter->get_container
EXPORTING
row = 1
column = 1
RECEIVING
container = container_1.
CALL METHOD splitter->get_container
EXPORTING
row = 1
column = 2
RECEIVING
container = container_2.
splitter->set_column_width(
EXPORTING
id = 1
width = 40 "设置为百分比
IMPORTING
result = rc ).
ENDIF.
IF g_editor IS INITIAL.
CREATE OBJECT g_editor "编辑文本框格式
EXPORTING
parent = container_1
wordwrap_mode = cl_gui_textedit=>wordwrap_at_fixed_position
wordwrap_position = line_length "行的长度
wordwrap_to_linebreak_mode = cl_gui_textedit=>true.
DATA:LT_ECHARTSET TYPE TABLE OF ZTFI_ECHAR****.
FIELD-SYMBOLS:<FS> LIKE LINE OF LT_ECHARTSET .
select * from ZTFI_ECHAR*** into table LT_ECHARTSET WHERE ZTYPE = 'bar'.
LOOP AT LT_ECHARTSET ASSIGNING <FS>.
APPEND <FS>-ZOPTION TO g_mytable .
ENDLOOP.
g_editor->set_text_as_r3table(
table = g_mytable
).
ENDIF.
IF html_control IS INITIAL.
CREATE OBJECT html_control
EXPORTING
parent = container_2.
PERFORM load_home_page. "加载主页
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form LOAD_HOME_PAGE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM load_home_page .
DATA: doc_url(80).
DATA: html_table TYPE TABLE OF w3html INITIAL SIZE 10,
html2pack TYPE TABLE OF swww_t_html_l INITIAL SIZE 100,
wa_html2pack TYPE swww_t_html_l,
wa_html TYPE w3html,
pos_tag_begin TYPE i,
pos_tag_end TYPE i,
l_src_len TYPE i,
in_pre_tag TYPE c,
in_script_tag TYPE c,
l_wa_len TYPE i.
CALL METHOD html_control->load_mime_object
EXPORTING
object_id = 'ZECHARTS'
object_url = 'echarts.js'
EXCEPTIONS
OTHERS = 1.
DEFINE fill_html.
APPEND &1 TO html_table.
END-OF-DEFINITION.
fill_html:
'<!DOCTYPE html>', "echarts全包 可不用
'<html>',
'<head>',
'<meta charset="utf-8">',
'<titile>显示标题</title>',
* '!-- 引入 ECharts 文件 -->'
'<script src="http://192.168.0.20:2801/Scripts/js/plugins/echarts/echarts.min.js"></script>',
'</head>',
'<body>',
'<div id="main" style="width:800px;height:500px;">这里的div会显示echar对象</div>',
'</body>',
'</html>'.
"html内表标签处理 的HTML必须处理
DESCRIBE FIELD wa_html LENGTH l_wa_len IN CHARACTER MODE.
l_src_len = l_wa_len.
LOOP AT html_table INTO wa_html.
wa_html2pack-len = strlen( wa_html ).
* Note 941692 - For space supression at 255th character - begin.
IF wa_html2pack-len EQ 254.
wa_html2pack-len = wa_html2pack-len + 1.
ENDIF.
* Note 941692 - For space supression at 255th character - end.
pos_tag_end = wa_html2pack-len.
pos_tag_begin = 0.
SEARCH wa_html FOR '<body'.
IF sy-subrc EQ 0.
in_pre_tag = 'X'.
ENDIF.
SEARCH wa_html FOR '<scipt'.
IF sy-subrc EQ 0.
in_script_tag = 'X'.
ENDIF.
IF in_pre_tag = 'X' OR in_script_tag = 'X'.
wa_html2pack-line = wa_html.
wa_html2pack-len = l_wa_len.
ELSE.
SEARCH wa_html FOR '>'.
IF sy-subrc EQ 0.
pos_tag_end = sy-fdpos.
SEARCH wa_html FOR '<'.
IF sy-subrc EQ 0.
pos_tag_begin = sy-fdpos.
ENDIF.
ENDIF.
IF pos_tag_end < pos_tag_begin.
wa_html2pack-line = wa_html.
ELSE.
IF l_src_len LT l_wa_len.
MOVE wa_html TO wa_html2pack-line.
ELSE.
MOVE wa_html TO wa_html2pack-line.
ENDIF.
ENDIF.
l_src_len = strlen( wa_html2pack-line ).
ENDIF.
APPEND wa_html2pack TO html2pack.
SEARCH wa_html FOR '<head'.
IF sy-subrc EQ 0.
CLEAR in_pre_tag.
ENDIF.
SEARCH wa_html FOR ''.
IF sy-subrc EQ 0.
CLEAR in_script_tag.
ENDIF.
ENDLOOP.
CLEAR html_table.
"pack to htmltable
CALL FUNCTION 'WWW_PACK_TABLE'
TABLES
html_table = html2pack
html_table_packed = html_table.
CALL METHOD html_control->load_data
EXPORTING
url = 'chart.html'
IMPORTING
assigned_url = doc_url
CHANGING
data_table = html_table.
CALL METHOD html_control->show_url
EXPORTING
url = doc_url.
html_control->set_ui_flag( html_control->uiflag_no3dborder ).
CLEAR script.
CALL METHOD g_editor->get_textstream
IMPORTING
text = script.
CALL METHOD cl_gui_cfw=>flush
EXCEPTIONS
OTHERS = 1.
html_control->execute_a_script( ).
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_EXECUTE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_execute .
CLEAR script.
CALL METHOD g_editor->get_textstream
IMPORTING
text = script.
html_control->do_refresh( ). "必须刷新页面
CALL METHOD cl_gui_cfw=>flush
EXCEPTIONS
OTHERS = 1.
"开始处 添加
IF script NS 'var myChart'.
CONCATENATE
'var myChart = echarts.init(document.getElementById("main"));'
script
INTO script.
ENDIF.
"结束时 添加
IF script NS 'myChart.setOption'.
CONCATENATE script
'myChart.setOption(option);'
INTO script SEPARATED BY cl_abap_char_utilities=>newline.
ENDIF.
CONCATENATE
'var div = document.getElementById("main");'
'div.style.width = document.body.clientWidth + "px";'
'div.style.height = document.body.clientWidth*6/10 + "px";'
script INTO script SEPARATED BY cl_abap_char_utilities=>newline.
html_control->execute_a_script( ). "执行脚本
ENDFORM.
执行后效果截图:
总结
今天到此为止,其实通过构建,还是可以实现灵活的数据列表、罗盘、仪表甚至综合指标桌面等。后面有空再写个项目出来