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

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 10 Next »

请注意,阅读此文档需要您拥有基础的JAVA和JS知识,您有必要亲自尝试使用FineReport的图表功能,如果您在阅读中出现疑问,可以比对零基础文档

 

图表插件介绍

图表插件是用于丰富帆软的图表类型,旨在帮助用户更好地做数据可视化展现。开发者需要通过帆软开放的接口,参考下面的demo和文档来制作插件。

安装FineReport和搭建插件开发环境

我们建议您在上手开发插件之前,先体验一下插件使用的具体情形,搭建环境的具体步骤在其他文档中写的很具体,这里不去赘述。

demo目录结构

plugins-calendarchart
  --src
    --com.fr.plugins.calendarchart
      --custompie
        --ChartConfigPane.java
        --DemoChartsPie.java
        --demoChartsPieUI.java
        --PieChart.java
      --images
        --pie256.png
      --web
        --echarts.bridge.js
        --echarts.loader.js
        --echarts.min.js
        --EChartsFileLoader.java
  --build.xml
  --plugin.xml
  --plugins-calendarchart.iml

1.custompie

此目录下存放第三方图表插件接口调用类,需要实现相应的方法。

2.images

此目录下存放插件的相关图片,供报表表单页面展示。

3.web

此目录下存放前台js,供图表预览时展示。

4.build.xml

该文件用于插件包构建,请参考文档

5.plugin.xml

该文件包含插件的接入点描述信息,请参考文档

6.plugins-calendarchart.iml

IEDA项目的配置。

接口介绍

接口详细介绍,请参阅文档

我的demo

1.demo开发概述

1) 开发过程:一共三个部分

数据抽取部分:设计器右侧的图表属性表-数据部分

前端展示样式:设计器右侧的图表属性表-样式部分

前端展示的js:图表预览展示的页面

2) 按照自己开发的类修改plugin.xml以及build.xml,请上面提到的文档。

2.下面详细讲一下开发过程吧

1) 默认数据集和图表属性+ js,除了js,我们需要继承以下三个类,并实现里面具体的方法:

Charts类:图表类

AbstractIndependentChartsProvider类:插件图表接口

AbstractJavaScriptFileHandler类:插件图表界面接口

第一步,继承Charts类,实现以下几个方法:

toJSON():通过getChartData(),这里有你需要的数据,并转成json,前端会拿到这个json

getChartID():返回的应该和plugin.xml配置中的相同

writeXML和readXML可以考虑不自定义实现,如需自定义实现下面会有介绍

public class YourCharts extends Charts {
    @Override

    public JSONObject toJSON(Repository repo) throws JSONException {

        //通过getChartData()得到你需要的数据,把这些数据转成自定义的json格式,前端会收到这个json
        return null;
    }

    @Override

    public String getChartID() {

        //这里返回值与plugin.xml配置中的plotID一致。
        return yourPlotID;
    }

    @Override

    public void writeXML(XMLPrintWriter xmlPrintWriter) {

        //图表属性配置信息会被存储在xml中,不考虑自定义图表样式,不用实现。
    }

    @Override

    public void readXML(XMLableReader xmLableReader) {

        //和writeXML一样,这里是读配置信息
	}
}

第二步,继承AbstractIndependentChartsProvider类,实现以下几个方法:

getChartName():返回插件的名字,供报表页面新增图表使用

getChartTypes():返回上一步创建的存储图表数据的类

getRequiredJS():你的图表交互的js

getWrapperName():JS对象名,该对象一般是一个函数,执行后会在给定的dom中绘制图表

getChartImagePath():图表的图标,文件存在images下面

currentAPILevel():当前接口的API等级用于判断是否要升级插件

public class YourChartsProvider extends AbstractIndependentChartsProvider {

    @Override

    public String getChartName() {

        return "你的图表插件名字";
    }

    @Override

