【仅供内部供应商使用,不提供对外解答和培训】

Page tree

【仅供内部供应商使用,不提供对外解答和培训】

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 9 Current »

demo地址:plugin-demochart

前言:

6个步骤,7个文件,千行代码,so easy

要开发一款图表,首先要清楚所用前端库的一些基础接口,此图表类型的数据结构。

以echarts三维柱形图(以下简称DEMO)为例,开发之前要知道:

1.数据结构 

x轴数据y轴数据

z轴数据

.........
........

2.前台图表实例化api:echarts.init(dom),配置项api:instance.setOption(option)。

前期准备:

  • idea中新建一个模块。
  • 在模块src下新建一个文件夹com.fr.plugin,之后在此文件夹下新建各种文件。原因:引擎默认只处理com.fr.plugin(9.0插件)或com.fr(8.0插件)包下的类。
  • 将前端库所用js文件拷贝到com.fr.plugin下。
  • 理解 开发步骤

开发步骤:栗子是echarts三维柱形图

  1. 第一步:
    定义图表所需数据结构xxxDataConfig,继承抽象类AbstractDataConfig。

    eg :

    声明变量x、y、z(保存配置的xyz轴数据的字段名称)。

    实现抽象方法:readXML(模板读取)&& writeXML(模板写入)&& clone && equals && hashCode && dataSetFields(返回由声明的变量组成的数组,用于预览时取数据库取数)。

    其中,供开发者使用的readExtendedField&writeExtendedField方法的第二个参数是字段写入模板对应的key。

    DemoDataConfig
    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())
                   ;
       }
    }
  2. 第二步:
    定义前台图表对象xxxWrapper.js,指定图表库的初始图表接口。
    eg:demoWrapper

    demoWrapper
    demoWrapper = ExtendedChart.extend({
        
        _init:function (dom, option) {
            var chart = echarts.init(dom);
            chart.setOption(option);
            return chart;
        }
        
    });
  3. 第三步:

    定义后台图表对象xxxChart,继承抽象类AbstractChart。注意点:继承的时候别忘了指定泛型DemoDataConfig,即extends AbstractChart<DemoDataConfig>。

    eg:

    实现抽象方法:getChartID (图表标志ID)&& getChartName(图表名称)  &&  demoImagePath (图表选择界面图片路径) && addJSON (预览时生成的json对象,即图表展现所需配置项option && requiredJS (前端图表库js文件)&& wrapperName(前端图表对象,即第二步定义的对象名称)。

    其中,获取某字段对应的数据库数据使用方法dataConfig.getX().getValues())。

    DemoChart
    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;
        }
    
    }
    
  4. 第四步:数据界面。
    数据集数据界面xxxTableDataPane,继承抽象类AbstractExtendedChartTableDataPane。注意点:extends AbstractExtendedChartTableDataPane<DemoDataConfig>

    eg:

    声明变量下拉框 x、y、z。
    实现抽象方法:fieldLabels  (标签名称)&& filedComboBoxes (下拉框数组)&& populate (属性设置到界面组件)&& update(组件值保存到图表属性中)。

    DemoTableDataPane
    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。处理参考数据集数据配置界面,上栗子,不做累述。

    DemoReportDataPane
    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;
        }
    }
    
    
  5. 第五步:
    图表插件接口xxx,继承抽象类AbstractExtentChartProvider。
    eg:
    实现抽象方法:createChart (返回第三步的实例对象xxxChart,后台图表对象)

    Demo
    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(表单工具栏拖拽图表小图标)

    DemoUI
    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";
        }
    }
    
  6. 第六步:插件相关。

    新建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返回的结果。

    plugin.xml
    <?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> 
    function-recorder
    /**
     * 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公式等,请参考开发进阶

  • No labels