forked from p85126437/datagear
[analysis]添加HtmlTplDashboardWidgetHtmlRenderer,用于支持使用原生HTML渲染看板
This commit is contained in:
parent
7895ea3a43
commit
295421ae12
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2018 datagear.tech. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package org.datagear.analysis.support.html;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* HTML看板导入项。
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
*/
|
||||
public class HtmlDashboardImport implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 名称 */
|
||||
private String name;
|
||||
|
||||
/** 内容 */
|
||||
private String content;
|
||||
|
||||
public HtmlDashboardImport()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public HtmlDashboardImport(String name, String content)
|
||||
{
|
||||
super();
|
||||
this.name = name;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getContent()
|
||||
{
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content)
|
||||
{
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getSimpleName() + " [name=" + name + ", content=" + content + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,681 @@
|
|||
/*
|
||||
* Copyright (c) 2018 datagear.tech. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package org.datagear.analysis.support.html;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.datagear.analysis.ChartTheme;
|
||||
import org.datagear.analysis.DashboardTheme;
|
||||
import org.datagear.analysis.RenderContext;
|
||||
import org.datagear.analysis.RenderException;
|
||||
import org.datagear.analysis.Theme;
|
||||
import org.datagear.analysis.support.ChartWidgetSource;
|
||||
import org.datagear.analysis.support.DashboardWidgetResManager;
|
||||
import org.datagear.util.StringUtil;
|
||||
|
||||
import freemarker.core.Environment;
|
||||
import freemarker.ext.util.WrapperTemplateModel;
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateDirectiveBody;
|
||||
import freemarker.template.TemplateDirectiveModel;
|
||||
import freemarker.template.TemplateException;
|
||||
import freemarker.template.TemplateExceptionHandler;
|
||||
import freemarker.template.TemplateHashModel;
|
||||
import freemarker.template.TemplateModel;
|
||||
import freemarker.template.TemplateModelException;
|
||||
import freemarker.template.TemplateScalarModel;
|
||||
|
||||
/**
|
||||
* 使用Freemarker作为模板的{@linkplain HtmlTplDashboardWidget}渲染器。
|
||||
* <p>
|
||||
* 此类可渲染由{@linkplain DashboardWidgetResManager}管理模板的{@linkplain HtmlTplDashboardWidget},
|
||||
* 其中{@linkplain HtmlTplDashboardWidget#getTemplate()}应该是可以通过{@linkplain DashboardWidgetResManager#getFile(String, String)}找到的模板文件名。
|
||||
* </p>
|
||||
* <p>
|
||||
* 此类需要手动调用{@linkplain #init()}方法进行初始化。
|
||||
* </p>
|
||||
* <p>
|
||||
* 支持的模板格式如下:
|
||||
* </p>
|
||||
* <code>
|
||||
* <pre>
|
||||
* ...
|
||||
* <@import />
|
||||
* ...
|
||||
* <@theme />
|
||||
* ...
|
||||
* <@dashboard var="..." listener="...">
|
||||
* ...
|
||||
* <@chart widget="..." var="..." elementId="..." />
|
||||
* ...
|
||||
* <@chart widget="..." var="..." elementId="..." />
|
||||
* ...
|
||||
* </@dashboard>
|
||||
* </pre>
|
||||
* </code>
|
||||
* <p>
|
||||
* <@import />:引入内置JS、CSS等HTML资源。
|
||||
* </p>
|
||||
* <p>
|
||||
* <@theme />:引入内置CSS主题样式。
|
||||
* </p>
|
||||
* <p>
|
||||
* <@dashboard>:定义看板,“var”自定义看板JS变量名,可不填;“listener”自定义看板JS监听器,可不填。
|
||||
* </p>
|
||||
* <p>
|
||||
* <@chart
|
||||
* />:定义图表,“widget”为{@linkplain HtmlChartWidget#getId()},必填;“var”自定义图表JS变量名,可不填;“elementId”自定义图表HTML元素ID,可不填。
|
||||
* </p>
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public class HtmlTplDashboardWidgetFmkRenderer<T extends HtmlRenderContext> extends HtmlTplDashboardWidgetRenderer<T>
|
||||
{
|
||||
public static final String DIRECTIVE_IMPORT = "import";
|
||||
|
||||
public static final String DIRECTIVE_THEME = "theme";
|
||||
|
||||
public static final String DIRECTIVE_DASHBOARD = "dashboard";
|
||||
|
||||
public static final String DIRECTIVE_CHART = "chart";
|
||||
|
||||
public static final String DASHBOARD_ELEMENT_STYLE_NAME = "dashboard";
|
||||
|
||||
public static final String CHART_ELEMENT_WRAPPER_STYLE_NAME = "chart-wrapper";
|
||||
|
||||
private boolean ignoreDashboardStyleBorderWidth = true;
|
||||
|
||||
private Configuration _configuration;
|
||||
|
||||
public HtmlTplDashboardWidgetFmkRenderer()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public HtmlTplDashboardWidgetFmkRenderer(DashboardWidgetResManager dashboardWidgetResManager,
|
||||
ChartWidgetSource chartWidgetSource)
|
||||
{
|
||||
super(dashboardWidgetResManager, chartWidgetSource);
|
||||
}
|
||||
|
||||
public boolean isIgnoreDashboardStyleBorderWidth()
|
||||
{
|
||||
return ignoreDashboardStyleBorderWidth;
|
||||
}
|
||||
|
||||
public void setIgnoreDashboardStyleBorderWidth(boolean ignoreDashboardStyleBorderWidth)
|
||||
{
|
||||
this.ignoreDashboardStyleBorderWidth = ignoreDashboardStyleBorderWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化。
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void init() throws IOException
|
||||
{
|
||||
Configuration cfg = new Configuration(Configuration.VERSION_2_3_28);
|
||||
cfg.setDirectoryForTemplateLoading(getDashboardWidgetResManager().getRootDirectory());
|
||||
cfg.setDefaultEncoding(getTemplateEncoding());
|
||||
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
|
||||
cfg.setLogTemplateExceptions(false);
|
||||
cfg.setWrapUncheckedExceptions(true);
|
||||
|
||||
cfg.setSharedVariable(DIRECTIVE_IMPORT, new ImportTemplateDirectiveModel());
|
||||
cfg.setSharedVariable(DIRECTIVE_THEME, new ThemeTemplateDirectiveModel());
|
||||
cfg.setSharedVariable(DIRECTIVE_DASHBOARD, new DashboardTemplateDirectiveModel());
|
||||
cfg.setSharedVariable(DIRECTIVE_CHART, new ChartTemplateDirectiveModel());
|
||||
|
||||
setConfiguration(cfg);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderHtmlDashboard(T renderContext, HtmlDashboard dashboard) throws Exception
|
||||
{
|
||||
HtmlDashboardRenderDataModel dataModel = new HtmlDashboardRenderDataModel(dashboard,
|
||||
renderContext.getContextPath());
|
||||
|
||||
Template template = getTemplate((HtmlTplDashboardWidget<?>) dashboard.getWidget());
|
||||
|
||||
try
|
||||
{
|
||||
template.process(buildHtmlDashboardRenderDataModel(dataModel), renderContext.getWriter());
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
throw new RenderException(t);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取{@linkplain HtmlTplDashboardWidget#getId()}的指定模板对象。
|
||||
*
|
||||
* @param dashboardWidget
|
||||
* @return
|
||||
* @throws RenderException
|
||||
*/
|
||||
protected Template getTemplate(HtmlTplDashboardWidget<?> dashboardWidget) throws RenderException
|
||||
{
|
||||
String path = getDashboardWidgetResManager().getRelativePath(dashboardWidget.getId(),
|
||||
dashboardWidget.getTemplate());
|
||||
|
||||
try
|
||||
{
|
||||
return getConfiguration().getTemplate(path);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
throw new RenderException(t);
|
||||
}
|
||||
}
|
||||
|
||||
protected Configuration getConfiguration()
|
||||
{
|
||||
return _configuration;
|
||||
}
|
||||
|
||||
protected void setConfiguration(Configuration _configuration)
|
||||
{
|
||||
this._configuration = _configuration;
|
||||
}
|
||||
|
||||
protected Object buildHtmlDashboardRenderDataModel(HtmlDashboardRenderDataModel dataModel)
|
||||
{
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
|
||||
map.put(KEY_HTML_DASHBOARD_RENDER_DATA_MODEL, dataModel);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
protected HtmlDashboardRenderDataModel getHtmlDashboardRenderDataModel(Environment env)
|
||||
throws TemplateModelException
|
||||
{
|
||||
TemplateHashModel templateHashModel = env.getDataModel();
|
||||
HtmlDashboardRenderDataModel dataModel = (HtmlDashboardRenderDataModel) templateHashModel
|
||||
.get(KEY_HTML_DASHBOARD_RENDER_DATA_MODEL);
|
||||
|
||||
return dataModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML看板渲染数据模型。
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
*/
|
||||
protected static class HtmlDashboardRenderDataModel implements WrapperTemplateModel
|
||||
{
|
||||
private HtmlDashboard htmlDashboard;
|
||||
|
||||
private String contextPath = "";
|
||||
|
||||
public HtmlDashboardRenderDataModel()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public HtmlDashboardRenderDataModel(HtmlDashboard htmlDashboard, String contextPath)
|
||||
{
|
||||
super();
|
||||
this.htmlDashboard = htmlDashboard;
|
||||
this.contextPath = contextPath;
|
||||
}
|
||||
|
||||
public HtmlDashboard getHtmlDashboard()
|
||||
{
|
||||
return htmlDashboard;
|
||||
}
|
||||
|
||||
public void setHtmlDashboard(HtmlDashboard htmlDashboard)
|
||||
{
|
||||
this.htmlDashboard = htmlDashboard;
|
||||
}
|
||||
|
||||
public String getContextPath()
|
||||
{
|
||||
return contextPath;
|
||||
}
|
||||
|
||||
public void setContextPath(String contextPath)
|
||||
{
|
||||
this.contextPath = contextPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getWrappedObject()
|
||||
{
|
||||
return this.htmlDashboard;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract class AbstractTemplateDirectiveModel implements TemplateDirectiveModel
|
||||
{
|
||||
public AbstractTemplateDirectiveModel()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字符串参数值。
|
||||
*
|
||||
* @param params
|
||||
* @param key
|
||||
* @return
|
||||
* @throws TemplateModelException
|
||||
*/
|
||||
protected String getStringParamValue(Map<?, ?> params, String key) throws TemplateModelException
|
||||
{
|
||||
Object value = params.get(key);
|
||||
|
||||
if (value == null)
|
||||
return null;
|
||||
else if (value instanceof String)
|
||||
return (String) value;
|
||||
else if (value instanceof TemplateScalarModel)
|
||||
return ((TemplateScalarModel) value).getAsString();
|
||||
else
|
||||
throw new TemplateModelException(
|
||||
"Can not get string from [" + value.getClass().getName() + "] instance");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* “@import”指令。
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
*/
|
||||
protected class ImportTemplateDirectiveModel extends AbstractTemplateDirectiveModel
|
||||
{
|
||||
public ImportTemplateDirectiveModel()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
|
||||
throws TemplateException, IOException
|
||||
{
|
||||
HtmlDashboardRenderDataModel dataModel = getHtmlDashboardRenderDataModel(env);
|
||||
HtmlDashboard dashboard = dataModel.getHtmlDashboard();
|
||||
HtmlRenderContext renderContext = dashboard.getRenderContext();
|
||||
|
||||
Writer out = env.getOut();
|
||||
|
||||
out.write("<meta charset=\"" + getWriterEncoding() + "\">");
|
||||
|
||||
writeDashboardImport(renderContext, dashboard, "");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* “@theme”指令。
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
*/
|
||||
protected class ThemeTemplateDirectiveModel extends AbstractTemplateDirectiveModel
|
||||
{
|
||||
public ThemeTemplateDirectiveModel()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
|
||||
throws TemplateException, IOException
|
||||
{
|
||||
HtmlDashboardRenderDataModel dataModel = getHtmlDashboardRenderDataModel(env);
|
||||
HtmlRenderContext renderContext = dataModel.getHtmlDashboard().getRenderContext();
|
||||
|
||||
Writer out = env.getOut();
|
||||
|
||||
DashboardTheme dashboardTheme = getDashboardTheme(renderContext);
|
||||
writeDashboardTheme(out, dashboardTheme);
|
||||
}
|
||||
|
||||
protected DashboardTheme getDashboardTheme(RenderContext renderContext)
|
||||
{
|
||||
DashboardTheme dashboardTheme = HtmlRenderAttributes.getDashboardTheme(renderContext);
|
||||
return dashboardTheme;
|
||||
}
|
||||
|
||||
protected void writeDashboardTheme(Writer out, DashboardTheme dashboardTheme) throws IOException
|
||||
{
|
||||
ChartTheme chartTheme = (dashboardTheme == null ? null : dashboardTheme.getChartTheme());
|
||||
|
||||
out.write("<style type=\"text/css\">");
|
||||
writeNewLine(out);
|
||||
out.write("body{");
|
||||
writeNewLine(out);
|
||||
out.write(" padding: 0px 0px;");
|
||||
writeNewLine(out);
|
||||
out.write(" margin: 0px 0px;");
|
||||
writeNewLine(out);
|
||||
if (dashboardTheme != null)
|
||||
{
|
||||
out.write(" background-color: " + dashboardTheme.getBackgroundColor() + ";");
|
||||
writeNewLine(out);
|
||||
out.write(" color: " + dashboardTheme.getForegroundColor() + ";");
|
||||
writeNewLine(out);
|
||||
}
|
||||
out.write("}");
|
||||
writeNewLine(out);
|
||||
out.write("." + DASHBOARD_ELEMENT_STYLE_NAME + "{");
|
||||
writeNewLine(out);
|
||||
writeThemeCssAttrs(out, dashboardTheme);
|
||||
writeBorderBoxCssAttrs(out);
|
||||
if (isIgnoreDashboardStyleBorderWidth())
|
||||
{
|
||||
out.write(" border-width: 0px;");
|
||||
writeNewLine(out);
|
||||
}
|
||||
out.write("}");
|
||||
writeNewLine(out);
|
||||
|
||||
out.write("." + CHART_ELEMENT_WRAPPER_STYLE_NAME + "{");
|
||||
writeNewLine(out);
|
||||
out.write(" position: relative;");
|
||||
writeNewLine(out);
|
||||
writeThemeCssAttrs(out, chartTheme);
|
||||
writeBorderBoxCssAttrs(out);
|
||||
out.write("}");
|
||||
writeNewLine(out);
|
||||
|
||||
out.write("." + HtmlChartPlugin.BUILTIN_CHART_ELEMENT_STYLE_NAME + "{");
|
||||
writeNewLine(out);
|
||||
writeFillParentCssAttrs(out);
|
||||
writeBorderBoxCssAttrs(out);
|
||||
out.write("}");
|
||||
writeNewLine(out);
|
||||
|
||||
out.write("</style>");
|
||||
writeNewLine(out);
|
||||
}
|
||||
|
||||
protected void writeThemeCssAttrs(Writer out, Theme theme) throws IOException
|
||||
{
|
||||
if (theme != null)
|
||||
{
|
||||
String borderWidth = theme.getBorderWidth();
|
||||
if (borderWidth == null)
|
||||
borderWidth = "0";
|
||||
|
||||
out.write(" color: " + theme.getForegroundColor() + ";");
|
||||
writeNewLine(out);
|
||||
out.write(" background-color: " + theme.getBackgroundColor() + ";");
|
||||
writeNewLine(out);
|
||||
out.write(" border-color: " + theme.getBorderColor() + ";");
|
||||
writeNewLine(out);
|
||||
out.write(" border-width: " + theme.getBorderWidth() + ";");
|
||||
writeNewLine(out);
|
||||
out.write(" border-style: solid;");
|
||||
writeNewLine(out);
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeFillParentCssAttrs(Writer out) throws IOException
|
||||
{
|
||||
out.write(" position: absolute;");
|
||||
writeNewLine(out);
|
||||
out.write(" top: 0px;");
|
||||
writeNewLine(out);
|
||||
out.write(" bottom: 0px;");
|
||||
writeNewLine(out);
|
||||
out.write(" left: 0px;");
|
||||
writeNewLine(out);
|
||||
out.write(" right: 0px;");
|
||||
writeNewLine(out);
|
||||
}
|
||||
|
||||
protected void writeBorderBoxCssAttrs(Writer out) throws IOException
|
||||
{
|
||||
out.write(" box-sizing: border-box;");
|
||||
writeNewLine(out);
|
||||
out.write(" -moz-box-sizing: border-box;");
|
||||
writeNewLine(out);
|
||||
out.write(" -webkit-box-sizing: border-box;");
|
||||
writeNewLine(out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* “@dashboard”指令。
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
*/
|
||||
protected class DashboardTemplateDirectiveModel extends AbstractTemplateDirectiveModel
|
||||
{
|
||||
public DashboardTemplateDirectiveModel()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
|
||||
throws TemplateException, IOException
|
||||
{
|
||||
String varName = getStringParamValue(params, "var");
|
||||
String listener = getStringParamValue(params, "listener");
|
||||
boolean hasListener = !StringUtil.isEmpty(listener);
|
||||
|
||||
HtmlDashboardRenderDataModel dataModel = getHtmlDashboardRenderDataModel(env);
|
||||
HtmlDashboard dashboard = dataModel.getHtmlDashboard();
|
||||
HtmlRenderContext renderContext = dashboard.getRenderContext();
|
||||
int nextSequence = -1;
|
||||
|
||||
if (StringUtil.isEmpty(varName))
|
||||
{
|
||||
nextSequence = HtmlRenderAttributes.getNextSequenceIfNot(renderContext, nextSequence);
|
||||
varName = HtmlRenderAttributes.generateDashboardVarName(nextSequence);
|
||||
}
|
||||
|
||||
dashboard.setVarName(varName);
|
||||
|
||||
Writer out = env.getOut();
|
||||
|
||||
writeScriptStartTag(out);
|
||||
writeNewLine(out);
|
||||
|
||||
out.write("var ");
|
||||
out.write(varName);
|
||||
out.write("=");
|
||||
writeNewLine(out);
|
||||
writeHtmlDashboardScriptObject(out, dashboard, true);
|
||||
out.write(";");
|
||||
writeNewLine(out);
|
||||
|
||||
writeScriptEndTag(out);
|
||||
writeNewLine(out);
|
||||
|
||||
HtmlRenderAttributes.setChartRenderContextVarName(renderContext, varName + ".renderContext");
|
||||
|
||||
if (body != null)
|
||||
body.render(out);
|
||||
|
||||
writeScriptStartTag(out);
|
||||
writeNewLine(out);
|
||||
|
||||
String tmpRenderContextVar = HtmlRenderAttributes.generateRenderContextVarName(nextSequence);
|
||||
|
||||
// 移除内部设置的属性
|
||||
HtmlRenderAttributes.removeChartRenderContextVarName(renderContext);
|
||||
HtmlRenderAttributes.removeChartNotRenderScriptTag(renderContext);
|
||||
HtmlRenderAttributes.removeChartScriptNotInvokeRender(renderContext);
|
||||
HtmlRenderAttributes.removeChartVarName(renderContext);
|
||||
HtmlRenderAttributes.removeChartElementId(renderContext);
|
||||
|
||||
renderContext.removeAttribute(RENDER_ATTR_NAME_FOR_NOT_FOUND_SCRIPT);
|
||||
|
||||
out.write("var ");
|
||||
out.write(tmpRenderContextVar);
|
||||
out.write("=");
|
||||
writeNewLine(out);
|
||||
writeRenderContextScriptObject(out, renderContext);
|
||||
out.write(";");
|
||||
writeNewLine(out);
|
||||
out.write(varName + ".renderContext.attributes = " + tmpRenderContextVar + ".attributes;");
|
||||
writeNewLine(out);
|
||||
|
||||
List<? extends HtmlChart> charts = dashboard.getCharts();
|
||||
if (charts != null)
|
||||
{
|
||||
for (HtmlChart chart : charts)
|
||||
{
|
||||
out.write(varName + ".charts.push(" + chart.getVarName() + ");");
|
||||
writeNewLine(out);
|
||||
}
|
||||
}
|
||||
|
||||
out.write(varName + ".render = function(){");
|
||||
writeNewLine(out);
|
||||
out.write(" for(var i=0; i<this.charts.length; i++){ this.charts[i].render(); }");
|
||||
writeNewLine(out);
|
||||
out.write("};");
|
||||
writeNewLine(out);
|
||||
|
||||
out.write(varName + ".update = function(){");
|
||||
writeNewLine(out);
|
||||
out.write(" for(var i=0; i<this.charts.length; i++){ this.charts[i].update(); }");
|
||||
writeNewLine(out);
|
||||
out.write("};");
|
||||
writeNewLine(out);
|
||||
|
||||
if (hasListener)
|
||||
{
|
||||
out.write(varName + ".listener = window[\"" + listener + "\"];");
|
||||
writeNewLine(out);
|
||||
}
|
||||
|
||||
out.write("window.onload = function(){");
|
||||
writeNewLine(out);
|
||||
|
||||
out.write("var doRender = true;");
|
||||
writeNewLine(out);
|
||||
|
||||
if (hasListener)
|
||||
{
|
||||
out.write("if(" + varName + ".listener && " + varName + ".listener.onRender)");
|
||||
writeNewLine(out);
|
||||
out.write(" doRender=" + varName + ".listener.onRender(" + varName + "); ");
|
||||
writeNewLine(out);
|
||||
}
|
||||
|
||||
out.write("if(doRender != false)");
|
||||
writeNewLine(out);
|
||||
out.write(" " + varName + ".render();");
|
||||
writeNewLine(out);
|
||||
|
||||
out.write("var doUpdate = true;");
|
||||
writeNewLine(out);
|
||||
|
||||
if (hasListener)
|
||||
{
|
||||
out.write("if(" + varName + ".listener && " + varName + ".listener.onUpdate)");
|
||||
writeNewLine(out);
|
||||
out.write(" doUpdate=" + varName + ".listener.onUpdate(" + varName + "); ");
|
||||
writeNewLine(out);
|
||||
}
|
||||
|
||||
out.write("if(doUpdate != false)");
|
||||
writeNewLine(out);
|
||||
out.write(" " + varName + ".update();");
|
||||
writeNewLine(out);
|
||||
|
||||
out.write("};");
|
||||
writeNewLine(out);
|
||||
|
||||
writeScriptEndTag(out);
|
||||
writeNewLine(out);
|
||||
}
|
||||
|
||||
protected void writeHtmlDashboardScriptObject(Writer out, HtmlDashboard dashboard, boolean renderContextEmpty)
|
||||
throws IOException
|
||||
{
|
||||
getHtmlDashboardScriptObjectWriter().write(out, dashboard, renderContextEmpty);
|
||||
}
|
||||
|
||||
protected void writeRenderContextScriptObject(Writer out, RenderContext renderContext) throws IOException
|
||||
{
|
||||
getHtmlDashboardScriptObjectWriter().writeRenderContext(out, renderContext, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* “@chart”指令。
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
*/
|
||||
protected class ChartTemplateDirectiveModel extends AbstractTemplateDirectiveModel
|
||||
{
|
||||
public ChartTemplateDirectiveModel()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Override
|
||||
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
|
||||
throws TemplateException, IOException
|
||||
{
|
||||
String widget = getStringParamValue(params, "widget");
|
||||
String var = getStringParamValue(params, "var");
|
||||
String elementId = getStringParamValue(params, "elementId");
|
||||
|
||||
HtmlDashboardRenderDataModel dataModel = getHtmlDashboardRenderDataModel(env);
|
||||
HtmlDashboard htmlDashboard = dataModel.getHtmlDashboard();
|
||||
HtmlRenderContext renderContext = htmlDashboard.getRenderContext();
|
||||
int nextSequence = -1;
|
||||
|
||||
HtmlChartWidget<HtmlRenderContext> chartWidget = getHtmlChartWidgetForRender(renderContext, widget);
|
||||
|
||||
if (StringUtil.isEmpty(var))
|
||||
{
|
||||
nextSequence = HtmlRenderAttributes.getNextSequenceIfNot(renderContext, nextSequence);
|
||||
var = HtmlRenderAttributes.generateChartVarName(nextSequence);
|
||||
}
|
||||
|
||||
if (StringUtil.isEmpty(elementId))
|
||||
{
|
||||
nextSequence = HtmlRenderAttributes.getNextSequenceIfNot(renderContext, nextSequence);
|
||||
elementId = HtmlRenderAttributes.generateChartElementId(nextSequence);
|
||||
}
|
||||
|
||||
HtmlRenderAttributes.setChartNotRenderScriptTag(renderContext, false);
|
||||
HtmlRenderAttributes.setChartScriptNotInvokeRender(renderContext, true);
|
||||
HtmlRenderAttributes.setChartVarName(renderContext, var);
|
||||
HtmlRenderAttributes.setChartElementId(renderContext, elementId);
|
||||
|
||||
HtmlChart chart = chartWidget.render(renderContext);
|
||||
|
||||
List<HtmlChart> charts = (List<HtmlChart>) htmlDashboard.getCharts();
|
||||
if (charts == null)
|
||||
{
|
||||
charts = new ArrayList<HtmlChart>();
|
||||
htmlDashboard.setCharts(charts);
|
||||
}
|
||||
|
||||
charts.add(chart);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -12,9 +12,7 @@ import java.io.IOException;
|
|||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.datagear.analysis.Chart;
|
||||
import org.datagear.analysis.ChartTheme;
|
||||
|
@ -24,90 +22,26 @@ import org.datagear.analysis.DashboardThemeSource;
|
|||
import org.datagear.analysis.RenderContext;
|
||||
import org.datagear.analysis.RenderException;
|
||||
import org.datagear.analysis.RenderStyle;
|
||||
import org.datagear.analysis.Theme;
|
||||
import org.datagear.analysis.support.ChartWidget;
|
||||
import org.datagear.analysis.support.ChartWidgetSource;
|
||||
import org.datagear.analysis.support.DashboardWidgetResManager;
|
||||
import org.datagear.analysis.support.SimpleDashboardThemeSource;
|
||||
import org.datagear.analysis.support.html.HtmlTplDashboardWidgetFmkRenderer.HtmlDashboardRenderDataModel;
|
||||
import org.datagear.util.Global;
|
||||
import org.datagear.util.IDUtil;
|
||||
import org.datagear.util.IOUtil;
|
||||
import org.datagear.util.StringUtil;
|
||||
|
||||
import freemarker.core.Environment;
|
||||
import freemarker.ext.util.WrapperTemplateModel;
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateDirectiveBody;
|
||||
import freemarker.template.TemplateDirectiveModel;
|
||||
import freemarker.template.TemplateException;
|
||||
import freemarker.template.TemplateExceptionHandler;
|
||||
import freemarker.template.TemplateHashModel;
|
||||
import freemarker.template.TemplateModel;
|
||||
import freemarker.template.TemplateModelException;
|
||||
import freemarker.template.TemplateScalarModel;
|
||||
|
||||
/**
|
||||
* {@linkplain HtmlTplDashboardWidget}渲染器。
|
||||
* <p>
|
||||
* 此类可渲染由{@linkplain DashboardWidgetResManager}管理模板的{@linkplain HtmlTplDashboardWidget},
|
||||
* 其中{@linkplain HtmlTplDashboardWidget#getTemplate()}应该是可以通过{@linkplain DashboardWidgetResManager#getFile(String, String)}找到的模板文件名。
|
||||
* </p>
|
||||
* <p>
|
||||
* 此类需要手动调用{@linkplain #init()}方法进行初始化。
|
||||
* </p>
|
||||
* <p>
|
||||
* 支持的模板格式如下:
|
||||
* </p>
|
||||
* <code>
|
||||
* <pre>
|
||||
* ...
|
||||
* <@import />
|
||||
* ...
|
||||
* <@theme />
|
||||
* ...
|
||||
* <@dashboard var="..." listener="...">
|
||||
* ...
|
||||
* <@chart widget="..." var="..." elementId="..." />
|
||||
* ...
|
||||
* <@chart widget="..." var="..." elementId="..." />
|
||||
* ...
|
||||
* </@dashboard>
|
||||
* </pre>
|
||||
* </code>
|
||||
* <p>
|
||||
* <@import />:引入内置JS、CSS等HTML资源。
|
||||
* </p>
|
||||
* <p>
|
||||
* <@theme />:引入内置CSS主题样式。
|
||||
* </p>
|
||||
* <p>
|
||||
* <@dashboard>:定义看板,“var”自定义看板JS变量名,可不填;“listener”自定义看板JS监听器,可不填。
|
||||
* </p>
|
||||
* <p>
|
||||
* <@chart
|
||||
* />:定义图表,“widget”为{@linkplain HtmlChartWidget#getId()},必填;“var”自定义图表JS变量名,可不填;“elementId”自定义图表HTML元素ID,可不填。
|
||||
* </p>
|
||||
* 抽象{@linkplain HtmlTplDashboardWidget}渲染器。
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
|
||||
public abstract class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
|
||||
{
|
||||
public static final String DIRECTIVE_IMPORT = "import";
|
||||
|
||||
public static final String DIRECTIVE_THEME = "theme";
|
||||
|
||||
public static final String DIRECTIVE_DASHBOARD = "dashboard";
|
||||
|
||||
public static final String DIRECTIVE_CHART = "chart";
|
||||
|
||||
public static final String DASHBOARD_ELEMENT_STYLE_NAME = "dashboard";
|
||||
|
||||
public static final String CHART_ELEMENT_WRAPPER_STYLE_NAME = "chart-wrapper";
|
||||
|
||||
public static final String DEFAULT_IMPORT_CONTEXT_PATH_PLACE_HOLDER = "$CONTEXTPATH";
|
||||
public static final String DEFAULT_CONTEXT_PATH_PLACE_HOLDER = "$CONTEXTPATH";
|
||||
|
||||
protected static final String KEY_HTML_DASHBOARD_RENDER_DATA_MODEL = HtmlDashboardRenderDataModel.class
|
||||
.getSimpleName();
|
||||
|
@ -115,11 +49,11 @@ public class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
|
|||
protected static final String RENDER_ATTR_NAME_FOR_NOT_FOUND_SCRIPT = StringUtil
|
||||
.firstLowerCase(Global.PRODUCT_NAME_EN) + "RenderValueForNotFound";
|
||||
|
||||
/** "@import"指令的输出内容 */
|
||||
private String importContent;
|
||||
/** 内置导入内容 */
|
||||
private List<HtmlDashboardImport> htmlDashboardImports;
|
||||
|
||||
/** "@import"指令的输出内容需要替换的上下文路径占位符 */
|
||||
private String importContentContextPathPlaceholder = DEFAULT_IMPORT_CONTEXT_PATH_PLACE_HOLDER;
|
||||
/** 上下文路径占位符 */
|
||||
private String contextPathPlaceholder = DEFAULT_CONTEXT_PATH_PLACE_HOLDER;
|
||||
|
||||
private DashboardWidgetResManager dashboardWidgetResManager;
|
||||
|
||||
|
@ -142,42 +76,37 @@ public class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
|
|||
/** 换行符 */
|
||||
private String newLine = "\r\n";
|
||||
|
||||
private boolean ignoreDashboardStyleBorderWidth = true;
|
||||
|
||||
private Configuration _configuration;
|
||||
|
||||
public HtmlTplDashboardWidgetRenderer()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public HtmlTplDashboardWidgetRenderer(String importContent, DashboardWidgetResManager dashboardWidgetResManager,
|
||||
public HtmlTplDashboardWidgetRenderer(DashboardWidgetResManager dashboardWidgetResManager,
|
||||
ChartWidgetSource chartWidgetSource)
|
||||
{
|
||||
super();
|
||||
this.importContent = importContent;
|
||||
this.dashboardWidgetResManager = dashboardWidgetResManager;
|
||||
this.chartWidgetSource = chartWidgetSource;
|
||||
}
|
||||
|
||||
public String getImportContent()
|
||||
public List<HtmlDashboardImport> getHtmlDashboardImports()
|
||||
{
|
||||
return importContent;
|
||||
return htmlDashboardImports;
|
||||
}
|
||||
|
||||
public void setImportContent(String importContent)
|
||||
public void setHtmlDashboardImports(List<HtmlDashboardImport> htmlDashboardImports)
|
||||
{
|
||||
this.importContent = importContent;
|
||||
this.htmlDashboardImports = htmlDashboardImports;
|
||||
}
|
||||
|
||||
public String getImportContentContextPathPlaceholder()
|
||||
public String getContextPathPlaceholder()
|
||||
{
|
||||
return importContentContextPathPlaceholder;
|
||||
return contextPathPlaceholder;
|
||||
}
|
||||
|
||||
public void setImportContentContextPathPlaceholder(String importContentContextPathPlaceholder)
|
||||
public void setContextPathPlaceholder(String contextPathPlaceholder)
|
||||
{
|
||||
this.importContentContextPathPlaceholder = importContentContextPathPlaceholder;
|
||||
this.contextPathPlaceholder = contextPathPlaceholder;
|
||||
}
|
||||
|
||||
public DashboardWidgetResManager getDashboardWidgetResManager()
|
||||
|
@ -260,38 +189,6 @@ public class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
|
|||
this.newLine = newLine;
|
||||
}
|
||||
|
||||
public boolean isIgnoreDashboardStyleBorderWidth()
|
||||
{
|
||||
return ignoreDashboardStyleBorderWidth;
|
||||
}
|
||||
|
||||
public void setIgnoreDashboardStyleBorderWidth(boolean ignoreDashboardStyleBorderWidth)
|
||||
{
|
||||
this.ignoreDashboardStyleBorderWidth = ignoreDashboardStyleBorderWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化。
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void init() throws IOException
|
||||
{
|
||||
Configuration cfg = new Configuration(Configuration.VERSION_2_3_28);
|
||||
cfg.setDirectoryForTemplateLoading(this.dashboardWidgetResManager.getRootDirectory());
|
||||
cfg.setDefaultEncoding(this.templateEncoding);
|
||||
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
|
||||
cfg.setLogTemplateExceptions(false);
|
||||
cfg.setWrapUncheckedExceptions(true);
|
||||
|
||||
cfg.setSharedVariable(DIRECTIVE_IMPORT, new ImportTemplateDirectiveModel());
|
||||
cfg.setSharedVariable(DIRECTIVE_THEME, new ThemeTemplateDirectiveModel());
|
||||
cfg.setSharedVariable(DIRECTIVE_DASHBOARD, new DashboardTemplateDirectiveModel());
|
||||
cfg.setSharedVariable(DIRECTIVE_CHART, new ChartTemplateDirectiveModel());
|
||||
|
||||
setConfiguration(cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染{@linkplain Dashboard}。
|
||||
*
|
||||
|
@ -304,21 +201,15 @@ public class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
|
|||
{
|
||||
inflateThemes(renderContext);
|
||||
|
||||
Template template = getTemplate(dashboardWidget);
|
||||
|
||||
HtmlDashboard dashboard = new HtmlDashboard();
|
||||
|
||||
dashboard.setId(IDUtil.uuid());
|
||||
dashboard.setWidget(dashboardWidget);
|
||||
dashboard.setRenderContext(renderContext);
|
||||
dashboard.setCharts(new ArrayList<Chart>());
|
||||
|
||||
HtmlDashboardRenderDataModel dataModel = new HtmlDashboardRenderDataModel(dashboard,
|
||||
renderContext.getContextPath());
|
||||
HtmlDashboard dashboard = createHtmlDashboard(renderContext, dashboardWidget);
|
||||
|
||||
try
|
||||
{
|
||||
template.process(buildHtmlDashboardRenderDataModel(dataModel), renderContext.getWriter());
|
||||
renderHtmlDashboard(renderContext, dashboard);
|
||||
}
|
||||
catch (RenderException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
|
@ -386,6 +277,52 @@ public class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建{@linkplain HtmlDashboard}。
|
||||
*
|
||||
* @param renderContext
|
||||
* @param dashboardWidget
|
||||
* @return
|
||||
*/
|
||||
protected HtmlDashboard createHtmlDashboard(T renderContext, HtmlTplDashboardWidget<T> dashboardWidget)
|
||||
{
|
||||
HtmlDashboard dashboard = new HtmlDashboard();
|
||||
|
||||
dashboard.setId(IDUtil.uuid());
|
||||
dashboard.setWidget(dashboardWidget);
|
||||
dashboard.setRenderContext(renderContext);
|
||||
dashboard.setCharts(new ArrayList<Chart>());
|
||||
|
||||
return dashboard;
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染{@linkplain Dashboard}。
|
||||
*
|
||||
* @param renderContext
|
||||
* @param dashboard
|
||||
* @throws Exception
|
||||
*/
|
||||
protected abstract void renderHtmlDashboard(T renderContext, HtmlDashboard dashboard) throws Exception;
|
||||
|
||||
/**
|
||||
* 获取{@linkplain HtmlTplDashboardWidget#getId()}的指定模板对象。
|
||||
*
|
||||
* @param dashboardWidget
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
protected Reader getTemplateReader(HtmlTplDashboardWidget<?> dashboardWidget) throws Exception
|
||||
{
|
||||
File templateFile = this.dashboardWidgetResManager.getFile(dashboardWidget.getId(),
|
||||
dashboardWidget.getTemplate());
|
||||
|
||||
if (!templateFile.exists())
|
||||
throw new RenderException("Dashboard template file not found");
|
||||
|
||||
return IOUtil.getReader(templateFile, getTemplateEncoding());
|
||||
}
|
||||
|
||||
protected void inflateThemes(HtmlRenderContext renderContext)
|
||||
{
|
||||
RenderStyle renderStyle = HtmlRenderAttributes.getRenderStyle(renderContext);
|
||||
|
@ -417,38 +354,6 @@ public class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取{@linkplain HtmlTplDashboardWidget#getId()}的指定模板对象。
|
||||
*
|
||||
* @param dashboardWidget
|
||||
* @return
|
||||
* @throws RenderException
|
||||
*/
|
||||
protected Template getTemplate(HtmlTplDashboardWidget<T> dashboardWidget) throws RenderException
|
||||
{
|
||||
String path = this.dashboardWidgetResManager.getRelativePath(dashboardWidget.getId(),
|
||||
dashboardWidget.getTemplate());
|
||||
|
||||
try
|
||||
{
|
||||
return getConfiguration().getTemplate(path);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
throw new RenderException(t);
|
||||
}
|
||||
}
|
||||
|
||||
protected Configuration getConfiguration()
|
||||
{
|
||||
return _configuration;
|
||||
}
|
||||
|
||||
protected void setConfiguration(Configuration _configuration)
|
||||
{
|
||||
this._configuration = _configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用于渲染指定ID图表的{@linkplain ChartWidget}。
|
||||
* <p>
|
||||
|
@ -474,23 +379,47 @@ public class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
|
|||
return (HtmlChartWidget<HtmlRenderContext>) chartWidget;
|
||||
}
|
||||
|
||||
protected Object buildHtmlDashboardRenderDataModel(HtmlDashboardRenderDataModel dataModel)
|
||||
protected void writeHtmlDashboardScriptObject(Writer out, HtmlDashboard dashboard, boolean renderContextEmpty)
|
||||
throws IOException
|
||||
{
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
|
||||
map.put(KEY_HTML_DASHBOARD_RENDER_DATA_MODEL, dataModel);
|
||||
|
||||
return map;
|
||||
getHtmlDashboardScriptObjectWriter().write(out, dashboard, renderContextEmpty);
|
||||
}
|
||||
|
||||
protected HtmlDashboardRenderDataModel getHtmlDashboardRenderDataModel(Environment env)
|
||||
throws TemplateModelException
|
||||
protected void writeRenderContextScriptObject(Writer out, RenderContext renderContext) throws IOException
|
||||
{
|
||||
TemplateHashModel templateHashModel = env.getDataModel();
|
||||
HtmlDashboardRenderDataModel dataModel = (HtmlDashboardRenderDataModel) templateHashModel
|
||||
.get(KEY_HTML_DASHBOARD_RENDER_DATA_MODEL);
|
||||
getHtmlDashboardScriptObjectWriter().writeRenderContext(out, renderContext, true);
|
||||
}
|
||||
|
||||
return dataModel;
|
||||
/**
|
||||
* 写看板导入项。
|
||||
*
|
||||
* @param renderContext
|
||||
* @param dashboard
|
||||
* @param importExclude
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void writeDashboardImport(HtmlRenderContext renderContext, HtmlDashboard dashboard, String importExclude)
|
||||
throws IOException
|
||||
{
|
||||
if (this.htmlDashboardImports == null || this.htmlDashboardImports.isEmpty())
|
||||
return;
|
||||
|
||||
Writer out = renderContext.getWriter();
|
||||
|
||||
List<String> excludes = StringUtil.splitWithTrim(importExclude, ",");
|
||||
|
||||
for (HtmlDashboardImport impt : this.htmlDashboardImports)
|
||||
{
|
||||
String name = impt.getName();
|
||||
|
||||
if (excludes.contains(name))
|
||||
continue;
|
||||
|
||||
String content = replaceContextPathPlaceholder(impt.getContent(), renderContext.getContextPath());
|
||||
|
||||
writeNewLine(out);
|
||||
out.write(content);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -508,556 +437,39 @@ public class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext>
|
|||
if (contextPath == null)
|
||||
contextPath = "";
|
||||
|
||||
return str.replace(getImportContentContextPathPlaceholder(), contextPath);
|
||||
return str.replace(getContextPathPlaceholder(), contextPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML看板渲染数据模型。
|
||||
* 写脚本开始标签。
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
* @param out
|
||||
* @throws IOException
|
||||
*/
|
||||
protected static class HtmlDashboardRenderDataModel implements WrapperTemplateModel
|
||||
protected void writeScriptStartTag(Writer out) throws IOException
|
||||
{
|
||||
private HtmlDashboard htmlDashboard;
|
||||
|
||||
private String contextPath = "";
|
||||
|
||||
public HtmlDashboardRenderDataModel()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public HtmlDashboardRenderDataModel(HtmlDashboard htmlDashboard, String contextPath)
|
||||
{
|
||||
super();
|
||||
this.htmlDashboard = htmlDashboard;
|
||||
this.contextPath = contextPath;
|
||||
}
|
||||
|
||||
public HtmlDashboard getHtmlDashboard()
|
||||
{
|
||||
return htmlDashboard;
|
||||
}
|
||||
|
||||
public void setHtmlDashboard(HtmlDashboard htmlDashboard)
|
||||
{
|
||||
this.htmlDashboard = htmlDashboard;
|
||||
}
|
||||
|
||||
public String getContextPath()
|
||||
{
|
||||
return contextPath;
|
||||
}
|
||||
|
||||
public void setContextPath(String contextPath)
|
||||
{
|
||||
this.contextPath = contextPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getWrappedObject()
|
||||
{
|
||||
return this.htmlDashboard;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract class AbstractTemplateDirectiveModel implements TemplateDirectiveModel
|
||||
{
|
||||
public AbstractTemplateDirectiveModel()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字符串参数值。
|
||||
*
|
||||
* @param params
|
||||
* @param key
|
||||
* @return
|
||||
* @throws TemplateModelException
|
||||
*/
|
||||
protected String getStringParamValue(Map<?, ?> params, String key) throws TemplateModelException
|
||||
{
|
||||
Object value = params.get(key);
|
||||
|
||||
if (value == null)
|
||||
return null;
|
||||
else if (value instanceof String)
|
||||
return (String) value;
|
||||
else if (value instanceof TemplateScalarModel)
|
||||
return ((TemplateScalarModel) value).getAsString();
|
||||
else
|
||||
throw new TemplateModelException(
|
||||
"Can not get string from [" + value.getClass().getName() + "] instance");
|
||||
}
|
||||
|
||||
/**
|
||||
* 写脚本开始标签。
|
||||
*
|
||||
* @param out
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void writeScriptStartTag(Writer out) throws IOException
|
||||
{
|
||||
out.write("<script type=\"text/javascript\">");
|
||||
}
|
||||
|
||||
/**
|
||||
* 写脚本结束标签。
|
||||
*
|
||||
* @param out
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void writeScriptEndTag(Writer out) throws IOException
|
||||
{
|
||||
out.write("</script>");
|
||||
}
|
||||
|
||||
/**
|
||||
* 写换行符。
|
||||
*
|
||||
* @param out
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void writeNewLine(Writer out) throws IOException
|
||||
{
|
||||
out.write(getNewLine());
|
||||
}
|
||||
out.write("<script type=\"text/javascript\">");
|
||||
}
|
||||
|
||||
/**
|
||||
* “@import”指令。
|
||||
* 写脚本结束标签。
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
* @param out
|
||||
* @throws IOException
|
||||
*/
|
||||
protected class ImportTemplateDirectiveModel extends AbstractTemplateDirectiveModel
|
||||
protected void writeScriptEndTag(Writer out) throws IOException
|
||||
{
|
||||
public ImportTemplateDirectiveModel()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
|
||||
throws TemplateException, IOException
|
||||
{
|
||||
HtmlDashboardRenderDataModel dataModel = getHtmlDashboardRenderDataModel(env);
|
||||
|
||||
Writer out = env.getOut();
|
||||
|
||||
String importContent = getImportContent();
|
||||
if (importContent == null)
|
||||
importContent = "";
|
||||
|
||||
out.write("<meta charset=\"" + getWriterEncoding() + "\">");
|
||||
|
||||
if (!StringUtil.isEmpty(importContent))
|
||||
{
|
||||
importContent = replaceContextPathPlaceholder(importContent, dataModel.getContextPath());
|
||||
writeNewLine(out);
|
||||
out.write(importContent);
|
||||
writeNewLine(out);
|
||||
}
|
||||
}
|
||||
out.write("</script>");
|
||||
}
|
||||
|
||||
/**
|
||||
* “@theme”指令。
|
||||
* 写换行符。
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
* @param out
|
||||
* @throws IOException
|
||||
*/
|
||||
protected class ThemeTemplateDirectiveModel extends AbstractTemplateDirectiveModel
|
||||
protected void writeNewLine(Writer out) throws IOException
|
||||
{
|
||||
public ThemeTemplateDirectiveModel()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
|
||||
throws TemplateException, IOException
|
||||
{
|
||||
HtmlDashboardRenderDataModel dataModel = getHtmlDashboardRenderDataModel(env);
|
||||
HtmlRenderContext renderContext = dataModel.getHtmlDashboard().getRenderContext();
|
||||
|
||||
Writer out = env.getOut();
|
||||
|
||||
DashboardTheme dashboardTheme = getDashboardTheme(renderContext);
|
||||
writeDashboardTheme(out, dashboardTheme);
|
||||
}
|
||||
|
||||
protected DashboardTheme getDashboardTheme(RenderContext renderContext)
|
||||
{
|
||||
DashboardTheme dashboardTheme = HtmlRenderAttributes.getDashboardTheme(renderContext);
|
||||
return dashboardTheme;
|
||||
}
|
||||
|
||||
protected void writeDashboardTheme(Writer out, DashboardTheme dashboardTheme) throws IOException
|
||||
{
|
||||
ChartTheme chartTheme = (dashboardTheme == null ? null : dashboardTheme.getChartTheme());
|
||||
|
||||
out.write("<style type=\"text/css\">");
|
||||
writeNewLine(out);
|
||||
out.write("body{");
|
||||
writeNewLine(out);
|
||||
out.write(" padding: 0px 0px;");
|
||||
writeNewLine(out);
|
||||
out.write(" margin: 0px 0px;");
|
||||
writeNewLine(out);
|
||||
if (dashboardTheme != null)
|
||||
{
|
||||
out.write(" background-color: " + dashboardTheme.getBackgroundColor() + ";");
|
||||
writeNewLine(out);
|
||||
out.write(" color: " + dashboardTheme.getForegroundColor() + ";");
|
||||
writeNewLine(out);
|
||||
}
|
||||
out.write("}");
|
||||
writeNewLine(out);
|
||||
out.write("." + DASHBOARD_ELEMENT_STYLE_NAME + "{");
|
||||
writeNewLine(out);
|
||||
writeThemeCssAttrs(out, dashboardTheme);
|
||||
writeBorderBoxCssAttrs(out);
|
||||
if (isIgnoreDashboardStyleBorderWidth())
|
||||
{
|
||||
out.write(" border-width: 0px;");
|
||||
writeNewLine(out);
|
||||
}
|
||||
out.write("}");
|
||||
writeNewLine(out);
|
||||
|
||||
out.write("." + CHART_ELEMENT_WRAPPER_STYLE_NAME + "{");
|
||||
writeNewLine(out);
|
||||
out.write(" position: relative;");
|
||||
writeNewLine(out);
|
||||
writeThemeCssAttrs(out, chartTheme);
|
||||
writeBorderBoxCssAttrs(out);
|
||||
out.write("}");
|
||||
writeNewLine(out);
|
||||
|
||||
out.write("." + HtmlChartPlugin.BUILTIN_CHART_ELEMENT_STYLE_NAME + "{");
|
||||
writeNewLine(out);
|
||||
writeFillParentCssAttrs(out);
|
||||
writeBorderBoxCssAttrs(out);
|
||||
out.write("}");
|
||||
writeNewLine(out);
|
||||
|
||||
out.write("</style>");
|
||||
writeNewLine(out);
|
||||
}
|
||||
|
||||
protected void writeThemeCssAttrs(Writer out, Theme theme) throws IOException
|
||||
{
|
||||
if (theme != null)
|
||||
{
|
||||
String borderWidth = theme.getBorderWidth();
|
||||
if (borderWidth == null)
|
||||
borderWidth = "0";
|
||||
|
||||
out.write(" color: " + theme.getForegroundColor() + ";");
|
||||
writeNewLine(out);
|
||||
out.write(" background-color: " + theme.getBackgroundColor() + ";");
|
||||
writeNewLine(out);
|
||||
out.write(" border-color: " + theme.getBorderColor() + ";");
|
||||
writeNewLine(out);
|
||||
out.write(" border-width: " + theme.getBorderWidth() + ";");
|
||||
writeNewLine(out);
|
||||
out.write(" border-style: solid;");
|
||||
writeNewLine(out);
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeFillParentCssAttrs(Writer out) throws IOException
|
||||
{
|
||||
out.write(" position: absolute;");
|
||||
writeNewLine(out);
|
||||
out.write(" top: 0px;");
|
||||
writeNewLine(out);
|
||||
out.write(" bottom: 0px;");
|
||||
writeNewLine(out);
|
||||
out.write(" left: 0px;");
|
||||
writeNewLine(out);
|
||||
out.write(" right: 0px;");
|
||||
writeNewLine(out);
|
||||
}
|
||||
|
||||
protected void writeBorderBoxCssAttrs(Writer out) throws IOException
|
||||
{
|
||||
out.write(" box-sizing: border-box;");
|
||||
writeNewLine(out);
|
||||
out.write(" -moz-box-sizing: border-box;");
|
||||
writeNewLine(out);
|
||||
out.write(" -webkit-box-sizing: border-box;");
|
||||
writeNewLine(out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* “@dashboard”指令。
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
*/
|
||||
protected class DashboardTemplateDirectiveModel extends AbstractTemplateDirectiveModel
|
||||
{
|
||||
public DashboardTemplateDirectiveModel()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
|
||||
throws TemplateException, IOException
|
||||
{
|
||||
String varName = getStringParamValue(params, "var");
|
||||
String listener = getStringParamValue(params, "listener");
|
||||
boolean hasListener = !StringUtil.isEmpty(listener);
|
||||
|
||||
HtmlDashboardRenderDataModel dataModel = getHtmlDashboardRenderDataModel(env);
|
||||
HtmlDashboard dashboard = dataModel.getHtmlDashboard();
|
||||
HtmlRenderContext renderContext = dashboard.getRenderContext();
|
||||
int nextSequence = -1;
|
||||
|
||||
if (StringUtil.isEmpty(varName))
|
||||
{
|
||||
nextSequence = HtmlRenderAttributes.getNextSequenceIfNot(renderContext, nextSequence);
|
||||
varName = HtmlRenderAttributes.generateDashboardVarName(nextSequence);
|
||||
}
|
||||
|
||||
dashboard.setVarName(varName);
|
||||
|
||||
Writer out = env.getOut();
|
||||
|
||||
writeScriptStartTag(out);
|
||||
writeNewLine(out);
|
||||
|
||||
out.write("var ");
|
||||
out.write(varName);
|
||||
out.write("=");
|
||||
writeNewLine(out);
|
||||
writeHtmlDashboardScriptObject(out, dashboard, true);
|
||||
out.write(";");
|
||||
writeNewLine(out);
|
||||
|
||||
writeScriptEndTag(out);
|
||||
writeNewLine(out);
|
||||
|
||||
HtmlRenderAttributes.setChartRenderContextVarName(renderContext, varName + ".renderContext");
|
||||
|
||||
if (body != null)
|
||||
body.render(out);
|
||||
|
||||
writeScriptStartTag(out);
|
||||
writeNewLine(out);
|
||||
|
||||
String tmpRenderContextVar = HtmlRenderAttributes.generateRenderContextVarName(nextSequence);
|
||||
|
||||
// 移除内部设置的属性
|
||||
HtmlRenderAttributes.removeChartRenderContextVarName(renderContext);
|
||||
HtmlRenderAttributes.removeChartNotRenderScriptTag(renderContext);
|
||||
HtmlRenderAttributes.removeChartScriptNotInvokeRender(renderContext);
|
||||
HtmlRenderAttributes.removeChartVarName(renderContext);
|
||||
HtmlRenderAttributes.removeChartElementId(renderContext);
|
||||
|
||||
renderContext.removeAttribute(RENDER_ATTR_NAME_FOR_NOT_FOUND_SCRIPT);
|
||||
|
||||
out.write("var ");
|
||||
out.write(tmpRenderContextVar);
|
||||
out.write("=");
|
||||
writeNewLine(out);
|
||||
writeRenderContextScriptObject(out, renderContext);
|
||||
out.write(";");
|
||||
writeNewLine(out);
|
||||
out.write(varName + ".renderContext.attributes = " + tmpRenderContextVar + ".attributes;");
|
||||
writeNewLine(out);
|
||||
|
||||
List<? extends HtmlChart> charts = dashboard.getCharts();
|
||||
if (charts != null)
|
||||
{
|
||||
for (HtmlChart chart : charts)
|
||||
{
|
||||
out.write(varName + ".charts.push(" + chart.getVarName() + ");");
|
||||
writeNewLine(out);
|
||||
}
|
||||
}
|
||||
|
||||
out.write(varName + ".render = function(){");
|
||||
writeNewLine(out);
|
||||
out.write(" for(var i=0; i<this.charts.length; i++){ this.charts[i].render(); }");
|
||||
writeNewLine(out);
|
||||
out.write("};");
|
||||
writeNewLine(out);
|
||||
|
||||
out.write(varName + ".update = function(){");
|
||||
writeNewLine(out);
|
||||
out.write(" for(var i=0; i<this.charts.length; i++){ this.charts[i].update(); }");
|
||||
writeNewLine(out);
|
||||
out.write("};");
|
||||
writeNewLine(out);
|
||||
|
||||
if (hasListener)
|
||||
{
|
||||
out.write(varName + ".listener = window[\"" + listener + "\"];");
|
||||
writeNewLine(out);
|
||||
}
|
||||
|
||||
out.write("window.onload = function(){");
|
||||
writeNewLine(out);
|
||||
|
||||
if (hasListener)
|
||||
{
|
||||
out.write("if(" + varName + ".listener && " + varName + ".listener.beforeRender)");
|
||||
writeNewLine(out);
|
||||
out.write(" " + varName + ".listener.beforeRender(" + varName + "); ");
|
||||
writeNewLine(out);
|
||||
}
|
||||
|
||||
out.write(varName + ".render();");
|
||||
writeNewLine(out);
|
||||
|
||||
if (hasListener)
|
||||
{
|
||||
out.write("if(" + varName + ".listener && " + varName + ".listener.afterRender)");
|
||||
writeNewLine(out);
|
||||
out.write(" " + varName + ".listener.afterRender(" + varName + "); ");
|
||||
writeNewLine(out);
|
||||
}
|
||||
|
||||
if (hasListener)
|
||||
{
|
||||
out.write("if(" + varName + ".listener && " + varName + ".listener.beforeUpdate)");
|
||||
writeNewLine(out);
|
||||
out.write(" " + varName + ".listener.beforeUpdate(" + varName + "); ");
|
||||
writeNewLine(out);
|
||||
}
|
||||
|
||||
out.write(varName + ".update();");
|
||||
writeNewLine(out);
|
||||
|
||||
if (hasListener)
|
||||
{
|
||||
out.write("if(" + varName + ".listener && " + varName + ".listener.afterUpdate)");
|
||||
writeNewLine(out);
|
||||
out.write(" " + varName + ".listener.afterUpdate(" + varName + "); ");
|
||||
writeNewLine(out);
|
||||
}
|
||||
|
||||
out.write("};");
|
||||
writeNewLine(out);
|
||||
|
||||
writeScriptEndTag(out);
|
||||
writeNewLine(out);
|
||||
}
|
||||
|
||||
protected void writeHtmlDashboardScriptObject(Writer out, HtmlDashboard dashboard, boolean renderContextEmpty)
|
||||
throws IOException
|
||||
{
|
||||
getHtmlDashboardScriptObjectWriter().write(out, dashboard, renderContextEmpty);
|
||||
}
|
||||
|
||||
protected void writeRenderContextScriptObject(Writer out, RenderContext renderContext) throws IOException
|
||||
{
|
||||
getHtmlDashboardScriptObjectWriter().writeRenderContext(out, renderContext, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* “@chart”指令。
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
*/
|
||||
protected class ChartTemplateDirectiveModel extends AbstractTemplateDirectiveModel
|
||||
{
|
||||
public ChartTemplateDirectiveModel()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Override
|
||||
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
|
||||
throws TemplateException, IOException
|
||||
{
|
||||
String widget = getStringParamValue(params, "widget");
|
||||
String var = getStringParamValue(params, "var");
|
||||
String elementId = getStringParamValue(params, "elementId");
|
||||
|
||||
HtmlDashboardRenderDataModel dataModel = getHtmlDashboardRenderDataModel(env);
|
||||
HtmlDashboard htmlDashboard = dataModel.getHtmlDashboard();
|
||||
HtmlRenderContext renderContext = htmlDashboard.getRenderContext();
|
||||
int nextSequence = -1;
|
||||
|
||||
HtmlChartWidget<HtmlRenderContext> chartWidget = getHtmlChartWidgetForRender(renderContext, widget);
|
||||
|
||||
if (StringUtil.isEmpty(var))
|
||||
{
|
||||
nextSequence = HtmlRenderAttributes.getNextSequenceIfNot(renderContext, nextSequence);
|
||||
var = HtmlRenderAttributes.generateChartVarName(nextSequence);
|
||||
}
|
||||
|
||||
if (StringUtil.isEmpty(elementId))
|
||||
{
|
||||
nextSequence = HtmlRenderAttributes.getNextSequenceIfNot(renderContext, nextSequence);
|
||||
elementId = HtmlRenderAttributes.generateChartElementId(nextSequence);
|
||||
}
|
||||
|
||||
HtmlRenderAttributes.setChartNotRenderScriptTag(renderContext, false);
|
||||
HtmlRenderAttributes.setChartScriptNotInvokeRender(renderContext, true);
|
||||
HtmlRenderAttributes.setChartVarName(renderContext, var);
|
||||
HtmlRenderAttributes.setChartElementId(renderContext, elementId);
|
||||
|
||||
HtmlChart chart = chartWidget.render(renderContext);
|
||||
|
||||
List<HtmlChart> charts = (List<HtmlChart>) htmlDashboard.getCharts();
|
||||
if (charts == null)
|
||||
{
|
||||
charts = new ArrayList<HtmlChart>();
|
||||
htmlDashboard.setCharts(charts);
|
||||
}
|
||||
|
||||
charts.add(chart);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写脚本开始标签。
|
||||
*
|
||||
* @param out
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
protected void writeScriptStartTag(Writer out) throws IOException
|
||||
{
|
||||
out.write("<script type=\"text/javascript\">");
|
||||
}
|
||||
|
||||
/**
|
||||
* 写脚本结束标签。
|
||||
*
|
||||
* @param out
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
protected void writeScriptEndTag(Writer out) throws IOException
|
||||
{
|
||||
out.write("</script>");
|
||||
}
|
||||
|
||||
/**
|
||||
* 写换行符。
|
||||
*
|
||||
* @param out
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
protected void writeNewLine(Writer out) throws IOException
|
||||
{
|
||||
out.write(getNewLine());
|
||||
}
|
||||
out.write(getNewLine());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,16 +17,16 @@ import org.junit.Assert;
|
|||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* {@linkplain HtmlTplDashboardWidget}单元测试类。
|
||||
* {@linkplain HtmlTplDashboardWidgetFmkRenderer}单元测试类。
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
*/
|
||||
public class HtmlTplDashboardWidgetTest
|
||||
public class HtmlTplDashboardWidgetFmkRendererTest
|
||||
{
|
||||
private HtmlTplDashboardWidget<HtmlRenderContext> dashboardWidget;
|
||||
private HtmlTplDashboardWidgetFmkRenderer<HtmlRenderContext> renderer;
|
||||
|
||||
public HtmlTplDashboardWidgetTest() throws Exception
|
||||
public HtmlTplDashboardWidgetFmkRendererTest() throws Exception
|
||||
{
|
||||
super();
|
||||
|
||||
|
@ -36,27 +36,24 @@ public class HtmlTplDashboardWidgetTest
|
|||
chartPlugin, (DataSetFactory[]) null);
|
||||
|
||||
DashboardWidgetResManager resManager = new DashboardWidgetResManager(
|
||||
"src/test/resources/org/datagear/analysis/support/html/htmlTplDashboardWidgets");
|
||||
"src/test/resources/org/datagear/analysis/support/html/htmlTplDashboardWidgets/freemarker");
|
||||
|
||||
SimpleChartWidgetSource chartWidgetSource = new SimpleChartWidgetSource(htmlChartWidget);
|
||||
|
||||
HtmlTplDashboardWidgetRenderer<HtmlRenderContext> renderer = new HtmlTplDashboardWidgetRenderer<HtmlRenderContext>(
|
||||
"<script type='text/javascript' src='static/js/jquery.js'></script>", resManager, chartWidgetSource);
|
||||
renderer.init();
|
||||
|
||||
HtmlTplDashboardWidget<HtmlRenderContext> dashboardWidget = new HtmlTplDashboardWidget<HtmlRenderContext>(
|
||||
"widget01", "index.html", renderer);
|
||||
|
||||
this.dashboardWidget = dashboardWidget;
|
||||
this.renderer = new HtmlTplDashboardWidgetFmkRenderer<HtmlRenderContext>(resManager, chartWidgetSource);
|
||||
this.renderer.init();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderTest()
|
||||
{
|
||||
HtmlTplDashboardWidget<HtmlRenderContext> dashboardWidget = new HtmlTplDashboardWidget<HtmlRenderContext>(
|
||||
"widget01", "index.html", this.renderer);
|
||||
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
DefaultHtmlRenderContext renderContext = new DefaultHtmlRenderContext(stringWriter);
|
||||
HtmlRenderAttributes.setRenderStyle(renderContext, RenderStyle.DARK);
|
||||
HtmlDashboard dashboard = this.dashboardWidget.render(renderContext);
|
||||
HtmlDashboard dashboard = dashboardWidget.render(renderContext);
|
||||
|
||||
String html = stringWriter.toString();
|
||||
|
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
* Copyright (c) 2018 datagear.tech. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package org.datagear.analysis.support.html;
|
||||
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.datagear.analysis.DataSetFactory;
|
||||
import org.datagear.analysis.RenderStyle;
|
||||
import org.datagear.analysis.support.DashboardWidgetResManager;
|
||||
import org.datagear.analysis.support.SimpleChartWidgetSource;
|
||||
import org.datagear.analysis.support.html.HtmlTplDashboardWidgetHtmlRenderer.ChartInfo;
|
||||
import org.datagear.analysis.support.html.HtmlTplDashboardWidgetHtmlRenderer.DashboardInfo;
|
||||
import org.datagear.util.IOUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* {@linkplain HtmlTplDashboardWidgetHtmlRenderer}单元测试类。
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
*/
|
||||
public class HtmlTplDashboardWidgetHtmlRendererTest
|
||||
{
|
||||
private HtmlTplDashboardWidgetHtmlRenderer<HtmlRenderContext> renderer;
|
||||
|
||||
protected static final String IMPORT_CONTENT_JQUERY = "<script type=\"text/javascript\" src=\"jquery.js\"></script>";
|
||||
|
||||
protected static final String IMPORT_CONTENT_UTIL = "<script type=\"text/javascript\" src=\"util.js\"></script>";
|
||||
|
||||
protected static final String IMPORT_CONTENT_THEME = "<link rel=\"stylesheet\" type=\"text/css\" href=\"theme.css\">";
|
||||
|
||||
protected static final String IMPORT_CONTENT_STYLE = "<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\">";
|
||||
|
||||
public HtmlTplDashboardWidgetHtmlRendererTest() throws Exception
|
||||
{
|
||||
super();
|
||||
|
||||
HtmlChartPlugin<HtmlRenderContext> chartPlugin = HtmlChartPluginTest.createHtmlChartPlugin();
|
||||
|
||||
HtmlChartWidget<HtmlRenderContext> htmlChartWidget = new HtmlChartWidget<HtmlRenderContext>("chart-widget-01",
|
||||
chartPlugin, (DataSetFactory[]) null);
|
||||
|
||||
DashboardWidgetResManager resManager = new DashboardWidgetResManager(
|
||||
"src/test/resources/org/datagear/analysis/support/html/htmlTplDashboardWidgets/html");
|
||||
|
||||
SimpleChartWidgetSource chartWidgetSource = new SimpleChartWidgetSource(htmlChartWidget);
|
||||
|
||||
List<HtmlDashboardImport> htmlDashboardImports = new ArrayList<HtmlDashboardImport>();
|
||||
htmlDashboardImports.add(new HtmlDashboardImport("jquery", IMPORT_CONTENT_JQUERY));
|
||||
htmlDashboardImports.add(new HtmlDashboardImport("util", IMPORT_CONTENT_UTIL));
|
||||
htmlDashboardImports.add(new HtmlDashboardImport("theme", IMPORT_CONTENT_THEME));
|
||||
htmlDashboardImports.add(new HtmlDashboardImport("style", IMPORT_CONTENT_STYLE));
|
||||
|
||||
this.renderer = new HtmlTplDashboardWidgetHtmlRenderer<HtmlRenderContext>(resManager, chartWidgetSource);
|
||||
this.renderer.setHtmlDashboardImports(htmlDashboardImports);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderHtmlDashboardTest() throws Exception
|
||||
{
|
||||
HtmlTplDashboardWidget<HtmlRenderContext> dashboardWidget = createHtmlTplDashboardWidget();
|
||||
|
||||
// 看板属性,双引号
|
||||
{
|
||||
String template = "<html dg-dashboard-var=\"myDashboard\" dg-dashboard-listener=\"myListener\" "
|
||||
+ " dg-dashboard-import-exclude=\"jquery\"><head></head><body></body></html>";
|
||||
|
||||
StringWriter out = new StringWriter();
|
||||
DefaultHtmlRenderContext renderContext = new DefaultHtmlRenderContext(out);
|
||||
|
||||
HtmlDashboard dashboard = this.renderer.createHtmlDashboard(renderContext, dashboardWidget);
|
||||
|
||||
DashboardInfo dashboardInfo = this.renderer.renderHtmlDashboard(renderContext, dashboard,
|
||||
IOUtil.getReader(template));
|
||||
|
||||
String html = out.toString();
|
||||
|
||||
Assert.assertEquals("myDashboard", dashboardInfo.getDashboardVar());
|
||||
Assert.assertEquals("myListener", dashboardInfo.getListenerVar());
|
||||
Assert.assertEquals("jquery", dashboardInfo.getImportExclude());
|
||||
Assert.assertFalse(html.contains(IMPORT_CONTENT_JQUERY));
|
||||
Assert.assertTrue(html.contains(IMPORT_CONTENT_UTIL));
|
||||
Assert.assertTrue(html.contains(IMPORT_CONTENT_THEME));
|
||||
Assert.assertTrue(html.contains(IMPORT_CONTENT_STYLE));
|
||||
Assert.assertTrue(html.contains("var myDashboard"));
|
||||
Assert.assertTrue(html.contains("myDashboard.listener = window[\"myListener\"];"));
|
||||
}
|
||||
|
||||
// 看板属性,无引号
|
||||
{
|
||||
String template = "<html dg-dashboard-var=myDashboard dg-dashboard-listener=myListener "
|
||||
+ " dg-dashboard-import-exclude=jquery><head></head><body></body></html>";
|
||||
|
||||
StringWriter out = new StringWriter();
|
||||
DefaultHtmlRenderContext renderContext = new DefaultHtmlRenderContext(out);
|
||||
|
||||
HtmlDashboard dashboard = this.renderer.createHtmlDashboard(renderContext, dashboardWidget);
|
||||
|
||||
DashboardInfo dashboardInfo = this.renderer.renderHtmlDashboard(renderContext, dashboard,
|
||||
IOUtil.getReader(template));
|
||||
|
||||
String html = getHtmlWithPrint(out);
|
||||
|
||||
Assert.assertEquals("myDashboard", dashboardInfo.getDashboardVar());
|
||||
Assert.assertEquals("myListener", dashboardInfo.getListenerVar());
|
||||
Assert.assertEquals("jquery", dashboardInfo.getImportExclude());
|
||||
Assert.assertFalse(html.contains(IMPORT_CONTENT_JQUERY));
|
||||
Assert.assertTrue(html.contains(IMPORT_CONTENT_UTIL));
|
||||
Assert.assertTrue(html.contains(IMPORT_CONTENT_THEME));
|
||||
Assert.assertTrue(html.contains(IMPORT_CONTENT_STYLE));
|
||||
Assert.assertTrue(html.contains("var myDashboard"));
|
||||
Assert.assertTrue(html.contains("myDashboard.listener = window[\"myListener\"];"));
|
||||
}
|
||||
|
||||
// 看板属性,单引号
|
||||
{
|
||||
String template = "<html dg-dashboard-var='myDashboard' dg-dashboard-listener='myListener' "
|
||||
+ " dg-dashboard-import-exclude='jquery'><head></head><body></body></html>";
|
||||
|
||||
StringWriter out = new StringWriter();
|
||||
DefaultHtmlRenderContext renderContext = new DefaultHtmlRenderContext(out);
|
||||
|
||||
HtmlDashboard dashboard = this.renderer.createHtmlDashboard(renderContext, dashboardWidget);
|
||||
|
||||
DashboardInfo dashboardInfo = this.renderer.renderHtmlDashboard(renderContext, dashboard,
|
||||
IOUtil.getReader(template));
|
||||
|
||||
String html = getHtmlWithPrint(out);
|
||||
|
||||
Assert.assertEquals("myDashboard", dashboardInfo.getDashboardVar());
|
||||
Assert.assertEquals("myListener", dashboardInfo.getListenerVar());
|
||||
Assert.assertEquals("jquery", dashboardInfo.getImportExclude());
|
||||
Assert.assertFalse(html.contains(IMPORT_CONTENT_JQUERY));
|
||||
Assert.assertTrue(html.contains(IMPORT_CONTENT_UTIL));
|
||||
Assert.assertTrue(html.contains(IMPORT_CONTENT_THEME));
|
||||
Assert.assertTrue(html.contains(IMPORT_CONTENT_STYLE));
|
||||
Assert.assertTrue(html.contains("var myDashboard"));
|
||||
Assert.assertTrue(html.contains("myDashboard.listener = window[\"myListener\"];"));
|
||||
}
|
||||
|
||||
// 看板属性,多个导入排除值
|
||||
{
|
||||
String template = "<html dg-dashboard-var='myDashboard' dg-dashboard-listener='myListener' "
|
||||
+ " dg-dashboard-import-exclude='jquery,theme, style '><head></head><body></body></html>";
|
||||
|
||||
StringWriter out = new StringWriter();
|
||||
DefaultHtmlRenderContext renderContext = new DefaultHtmlRenderContext(out);
|
||||
|
||||
HtmlDashboard dashboard = this.renderer.createHtmlDashboard(renderContext, dashboardWidget);
|
||||
|
||||
DashboardInfo dashboardInfo = this.renderer.renderHtmlDashboard(renderContext, dashboard,
|
||||
IOUtil.getReader(template));
|
||||
|
||||
String html = getHtmlWithPrint(out);
|
||||
|
||||
Assert.assertEquals("myDashboard", dashboardInfo.getDashboardVar());
|
||||
Assert.assertEquals("myListener", dashboardInfo.getListenerVar());
|
||||
Assert.assertEquals("jquery,theme, style", dashboardInfo.getImportExclude());
|
||||
Assert.assertFalse(html.contains(IMPORT_CONTENT_JQUERY));
|
||||
Assert.assertTrue(html.contains(IMPORT_CONTENT_UTIL));
|
||||
Assert.assertFalse(html.contains(IMPORT_CONTENT_THEME));
|
||||
Assert.assertFalse(html.contains(IMPORT_CONTENT_STYLE));
|
||||
Assert.assertTrue(html.contains("var myDashboard"));
|
||||
Assert.assertTrue(html.contains("myDashboard.listener = window[\"myListener\"];"));
|
||||
}
|
||||
|
||||
// 看板属性,默认
|
||||
{
|
||||
String template = "<html><head></head><body></body></html>";
|
||||
|
||||
StringWriter out = new StringWriter();
|
||||
DefaultHtmlRenderContext renderContext = new DefaultHtmlRenderContext(out);
|
||||
|
||||
HtmlDashboard dashboard = this.renderer.createHtmlDashboard(renderContext, dashboardWidget);
|
||||
|
||||
DashboardInfo dashboardInfo = this.renderer.renderHtmlDashboard(renderContext, dashboard,
|
||||
IOUtil.getReader(template));
|
||||
|
||||
String html = getHtmlWithPrint(out);
|
||||
|
||||
Assert.assertNull(dashboardInfo.getDashboardVar());
|
||||
Assert.assertNull(dashboardInfo.getListenerVar());
|
||||
Assert.assertNull(dashboardInfo.getImportExclude());
|
||||
Assert.assertTrue(html.contains(IMPORT_CONTENT_JQUERY));
|
||||
Assert.assertTrue(html.contains(IMPORT_CONTENT_UTIL));
|
||||
Assert.assertTrue(html.contains(IMPORT_CONTENT_THEME));
|
||||
Assert.assertTrue(html.contains(IMPORT_CONTENT_STYLE));
|
||||
Assert.assertTrue(html.contains("var dataGearDashboard1"));
|
||||
Assert.assertFalse(html.contains("dataGearDashboard1.listener = window[\""));
|
||||
}
|
||||
|
||||
// 图表属性
|
||||
{
|
||||
String template = "<html><head></head><body>" + "\r\n"
|
||||
+ "<div id=\"element_1\" dg-chart-widget=\"chartwidget_1\" dg-chart-var=\"chartvar_1\"></div>"
|
||||
+ "\r\n" + "<div id='element_2' dg-chart-widget='chartwidget_2' dg-chart-var='chartvar_2'></div>"
|
||||
+ "\r\n" + "<div id=element_3 dg-chart-widget=chartwidget_3 dg-chart-var=chartvar_3></div>" + "\r\n"
|
||||
+ "<div sdf abc def 12345677788 // >"
|
||||
//
|
||||
+ "\r\n"
|
||||
+ "<div id=element_4 dg-chart-widget=chartwidget_4 dg-chart-var=chartvar_4 ></div>"
|
||||
+ "\r\n"
|
||||
+ "<div id = element_5 dg-chart-widget= chartwidget_5 dg-chart-var =chartvar_5/>"
|
||||
+ "\r\n" + "<div id=element_6 dg-chart-widget=chartwidget_6 dg-chart-var=chartvar_6 />"
|
||||
+ "\r\n" + "<div id=element_7 dg-chart-widget=chartwidget_7 dg-chart-var=chartvar_7 / >"
|
||||
+ "\r\n" + "<div dg-chart-widget=chartwidget_8 / >"
|
||||
//
|
||||
+ "\r\n" + "<div dg-chart-widget=chartwidget_9/>"
|
||||
//
|
||||
+ "\r\n" + "<div dg-chart-widget=/>"
|
||||
//
|
||||
+ "\r\n" + "<div dg-chart-widget= />"
|
||||
//
|
||||
+ "\r\n" + "</body></html>";
|
||||
|
||||
StringWriter out = new StringWriter();
|
||||
DefaultHtmlRenderContext renderContext = new DefaultHtmlRenderContext(out);
|
||||
|
||||
HtmlDashboard dashboard = this.renderer.createHtmlDashboard(renderContext, dashboardWidget);
|
||||
|
||||
DashboardInfo dashboardInfo = this.renderer.renderHtmlDashboard(renderContext, dashboard,
|
||||
IOUtil.getReader(template));
|
||||
|
||||
String html = getHtmlWithPrint(out);
|
||||
|
||||
List<ChartInfo> chartInfos = dashboardInfo.getChartInfos();
|
||||
Assert.assertEquals(9, chartInfos.size());
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
ChartInfo chartInfo = chartInfos.get(i);
|
||||
Assert.assertEquals("element_" + (i + 1), chartInfo.getElementId());
|
||||
Assert.assertEquals("chartwidget_" + (i + 1), chartInfo.getWidgetId());
|
||||
Assert.assertEquals("chartvar_" + (i + 1), chartInfo.getChartVar());
|
||||
}
|
||||
|
||||
Assert.assertTrue(html.contains("<html><head>"));
|
||||
Assert.assertTrue(html.contains("</head><body>"));
|
||||
Assert.assertTrue(html.contains(
|
||||
"<div id=\"element_1\" dg-chart-widget=\"chartwidget_1\" dg-chart-var=\"chartvar_1\"></div>"));
|
||||
Assert.assertTrue(html
|
||||
.contains("<div id='element_2' dg-chart-widget='chartwidget_2' dg-chart-var='chartvar_2'></div>"));
|
||||
Assert.assertTrue(
|
||||
html.contains("<div id=element_3 dg-chart-widget=chartwidget_3 dg-chart-var=chartvar_3></div>"));
|
||||
Assert.assertTrue(html.contains("<div sdf abc def 12345677788 // >"));
|
||||
Assert.assertTrue(html.contains(
|
||||
"<div id=element_4 dg-chart-widget=chartwidget_4 dg-chart-var=chartvar_4 ></div>"));
|
||||
Assert.assertTrue(html.contains(
|
||||
"<div id = element_5 dg-chart-widget= chartwidget_5 dg-chart-var =chartvar_5/>"));
|
||||
Assert.assertTrue(html
|
||||
.contains("<div id=element_6 dg-chart-widget=chartwidget_6 dg-chart-var=chartvar_6 />"));
|
||||
Assert.assertTrue(html
|
||||
.contains("<div id=element_7 dg-chart-widget=chartwidget_7 dg-chart-var=chartvar_7 / >"));
|
||||
Assert.assertTrue(
|
||||
html.contains("<div dg-chart-widget=chartwidget_8 id=\"dataGearChartElement1\" / >"));
|
||||
Assert.assertTrue(html.contains("<div dg-chart-widget=chartwidget_9 id=\"dataGearChartElement2\" />"));
|
||||
Assert.assertTrue(html.contains("<div dg-chart-widget=/>"));
|
||||
Assert.assertTrue(html.contains("<div dg-chart-widget= />"));
|
||||
Assert.assertTrue(html.contains("</body></html>"));
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
Assert.assertTrue(html.contains("var chartvar_" + (i + 1)));
|
||||
Assert.assertTrue(html.contains("var dataGearChart4"));
|
||||
Assert.assertTrue(html.contains("var dataGearChart5"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderTest() throws Exception
|
||||
{
|
||||
HtmlTplDashboardWidget<HtmlRenderContext> dashboardWidget = createHtmlTplDashboardWidget();
|
||||
|
||||
StringWriter out = new StringWriter();
|
||||
DefaultHtmlRenderContext renderContext = new DefaultHtmlRenderContext(out);
|
||||
HtmlRenderAttributes.setRenderStyle(renderContext, RenderStyle.DARK);
|
||||
HtmlDashboard dashboard = dashboardWidget.render(renderContext);
|
||||
|
||||
getHtmlWithPrint(out);
|
||||
|
||||
Assert.assertEquals(6, dashboard.getCharts().size());
|
||||
}
|
||||
|
||||
protected HtmlTplDashboardWidget<HtmlRenderContext> createHtmlTplDashboardWidget()
|
||||
{
|
||||
HtmlTplDashboardWidget<HtmlRenderContext> dashboardWidget = new HtmlTplDashboardWidget<HtmlRenderContext>(
|
||||
"widget01", "index.html", this.renderer);
|
||||
|
||||
return dashboardWidget;
|
||||
}
|
||||
|
||||
protected String getHtmlWithPrint(StringWriter out)
|
||||
{
|
||||
String html = out.toString();
|
||||
|
||||
System.out.println(html);
|
||||
System.out.println("");
|
||||
System.out.println("-----------------------");
|
||||
System.out.println("");
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
|
@ -14,29 +14,16 @@
|
|||
<script type="text/javascript">
|
||||
var myListener =
|
||||
{
|
||||
beforeRender : function(dashboard)
|
||||
onRender : function(dashboard)
|
||||
{
|
||||
var element = document.getElementById("listener");
|
||||
|
||||
element.innerHTML = "<div>beforeRender</div>";
|
||||
element.innerHTML += "<div>onRender</div>";
|
||||
},
|
||||
afterRender : function(dashboard)
|
||||
|
||||
onUpdate : function(dashboard)
|
||||
{
|
||||
var element = document.getElementById("listener");
|
||||
|
||||
element.innerHTML += "<div>afterRender</div>";
|
||||
},
|
||||
beforeUpdate : function(dashboard)
|
||||
{
|
||||
var element = document.getElementById("listener");
|
||||
|
||||
element.innerHTML += "<div>beforeUpdate</div>";
|
||||
},
|
||||
afterUpdate : function(dashboard)
|
||||
{
|
||||
var element = document.getElementById("listener");
|
||||
|
||||
element.innerHTML += "<div>afterUpdate</div>";
|
||||
element.innerHTML += "<div>onUpdate</div>";
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,36 @@
|
|||
<!doctype html>
|
||||
<html dg-dashboard-var="myDashboard" dg-dashboard-listener="myListener" dg-dashboard-import-exclude="jquery,theme">
|
||||
<head>
|
||||
<script type="text/javascript">
|
||||
var myListener =
|
||||
{
|
||||
onRender : function(dashboard)
|
||||
{
|
||||
var element = document.getElementById("listener");
|
||||
element.innerHTML += "<div>onRender</div>";
|
||||
},
|
||||
|
||||
onUpdate : function(dashboard)
|
||||
{
|
||||
var element = document.getElementById("listener");
|
||||
element.innerHTML += "<div>onUpdate</div>";
|
||||
}
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div dg-chart-widget="chart-widget-01"></div>
|
||||
|
||||
<div id="element_1" dg-chart-widget="chart-widget-01" dg-chart-var="chartvar_01" ></div>
|
||||
|
||||
<div dg-chart-widget="chart-widget-03"></div>
|
||||
|
||||
<div id="element_2" dg-chart-widget="chart-widget-01" ></div>
|
||||
|
||||
<div dg-chart-widget="chart-widget-05"></div>
|
||||
|
||||
<div dg-chart-widget="chart-widget-01" dg-chart-var="chartvar_02"></div>
|
||||
|
||||
<div id="listener"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -11,7 +11,7 @@ import java.util.Date;
|
|||
|
||||
import org.datagear.analysis.support.html.HtmlRenderContext;
|
||||
import org.datagear.analysis.support.html.HtmlTplDashboardWidget;
|
||||
import org.datagear.analysis.support.html.HtmlTplDashboardWidgetRenderer;
|
||||
import org.datagear.analysis.support.html.HtmlTplDashboardWidgetFmkRenderer;
|
||||
|
||||
/**
|
||||
* {@linkplain HtmlTplDashboardWidget}实体。
|
||||
|
@ -48,7 +48,7 @@ public class HtmlTplDashboardWidgetEntity extends HtmlTplDashboardWidget<HtmlRen
|
|||
}
|
||||
|
||||
public HtmlTplDashboardWidgetEntity(String id, String template,
|
||||
HtmlTplDashboardWidgetRenderer<HtmlRenderContext> renderer, String name, User createUser)
|
||||
HtmlTplDashboardWidgetFmkRenderer<HtmlRenderContext> renderer, String name, User createUser)
|
||||
{
|
||||
super(id, template, renderer);
|
||||
this.name = name;
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.Map;
|
|||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.datagear.analysis.support.html.HtmlRenderContext;
|
||||
import org.datagear.analysis.support.html.HtmlTplDashboardWidget;
|
||||
import org.datagear.analysis.support.html.HtmlTplDashboardWidgetFmkRenderer;
|
||||
import org.datagear.analysis.support.html.HtmlTplDashboardWidgetRenderer;
|
||||
import org.datagear.management.domain.HtmlChartWidgetEntity;
|
||||
import org.datagear.management.domain.HtmlTplDashboardWidgetEntity;
|
||||
|
@ -49,7 +50,7 @@ public class HtmlTplDashboardWidgetEntityServiceImpl
|
|||
AuthorizationService authorizationService)
|
||||
{
|
||||
super(sqlSessionFactory);
|
||||
this.htmlTplDashboardWidgetRenderer = (HtmlTplDashboardWidgetRenderer<HtmlRenderContext>) htmlTplDashboardWidgetRenderer;
|
||||
this.htmlTplDashboardWidgetRenderer = (HtmlTplDashboardWidgetFmkRenderer<HtmlRenderContext>) htmlTplDashboardWidgetRenderer;
|
||||
this.authorizationService = authorizationService;
|
||||
}
|
||||
|
||||
|
@ -59,7 +60,7 @@ public class HtmlTplDashboardWidgetEntityServiceImpl
|
|||
AuthorizationService authorizationService)
|
||||
{
|
||||
super(sqlSessionTemplate);
|
||||
this.htmlTplDashboardWidgetRenderer = (HtmlTplDashboardWidgetRenderer<HtmlRenderContext>) htmlTplDashboardWidgetRenderer;
|
||||
this.htmlTplDashboardWidgetRenderer = (HtmlTplDashboardWidgetFmkRenderer<HtmlRenderContext>) htmlTplDashboardWidgetRenderer;
|
||||
this.authorizationService = authorizationService;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.io.InputStreamReader;
|
|||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.Writer;
|
||||
|
@ -335,6 +336,17 @@ public class IOUtil
|
|||
return new BufferedReader(new InputStreamReader(in, encoding));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取输入流。
|
||||
*
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static StringReader getReader(String s)
|
||||
{
|
||||
return new StringReader(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取输出流。
|
||||
*
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
*/
|
||||
package org.datagear.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
@ -187,4 +190,28 @@ public class StringUtil
|
|||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 拆分字符串,并删除元素两边的空格。
|
||||
* <p>
|
||||
* 如果{@code s}为{@code null},返回空列表。
|
||||
* </p>
|
||||
*
|
||||
* @param str
|
||||
* @param splitter
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<String> splitWithTrim(String str, String splitter)
|
||||
{
|
||||
if (str == null)
|
||||
return Collections.EMPTY_LIST;
|
||||
|
||||
String[] strs = str.split(splitter);
|
||||
|
||||
for (int i = 0; i < strs.length; i++)
|
||||
strs[i] = strs[i].trim();
|
||||
|
||||
return Arrays.asList(strs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -336,8 +336,15 @@
|
|||
<property name="rootDirectory" ref="dashboardRootDirectory" />
|
||||
</bean>
|
||||
|
||||
<bean id="htmlTplDashboardWidgetRenderer" class="org.datagear.analysis.support.html.HtmlTplDashboardWidgetRenderer" init-method="init">
|
||||
<property name="importContent" value="<script type='text/javascript' src='$CONTEXTPATH/static/script/jquery/jquery-1.12.4.js' ></script>" />
|
||||
<bean id="htmlTplDashboardWidgetRenderer" class="org.datagear.analysis.support.html.HtmlTplDashboardWidgetHtmlRenderer">
|
||||
<property name="htmlDashboardImports">
|
||||
<list>
|
||||
<bean class="org.datagear.analysis.support.html.HtmlDashboardImport">
|
||||
<property name="name" value="jquery" />
|
||||
<property name="content" value="<script type='text/javascript' src='$CONTEXTPATH/static/script/jquery/jquery-1.12.4.js' ></script>" />
|
||||
</bean>
|
||||
</list>
|
||||
</property>
|
||||
<property name="dashboardWidgetResManager" ref="dashboardWidgetResManager" />
|
||||
<property name="chartWidgetSource" ref="htmlChartWidgetEntityService" />
|
||||
</bean>
|
||||
|
|
Loading…
Reference in New Issue