    public Chart[] getChartTypes() {

        //返回上一步创建的存储图表数据的类,即YourCharts
        return new YourCharts[]{new YourCharts()};
    }

    @Override

    public String[] getRequiredJS() {

        //你的图表交互的js,所依赖的其他js文件,比如echarts.js在另外地方配置,后边会提到
        return new String[]{           
			"/com/fr/plugins/xxx/web/echarts.bridge.js"
        };
    }

    @Override

    public String getWrapperName() {

        //JS对象名,该对象一般是一个函数,执行后会在给定的dom中绘制图表 
        return "EChartsFactory";
    }

    @Override

    public String getChartImagePath() {

        //你的图表插件的图标
        return "com/fr/plugins/xxx/images/xxx.png";
    }

    @Override 

    public int currentAPILevel() {

        //当前接口的API等级用于判断是否要升级插件
        return CURRENT_API_LEVEL;
    }
}

第三步,继承AbstractJavaScriptFileHandler类,实现以下几个方法:

pathsForFiles():如果你用的是Echarts的话,返回echarts的js,例如:

return new String[]{
	"/com/fr/plugin/parallelchart/web/echarts.loader.js",
	"/com/fr/plugin/parallelchart/web/echarts.min.js"
};

如果你用的是g2的话,返回g2的js,例如:

return new String[]{
	"/com/fr/plugin/parallelchart/web/g2.js"
};

encode():编码格式

public class EchartFileLoader extends AbstractJavaScriptFileHandler {

    @Override


    public String[] pathsForFiles() {
		
		//加载js
        return new String[]{
            "/com/fr/plugin/parallelchart/web/echarts.loader.js",
			"/com/fr/plugin/parallelchart/web/echarts.min.js"
        };
    }

    @Override

    public String encode() {

        return EncodeConstants.ENCODING_UTF_8;
    }

2) 自定义图表属性+默认数据集 +js 

在上边的例子基础上,加上一个自定义属性的配置,以配置图表的标题为例。

第一步,继承ChartsConfigPane的YourChartsConfigPane,通过这个类的populate和update方法与Charts类做交互,实现以下几个方法:

YourChartsConfigPane():构建图表属性面板,以自定义标题为例

Populate():把YourCharts中图表配置的数据在属性面板上展示

Update():把面板上的数据存到YourCharts中去

public class YourChartsConfigPane extends ChartsConfigPane<YourCharts> {


	private ChartCollection chartCollection;
    private UITextField value;

    public YourChartsConfigPane() {

		//这里构建了一个图表属性面板,创建了一个文本框,用来让用户输入将展示的图表的标题
		this.setLayout(new BorderLayout());
		northJpane.setLayout(new GridLayout(4, 1, 10,10));
		northJpane.add(nameUILabel);
		northJpane.add(value);
		northJpane.add(demoUILabel);
		northJpane.add(customTextArea);
		this.add(northJpane, BorderLayout.NORTH);
		this.add(centerJpane, BorderLayout.CENTER);
		this.setSize(200, 200);
		this.setVisible(true);

		//初始化所有组件后必须调用此方法为他们添加监听。注意:此方法必须实现,不实现无法监听更新保存!!
		initAllListeners();
    }

	//这个类是点击确认按钮时的监听
    class ColorEventListener implements ActionListener {


        @Override

        public void actionPerformed(ActionEvent e) {
          
			update(chartCollection);
        }
    }

    @Override

    //返回的类是类定义中的泛型类
    public Class<?extends Charts> accptType() {

        return YourCharts.class;
    }

    @Override

    public void populate(ChartCollection collection, YourCharts selectedChart) {

        chartCollection = collection;

        //把YourCharts中图表配置的数据这边的面板上
    	value.setText(selectedChart.getCustomData());
    }

    @Override


    public void update(ChartCollection collection, YourCharts selectedChart) {

        //把面板上的数据存到YourCharts中去
        selectedChart.setCustomData(value.getText());
    }
}
 

