图表元素上的dg-chart-listener改为继承<body>上的而非覆盖;看板监听器添加updateChartError函数,图表监听器添加updateError函数,用于自定义图表更新数据出错处理逻辑

This commit is contained in:
datagear 2021-06-30 10:31:10 +08:00
parent de5c883a18
commit cd381b28b0
7 changed files with 248 additions and 108 deletions

View File

@ -2,7 +2,8 @@
添加更多内置图表插件:嵌套饼图、盒须图、地图热力图、路径图;
数据管理高级查询功能、SQL数据集添加防注入支持
看板新增加载数据异常处理API
ok 看板新增加载数据异常处理API
ok 看板单个图表数据加载出错不应影响其他图表数据加载;
ok 仪表盘图表支持多指标;
ok 看板JS对象添加获取服务端当前日期时间的API
ok 升级ECharts版本4.9.0至5.1.2注意5.0.2版本的关系图graph在使用geo坐标系统时报错
@ -14,7 +15,6 @@
看板图表新增导出数据功能;
系统添加缓存支持;
共享看板支持设置密码;
看板单个图表数据加载出错不应影响其他图表数据加载;
看板模板管理功能和内置看板模板;
改进看板表单功能,支持不绘制表单项,而仅是绑定参数;
看板布局组件;

View File

@ -0,0 +1,90 @@
/*
* Copyright 2018 datagear.tech
*
* Licensed under the LGPLv3 license:
* http://www.gnu.org/licenses/lgpl-3.0.html
*/
package org.datagear.analysis.support;
import java.io.Serializable;
import org.datagear.analysis.ChartResultError;
/**
* 图表结果错误消息
*
* @author datagear@163.com
*
*/
public class ChartResultErrorMessage implements Serializable
{
private static final long serialVersionUID = 1L;
/** 错误类型 */
private String type = "";
/** 错误消息 */
private String message = "";
public ChartResultErrorMessage()
{
super();
}
public ChartResultErrorMessage(String type, String message)
{
super();
this.type = type;
this.message = message;
}
public ChartResultErrorMessage(ChartResultError error)
{
this(error, false);
}
public ChartResultErrorMessage(ChartResultError error, boolean rootCauseMessage)
{
Throwable throwable = error.getThrowable();
if (throwable != null)
{
this.type = throwable.getClass().getSimpleName();
if (rootCauseMessage)
{
Throwable cause = throwable;
while (cause.getCause() != null)
cause = cause.getCause();
this.message = cause.getMessage();
}
else
{
this.message = throwable.getMessage();
}
}
}
public String getType()
{
return type;
}
public void setType(String type)
{
this.type = type;
}
public String getMessage()
{
return message;
}
public void setMessage(String message)
{
this.message = message;
}
}

View File

@ -31,7 +31,13 @@ public class ErrorMessageDashboardResult extends DashboardResult
public ErrorMessageDashboardResult(DashboardResult result)
{
super.setChartResults(result.getChartResults());
setChartResultErrorMessages(toChartResultErrorMessages(result.getChartResultErrors()));
setChartResultErrorMessages(toChartResultErrorMessages(result.getChartResultErrors(), false));
}
public ErrorMessageDashboardResult(DashboardResult result, boolean rootCauseMessage)
{
super.setChartResults(result.getChartResults());
setChartResultErrorMessages(toChartResultErrorMessages(result.getChartResultErrors(), rootCauseMessage));
}
public Map<String, ChartResultErrorMessage> getChartResultErrorMessages()
@ -57,73 +63,20 @@ public class ErrorMessageDashboardResult extends DashboardResult
}
protected Map<String, ChartResultErrorMessage> toChartResultErrorMessages(
Map<String, ChartResultError> chartResultErrors)
Map<String, ChartResultError> chartResultErrors, boolean rootCauseMessage)
{
if (chartResultErrors == null)
return Collections.emptyMap();
Map<String, ChartResultErrorMessage> re = new HashMap<String, ErrorMessageDashboardResult.ChartResultErrorMessage>(
Map<String, ChartResultErrorMessage> re = new HashMap<String, ChartResultErrorMessage>(
chartResultErrors.size());
for (Map.Entry<String, ChartResultError> entry : chartResultErrors.entrySet())
{
ChartResultErrorMessage em = new ChartResultErrorMessage(entry.getValue());
ChartResultErrorMessage em = new ChartResultErrorMessage(entry.getValue(), rootCauseMessage);
re.put(entry.getKey(), em);
}
return re;
}
public static class ChartResultErrorMessage
{
/** 错误类型 */
private String type = "";
/** 错误消息 */
private String message = "";
public ChartResultErrorMessage()
{
super();
}
public ChartResultErrorMessage(String type, String message)
{
super();
this.type = type;
this.message = message;
}
public ChartResultErrorMessage(ChartResultError error)
{
super();
Throwable throwable = error.getThrowable();
if (throwable != null)
{
this.type = throwable.getClass().getSimpleName();
this.message = throwable.getMessage();
}
}
public String getType()
{
return type;
}
public void setType(String type)
{
this.type = type;
}
public String getMessage()
{
return message;
}
public void setMessage(String message)
{
this.message = message;
}
}
}

