【仅供内部供应商使用,不提供对外解答和培训】
...
以echarts三维柱形图(以下简称DEMO)为例,开发之前要知道:
1.数据结构
x轴数据 | y轴数据 | z轴数据 |
---|---|---|
... | ... | ... |
... | .. | ... |
2.前台图表实例化api:echarts.init(dom),配置项api:instance.setOption(option)。
第一步:
定义图表所需数据结构xxxDataConfig,继承抽象类AbstractDataConfig。
eg :
声明变量x、y、z(保存配置的xyz轴数据的字段名称)。
实现抽象方法:readXML(模板读取)&& writeXML(模板写入)&& clone && equals && hashCode && dataSetFields(返回由声明的变量组成的数组,用于预览时取数据库取数)。
其中,供开发者使用的readExtendedField&writeExtendedField方法的第二个参数是字段写入模板对应的key。
Code Block | ||||
---|---|---|---|---|
| ||||
package com.fr.plugin.demo; import com.fr.extended.chart.AbstractDataConfig; import com.fr.extended.chart.ExtendedField; import com.fr.general.ComparatorUtils; import com.fr.stable.xml.XMLPrintWriter; import com.fr.stable.xml.XMLableReader; /** * Created by shine on 2018/3/24. */ public class DemoDataConfig extends AbstractDataConfig { private ExtendedField x = new ExtendedField(); private ExtendedField y = new ExtendedField(); private ExtendedField z = new ExtendedField(); public ExtendedField getX() { return x; } public void setX(ExtendedField x) { this.x = x; } public ExtendedField getY() { return y; } public void setY(ExtendedField y) { this.y = y; } public ExtendedField getZ() { return z; } public void setZ(ExtendedField z) { this.z = z; } @Override protected void readAttr(XMLableReader reader) { readExtendedField(x, "x", reader); readExtendedField(y, "y", reader); readExtendedField(z, "z", reader); } @Override protected void writeAttr(XMLPrintWriter writer) { writeExtendedField(x, "x", writer); writeExtendedField(y, "y", writer); writeExtendedField(z, "z", writer); } @Override public ExtendedField[] dataSetFields() { return new ExtendedField[]{ x, y, z }; } @Override public DemoDataConfig clone() throws CloneNotSupportedException { DemoDataConfig result = new DemoDataConfig(); result.setX(this.getX().clone()); result.setY(this.getY().clone()); result.setZ(this.getZ().clone()); return result; } @Override public int hashCode() { return super.hashCode() + AssistUtils.hashCode(this.getX(), this.getY(), this.getZ()); } @Override public boolean equals(Object obj) { return obj instanceof DemoDataConfig && AssistUtils.equals(this.getX(), ((DemoDataConfig) obj).getX()) && AssistUtils.equals(this.getY(), ((DemoDataConfig) obj).getY()) && AssistUtils.equals(this.getZ(), ((DemoDataConfig) obj).getZ()) ; } } |
第二步:
定义前台图表对象xxxWrapper.js,指定图表库的初始图表接口。
eg:demoWrapper
Code Block | ||||
---|---|---|---|---|
| ||||
demoWrapper = ExtendedChart.extend({ _init:function (dom, option) { var chart = echarts.init(dom); chart.setOption(option); return chart; } }); |
第三步:
定义后台图表对象xxxChart,继承抽象类AbstractChart。注意点:继承的时候别忘了指定泛型DemoDataConfig,即extends AbstractChart<DemoDataConfig>。
eg:
实现抽象方法:getChartID (图表标志ID)&& getChartName(图表名称) && demoImagePath (图表选择界面图片路径) && addJSON (预览时生成的json对象,即图表展现所需配置项option && requiredJS (前端图表库js文件)&& wrapperName(前端图表对象,即第二步定义的对象名称)。
其中,获取某字段对应的数据库数据使用方法dataConfig.getX().getValues())。
Code Block | ||||
---|---|---|---|---|
| ||||
package com.fr.plugin.extended.chart.demo; import com.fr.base.BaseFormula; import com.fr.extended.chart.AbstractChart; import com.fr.extended.chart.HyperLinkPara; import com.fr.extended.chart.export.ExportProcessor; import com.fr.general.GeneralUtils; import com.fr.json.JSON; import com.fr.json.JSONArray; import com.fr.json.JSONException; import com.fr.json.JSONFactory; import com.fr.json.JSONObject; import com.fr.stable.web.Repository; import java.util.List; /** * Created by shine on 2018/3/24. */ public class DemoChart extends AbstractChart<DemoDataConfig>{ private static final String ID = "DEMO_CHART"; private static final String NAME = "DEMO图表"; @Override protected String getChartID() { return ID; } @Override public String getChartName() { return NAME; } @Override protected String demoImagePath() { return "com/fr/plugin/extended/chart/demo/demo.png"; } @Override protected void addJSON(DemoDataConfig dataConfig, JSONObject jsonObject, Repository repo, JSONPara para) throws JSONException { JSONArray array = JSONFactory.createJSON(JSON.ARRAY); List<Object> xValues = dataConfig.getX().getValues(); List<Object> yValues = dataConfig.getY().getValues(); List<Object> zValues = dataConfig.getZ().getValues(); double maxValue = Double.MIN_VALUE; for (int i = 0, len = xValues.size(); i < len; i++) { maxValue = Math.max(GeneralUtils.objectToNumber(zValues.get(i)).doubleValue(), maxValue); array.put(JSONFactory.createJSON(JSON.ARRAY).put(xValues.get(i)).put(yValues.get(i)).put(zValues.get(i))); } jsonObject.put("series", JSONFactory.createJSON(JSON.OBJECT).put("type", "bar3D").put("data", array) .put("bevelSize", 0.2).put("bevelSmoothness", 2).put("shading", "color")); jsonObject.put("xAxis3D", JSONFactory.createJSON(JSON.OBJECT).put("type", "category")) .put("yAxis3D", JSONFactory.createJSON(JSON.OBJECT).put("type", "category")) .put("zAxis3D", JSONFactory.createJSON(JSON.OBJECT).put("type", "value")); jsonObject.put("grid3D", JSONFactory.createJSON(JSON.OBJECT).put("boxWidth", 200).put("boxDepth", 80)); jsonObject.put("visualMap", JSONFactory.createJSON(JSON.OBJECT) .put("max", maxValue) .put("color", JSONFactory.createJSON(JSON.ARRAY).put("#d94e5d").put("#eac736").put("#50a3ba"))); } @Override protected String[] requiredJS() { return new String[]{ "com/fr/plugin/extended/chart/demo/demoWrapper.js", "com/fr/plugin/extended/chart/demo/echarts.js", "com/fr/plugin/extended/chart/demo/echarts-gl.js" }; } @Override protected String wrapperName() { return "demoWrapper"; } @Override protected HyperLinkPara[] hyperLinkParas() { return new HyperLinkPara[0]; } @Override protected List<StringFormula> formulas() { return null; } @Override protected ExportProcessor createExportProcessor() { return null; } } |
第四步:数据界面。
数据集数据界面xxxTableDataPane,继承抽象类AbstractExtendedChartTableDataPane。注意点:extends AbstractExtendedChartTableDataPane<DemoDataConfig>
eg:
声明变量下拉框 x、y、z。
实现抽象方法:fieldLabels (标签名称)&& filedComboBoxes (下拉框数组)&& populate (属性设置到界面组件)&& update(组件值保存到图表属性中)。
Code Block | ||||
---|---|---|---|---|
| ||||
package com.fr.plugin.extended.chart.demo; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.extended.chart.AbstractExtendedChartTableDataPane; /** * Created by shine on 2018/3/24. */ public class DemoTableDataPane extends AbstractExtendedChartTableDataPane<DemoDataConfig>{ private UIComboBox xComboBox; private UIComboBox yComboBox; private UIComboBox zComboBox; @Override protected String[] fieldLabels() { return new String[]{ "X轴", "Y轴", "Z轴" }; } @Override protected UIComboBox[] filedComboBoxes() { if (xComboBox == null) { xComboBox = new UIComboBox(); yComboBox = new UIComboBox(); zComboBox = new UIComboBox(); } return new UIComboBox[]{ xComboBox, yComboBox, zComboBox }; } @Override protected void populate(DemoDataConfig dataConf) { populateField(xComboBox, dataConf.getX()); populateField(yComboBox, dataConf.getY()); populateField(zComboBox, dataConf.getZ()); } @Override protected DemoDataConfig update() { DemoDataConfig dataConfig = new DemoDataConfig(); updateField(xComboBox, dataConfig.getX()); updateField(yComboBox, dataConfig.getY()); updateField(zComboBox, dataConfig.getZ()); return dataConfig; } } |
单元格配置界面xxxReportDataPane,继承抽象类AbstractExtendedChartReportDataPane。处理参考数据集数据配置界面,上栗子,不做累述。
Code Block | ||||
---|---|---|---|---|
| ||||
package com.fr.plugin.extended.chart.demo; import com.fr.design.formula.TinyFormulaPane; import com.fr.extended.chart.AbstractExtendedChartReportDataPane; /** * Created by shine on 2018/3/24. */ public class DemoReportDataPane extends AbstractExtendedChartReportDataPane<DemoDataConfig> { private TinyFormulaPane xPane; private TinyFormulaPane yPane; private TinyFormulaPane zPane; @Override protected String[] fieldLabel() { return new String[]{ "X轴", "Y轴", "Z轴" }; } @Override protected TinyFormulaPane[] formulaPanes() { if (xPane == null) { xPane = new TinyFormulaPane(); yPane = new TinyFormulaPane(); zPane = new TinyFormulaPane(); } return new TinyFormulaPane[]{ xPane, yPane, zPane }; } @Override protected void populate(DemoDataConfig dataConf) { populateField(xPane, dataConf.getX()); populateField(yPane, dataConf.getY()); populateField(zPane, dataConf.getZ()); } @Override protected DemoDataConfig update() { DemoDataConfig dataConfig = new DemoDataConfig(); updateField(xPane, dataConfig.getX()); updateField(yPane, dataConfig.getY()); updateField(zPane, dataConfig.getZ()); return dataConfig; } } |
第五步:
图表插件接口xxx,继承抽象类AbstractExtentChartProvider。
eg:
实现抽象方法:createChart (返回第三步的实例对象xxxChart,后台图表对象)。
Code Block | ||||
---|---|---|---|---|
| ||||
package com.fr.plugin.extended.chart.demo; import com.fr.extended.chart.AbstractChart; import com.fr.extended.chart.AbstractExtentChartProvider; /** * Created by shine on 2018/3/24. */ public class Demo extends AbstractExtentChartProvider { @Override protected AbstractChart createChart() { return new DemoChart(); } } |
图表界面插件接口xxxUI,继承AbstractExtendedChartUIProvider。
eg:实现接口方法:getTableDataSourcePane && getReportDataSourcePane (返回第四步定义的两个数据配置界面的实例对象)&&getIconPath(表单工具栏拖拽图表小图标)。
Code Block | ||||
---|---|---|---|---|
| ||||
package com.fr.plugin.extended.chart.demo; import com.fr.design.mainframe.chart.gui.data.report.AbstractReportDataContentPane; import com.fr.extended.chart.AbstractExtendedChartTableDataPane; import com.fr.extended.chart.AbstractExtendedChartUIProvider; /** * Created by shine on 2018/3/24. */ public class DemoUI extends AbstractExtendedChartUIProvider { @Override protected AbstractExtendedChartTableDataPane getTableDataSourcePane() { return new DemoTableDataPane(); } @Override protected AbstractReportDataContentPane getReportDataSourcePane() { return new DemoReportDataPane(); } @Override public String getIconPath() { return "com/fr/plugin/extended/chart/demo/icon.png"; } } |
第六步:插件相关。
新建plugin.xml文件,内容拷贝下面内容,需要更改的字段有:
id:插件id。com.fr.plugin.demoChart 换成自己的,比如com.fr.plugin.xxxChart。
name:插件名称。DEMO图表 换成自己的。
function-recorder: 插件功能点记录。很重要!!!。class写第三步定义的类的路径即可。同时需要给第三步定义的类添加注解@FunctionRecorder,方法addJSON添加注解@ExecuteFunctionRecord
IndependentChartProvider:图表接口。class写第五步中的xxx路径。plotID为 第三步中图表对象实现的抽象方法getChartID返回的结果。
IndependentChartUIProvider:图表UI接口。class写第五步中的xxxUI路径。plotID为 第三步中图表对象实现的抽象方法getChartID返回的结果。
Code Block | ||||
---|---|---|---|---|
| ||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><plugin> <id>com.fr.plugin.demoChart</id> <name><![CDATA[DEMO图表]]></name> <active>yes</active> <version>1.0.0</version> <env-version>10.0</env-version> <jartime>2018-3-31</jartime> <vendor>finereport.shine</vendor> <description><![CDATA[给开发者参考的图表插件demo]]></description> <change-notes><![CDATA[]]></change-notes> <function-recorder class="com.fr.plugin.demo.DemoChart"/> <extra-chart> <IndependentChartProvider class="com.fr.plugin.demo.Demo" plotID="DEMO_CHART"/> </extra-chart> <extra-chart-designer> <IndependentChartUIProvider class="com.fr.plugin.demo.DemoUI" plotID="DEMO_CHART"/> </extra-chart-designer> </plugin> |
Code Block | ||||
---|---|---|---|---|
| ||||
/** * Created by shine on 2018/3/24. */ @FunctionRecorder public class DemoChart extends AbstractChart<DemoDataConfig>{ @ExecuteFunctionRecord @Override protected void addJSON(DemoDataConfig dataConfig, JSONObject jsonObject, Repository repo) throws JSONException { JSONArray array = JSONFactory.createJSON(JSON.ARRAY); List<Object> xValues = dataConfig.getX().getValues(); List<Object> yValues = dataConfig.getY().getValues(); List<Object> zValues = dataConfig.getZ().getValues(); ......其余省略,主要看@FunctionRecorder && @ExecuteFunctionRecord |
简单的开发到此结束,如果想要联动or超链or导出or公式等,请参考开发进阶