第二步,继承Charts的YourCharts,默认图表属性时,writeXML和readXML不需要实现,自定义图表属性需要实现这两个方法。

writeXML():把数据存到XML中,具体过程参考demo或者查看文档

readXML():从xml中取数据,具体过程参考demo或者查看文档

public class YourCharts extends Charts {

	//这个类之前只需要修改writeXML和readXML两个方法 
    @Override

    public void writeXML(XMLPrintWriter xmlPrintWriter) {

    	//这里将数据存在XML中
       	xmlPrintWriter.startTAG(TAG_NAME)
			.attr("custom", getCustomData())
            .end();
        writeDefinition(xmlPrintWriter);
    }

    @Override

    public void readXML(XMLableReader xmLableReader) {

        //这里将XML中的数据读出来
        if (xmLableReader.isChildNode()) {


            String tagName = xmLableReader.getTagName();
            if (tagName.equals("customChartDemo")) {
            	setCustomData(xmLableReader.getAttrAsString("custom","111"));
            }
        }
    }
}

3) 自定义图表属性+自定义数据集+js

在上边基础上,新加3个类,分别是:定义数据集的面板类,数据集的定义和查询类,查询结果存储类。

第一步,继承AbstractTableDataContentPane,定义数据集的面板类,就是你的插件用户在这个面板上配置他们想要的数据,比如要用哪个表的哪一列数据,里边需要实现的接口作用,如下:

populateBean:同步配置到面板。
updateBean:将面板配置更新
checkBoxUse:检查某些box是否可用
clearAllBoxList:清空设置box的设置
refreshBoxListWithSelectTableData:刷新box

public class TableDataContentPane extends AbstractTableDataContentPane {

    private UIComboBox dateComboBox;

    private UIComboBox valueComboBox;

    public TableDataContentPane(ChartDataPane parent) {

        dateComboBox = new UIComboBox();
        valueComboBox = new UIComboBox();
		dateComboBox.setPreferredSize(new Dimension(100, 20));
  		valueComboBox.setPreferredSize(new Dimension(100, 20));

        Component[][] components = new Component[][]{


            new Component[]{new UILabel("名称", SwingConstants.RIGHT), dateComboBox},

            new Component[]{new UILabel("值", SwingConstants.RIGHT), valueComboBox}};

        	double p = TableLayout.PREFERRED;
	        double[] columnSize = {p, p};
	        double[] rowSize = {p, p, p};


        JPanel panel = TableLayoutHelper.createTableLayoutPane(components, rowSize, columnSize);

        setLayout(new BorderLayout());

        add(panel, BorderLayout.CENTER);
    }

    @Override

    public void populateBean(ChartCollection collection) {
      
		DefaultTableDataDefinition configuration = (DefaultTableDataDefinition)
		collection.getSelectedChart().getFilterDefinition();

        if (configuration == null) return;

        combineCustomEditValue(dateComboBox, configuration.getDate());
        combineCustomEditValue(valueComboBox, configuration.getValue());
    }

    @Override

    public void updateBean(ChartCollection ob) {

    	DefaultTableDataDefinition myConfiguration = new DefaultTableDataDefinition();
        Object wname = dateComboBox.getSelectedItem();
        Object wvalue = valueComboBox.getSelectedItem();

        if (wname != null) {
        	myConfiguration.setDate(wname.toString());
        }

        if (wvalue != null) {
        	myConfiguration.setValue(wvalue.toString());
        }

        ob.getSelectedChart().setFilterDefinition(myConfiguration);
    }

    @Override

    public void clearAllBoxList() {
    
		dateComboBox.removeAll();
        valueComboBox.removeAll();
    }

    @Override

    protected void refreshBoxListWithSelectTableData(List columnNameList) {
       
		refreshBoxItems(dateComboBox, columnNameList);
		refreshBoxItems(valueComboBox, columnNameList)
    }
}
  • No labels