如何在Oracle Apex中为已审批PM_KPI记录自动渲染新图表
在Oracle Apex中为已审批KPI动态渲染专业图表的实现方案
完全可行,Oracle Apex提供了多种原生且专业的方式实现该需求,以下是几种优于原生HTML嵌入的推荐方案:
方案1:交互式网格+动态图表区域(直观原生方案)
适合需要用户选择查看特定KPI图表的场景:
- 创建交互式网格,数据源为:
SELECT ID, NAME_EN, NAME_AR, KPI_TYPE_EN FROM PM_KPI WHERE STATUS = '已审批' -- 替换为实际"已审批"状态值 - 添加独立图表区域,数据源关联KPI度量表(假设存在
PM_KPI_VALUES存储KPI实际值),通过页面项PX_KPI_ID过滤数据 - 配置交互式网格的行选择事件,触发动态操作:将选中行的
ID赋值给PX_KPI_ID,并刷新图表区域 - 可选:开启行展开功能,将图表嵌入展开面板,实现单页查看所有KPI图表
方案2:PL/SQL动态内容生成Apex图表(高度自定义)
适合需要批量渲染所有KPI图表的场景:
- 创建PL/SQL动态内容区域,代码示例:
DECLARE l_html VARCHAR2(32767); BEGIN FOR kpi IN (SELECT ID, NAME_EN, KPI_TYPE_EN FROM PM_KPI WHERE STATUS = '已审批') LOOP -- 生成图表容器 l_html := l_html || '<div id="chart_' || kpi.ID || '" class="kpi-chart" style="height:300px;margin:20px 0;"></div>'; -- 动态生成Apex图表初始化脚本 l_html := l_html || apex_javascript.add_onload_code( 'apex.chart.create(''chart_' || kpi.ID || ''', { series: [{ name: ''' || apex_escape.js(kpi.NAME_EN) || ''', data: ' || (SELECT JSON_ARRAYAGG(value ORDER BY period) FROM PM_KPI_VALUES WHERE KPI_ID = kpi.ID) || ' }], chart: { type: ''' || CASE kpi.KPI_TYPE_EN WHEN '趋势类' THEN 'line' WHEN '对比类' THEN 'bar' ELSE 'gauge' END || ''' }, title: { text: ''' || apex_escape.js(kpi.NAME_EN) || ''' } });' ); END LOOP; htp.p(l_html); END; - 注意:使用
apex_escape.js防止XSS注入,根据KPI类型动态切换图表类型
方案3:卡片区域结合Apex图表组件(优化原生卡片布局)
改进你之前尝试的卡片方案,使用原生图表组件提升专业性:
- 创建基于SQL的卡片区域,数据源为已审批KPI列表
- 编辑卡片模板,在主体部分添加图表占位符:
<div class="card-body"> <h5 class="card-title">#NAME_EN#</h5> <div id="chart_#ID#" style="height:250px;"></div> <p class="card-text mt-2">#DESCRIPTION_EN#</p> </div> - 添加页面级JavaScript,通过AJAX批量加载图表数据:
document.addEventListener('DOMContentLoaded', function() { apex.server.process('GET_ALL_KPI_DATA', {}, { success: function(data) { data.forEach(kpi => { apex.chart.create(`chart_${kpi.id}`, { series: [{ data: kpi.values }], chart: { type: kpi.chart_type }, title: { text: kpi.name } }); }); } }); }); - 创建AJAX进程
GET_ALL_KPI_DATA,返回所有KPI的度量数据:DECLARE BEGIN apex_json.open_array; FOR kpi IN (SELECT ID, NAME_EN, KPI_TYPE_EN FROM PM_KPI WHERE STATUS = '已审批') LOOP apex_json.open_object; apex_json.write('id', kpi.ID); apex_json.write('name', kpi.NAME_EN); apex_json.write('chart_type', CASE kpi.KPI_TYPE_EN WHEN '趋势类' THEN 'line' WHEN '对比类' THEN 'bar' ELSE 'gauge' END); apex_json.write('values', (SELECT JSON_ARRAYAGG(value ORDER BY period) FROM PM_KPI_VALUES WHERE KPI_ID = kpi.ID)); apex_json.close_object; END LOOP; apex_json.close_array; END;
注意事项
- 性能优化:KPI数量较多时,建议实现懒加载(滚动到视图区域再初始化图表)
- 多语言支持:根据会话语言切换
NAME_EN/NAME_AR等字段 - 权限控制:通过页面授权或数据源过滤限制可查看的KPI范围
- 数据关联:确保KPI度量表(如
PM_KPI_VALUES)与PM_KPI.ID正确关联
内容的提问来源于stack exchange,提问作者Ataaacker
相关产品推荐
相关产品推荐