View File

@ -398,7 +398,7 @@ public class ChartController extends AbstractChartPluginAwareController implemen
WebContext webContext = createWebContext(request);
DashboardResult dashboardResult = getDashboardResult(request, response, model, webContext, form);
return new ErrorMessageDashboardResult(dashboardResult);
return new ErrorMessageDashboardResult(dashboardResult, true);
}
/**

View File

@ -1006,7 +1006,7 @@ public class DashboardController extends AbstractDataAnalysisController implemen
WebContext webContext = createWebContext(request);
DashboardResult dashboardResult = getDashboardResult(request, response, model, webContext, form);
return new ErrorMessageDashboardResult(dashboardResult);
return new ErrorMessageDashboardResult(dashboardResult, true);
}
/**

View File

@ -504,19 +504,88 @@
*/
chartBase._initListener = function()
{
var $element = this.elementJquery();
var globalListener = $(document.body).attr(elementAttrConst.LISTENER);
var localListener = this.elementJquery().attr(elementAttrConst.LISTENER);
var listenerStr = $element.attr(elementAttrConst.LISTENER);
if(!listenerStr)
listenerStr = $(document.body).attr(elementAttrConst.LISTENER);
if(listenerStr)
if(globalListener)
{
var listener = chartFactory.evalSilently(listenerStr);
if(!chartFactory._globalChartListener)
{
chartFactory._globalChartListener = chartFactory.evalSilently(globalListener);
}
if(listener)
this.listener(listener);
globalListener = chartFactory._globalChartListener;
}
if(localListener)
{
localListener = chartFactory.evalSilently(localListener);
}
var myListener = null;
if(!localListener && !globalListener)
{
myListener = null;
}
else if(!localListener)
{
myListener = globalListener;
}
else if(!globalListener)
{
myListener = localListener;
}
else
{
//实现局部图表监听器继承全局图表监听器功能
myListener =
{
//标识这是一个由元素图表监听器属性生成的内部代理图表监听器
_proxyChartListenerFromEleAttr: true,
_listeners: [localListener, globalListener],
render: function(chart)
{
var dl = this._findListenerOfFunc("render");
if(dl)
return dl.render(chart);
},
update: function(chart, results)
{
var dl = this._findListenerOfFunc("update");
if(dl)
return dl.update(chart, results);
},
onRender: function(chart)
{
var dl = this._findListenerOfFunc("onRender");
if(dl)
return dl.onRender(chart);
},
onUpdate: function(chart, results)
{
var dl = this._findListenerOfFunc("onUpdate");
if(dl)
return dl.onUpdate(chart, results);
},
_findListenerOfFunc: function(funcName)
{
for(var i=0; i<this._listeners.length; i++)
{
if(this._listeners[i] && this._listeners[i][funcName])
return this._listeners[i];
}
return null;
}
};
}
this.listener(myListener);
};
/**
@ -707,7 +776,7 @@
* //可选渲染图表前置回调函数返回false将阻止渲染图表
* onRender: function(chart){ ... },
* //可选更新图表数据前置回调函数返回false将阻止更新图表数据
* onUpdate: function(chart, results){ ... },
* onUpdate: function(chart, results){ ... }
* }
*
* @param listener 可选要设置的监听器对象没有则执行获取操作

View File

@ -30,6 +30,8 @@
*
* 此看板工厂支持为<body>元素图表元素添加elementAttrConst.UPDATE_GROUP属性用于设置图表更新ajax分组
*
* 此看板工厂扩展了图表监听器功能支持为图表监听器添加图表更新数据出错处理函数{ updateError: function(chart, error){ ... } }
*
* 此看板工厂支持将页面内添加了elementAttrConst.DASHBOARD_FORM属性的<form>元素构建为看板表单具体参考dashboardBase._initForms函数说明
*
*/
@ -660,11 +662,14 @@
var listener = $(document.body).attr(elementAttrConst.DASHBOARD_LISTENER);
if(listener)
{
listener = chartFactory.evalSilently(listener);
}
// < @deprecated 用于兼容1.5.0版本的dashboardRenderer设计未来版本会移除
else if(typeof(dashboardRenderer) != "undefined")
{
listener = dashboardRenderer.listener;
}
// > @deprecated 用于兼容1.5.0版本的dashboardRenderer设计未来版本会移除
if(listener)
@ -706,9 +711,27 @@
chartFactory.init(chart);
//如果图表没有定义监听器,则使用代理看板监听器
if(!chart.listener())
var chartListener = chart.listener();
//图表监听器不继承看板监听器功能,所有只有图表没有定义监听器时,才使用代理看板监听器
if(!chartListener)
{
chart.listener(this._getDelegateChartListener());
}
else
{
//由元素图表监听器属性生成的内部代理图表监听器应为其添加updateError处理函数
if(chartListener._proxyChartListenerFromEleAttr)
{
chartListener.updateError = function(chart, error)
{
var dl = this._findListenerOfFunc("updateError");
if(dl)
return dl.updateError(chart, error);
};
}
}
};
/**
@ -751,7 +774,9 @@
* //可选渲染图表前置回调函数返回false将阻止渲染图表
* onRenderChart: function(dashboard, chart){ ... },
* //可选更新图表数据前置回调函数返回false将阻止更新图表数据
* onUpdateChart: function(dashboard, chart, results){ ... }
* onUpdateChart: function(dashboard, chart, results){ ... },
* //可选,更新图表数据出错处理函数
* updateChartError: function(dashboard, chart, error){ ... }
* }
*
* @param listener 可选要设置的监听器对象没有则执行获取操作
@ -787,6 +812,11 @@
chartListener.onUpdate = function(chart, results){ return listener.onUpdateChart(dashboard, chart, results); };
else
chartListener.onUpdate = undefined;
if(listener && listener.updateChartError)
chartListener.updateError = function(chart, error){ return listener.updateChartError(dashboard, chart, error); };
else
chartListener.updateError = undefined;
};
/**
@ -1438,7 +1468,17 @@
if(!chart)
continue;
this._handleChartResultError(chart, chartResultErrorMessages[chartId]);
try
{
//设置为更新出错状态避免更新失败后会_doHandleCharts中会无限尝试更新
chart.status(chartStatusConst.UPDATE_ERROR);
this._handleChartResultError(chart, chartResultErrorMessages[chartId]);
}
catch(e)
{
chartFactory.logException(e);
}
}
};
@ -1450,19 +1490,18 @@
*/
dashboardBase._handleChartResultError = function(chart, chartResultErrorMessage)
{
//设置为更新出错状态避免更新失败后会_doHandleCharts中会无限尝试更新
chart.status(chartStatusConst.UPDATE_ERROR);
var chartListener = chart.listener();
var errorType = (chartResultErrorMessage ? chartResultErrorMessage.type : "Error");
var errorMessage = (chartResultErrorMessage ? chartResultErrorMessage.message : "Chart result error");
try
if(chartListener && chartListener.updateError)
{
chartFactory.logException(errorType + " : " + errorMessage);
chartListener.updateError(chart, chartResultErrorMessage);
}
catch(e)
else
{
chartFactory.logException(e);
var errorType = (chartResultErrorMessage ? chartResultErrorMessage.type : "Error");
var errorMessage = (chartResultErrorMessage ? chartResultErrorMessage.message : "Chart result error");
chartFactory.logException(errorType + " : " + errorMessage);
}
};
@ -1483,7 +1522,17 @@
if(!chart)
continue;
this._updateChart(chart, chartResults[chartId]);
try
{
this._updateChart(chart, chartResults[chartId]);
}
catch(e)
{
//设置为更新出错状态避免更新失败后会_doHandleCharts中会无限尝试更新
chart.status(chartStatusConst.UPDATE_ERROR);
chartFactory.logException(e);
}
}
};
@ -1497,28 +1546,7 @@
{
var dataSetResults = (chartResult ? chartResult.dataSetResults : []);
try
{
this._doUpdateChart(chart, dataSetResults);
}
catch(e)
{
//设置为更新出错状态避免更新失败后会_doHandleCharts中会无限尝试更新
chart.status(chartStatusConst.UPDATE_ERROR);
chartFactory.logException(e);
}
};
/**
* 更新指定图表
*
* @param chart 图表对象
* @param results 图表数据集结果数组
*/
dashboardBase._doUpdateChart = function(chart, results)
{
return chart.update(results);
chart.update(dataSetResults);
};
dashboardBase._setUpdateTime = function(chart, time)