FineReport除了内置的图表、新特性图表插件外,还提供了第三方图表开发的API,方便进行个性化、第三方的图表开发。但是第三方图表API接口过于复杂,用户很难快速的实现并使用自己想使用的第三方新图表。
在原有的图表接口基础之上,对接口进行了简化和修改,让用户可以快速的写出第三方图表插件并使用。
package com.fr.chart.fun; import com.fr.chart.chartattr.Chart; import com.fr.stable.fun.Level; /** * Created by eason on 15/4/21. * 图表接口 */ public interface IndependentChartProvider extends Level { String XML_TAG = "IndependentChartProvider"; int CURRENT_API_LEVEL = 3; /** * 图表的国际化的名字的key * * @return 图表国际化的名字的key */ String getChartName(); /** * 该种图表所有的图表类型,比如柱形图就有堆积柱形图,百分比堆积柱形图等等 * * @return 所有的图表类型 */ Chart[] getChartTypes(); /** * 图表在web端展现时需要的JS文件 * * @return JS文件数组 */ String[] getRequiredJS(); /** * JS对象名,该对象一般是一个函数,执行后会在给定的dom中绘制图表 * * @return JS对象名 */ String getWrapperName(); /** * 定义在设计器里展现的图的路径 * * @return 图的路径 */ String getChartImagePath(); /** * 当前接口的API等级,用于判断是否需要升级插件 * * @return API等级 */ int currentAPILevel(); } |
上述接口您不必实现,只需要继承实现了该接口的抽象类:
AbstractIndependentChartProvider4Custom类即可,并实现里面具体的方法,示例如下:
package com.fr.plugins.democharts.pie; import com.fr.chart.chartattr.Chart; import com.fr.chart.fun.impl.AbstractIndependentChartProvider4Custom; public class DemoChartsPie extends AbstractIndependentChartProvider4Custom { public static pieChart[] charts = new pieChart[] { new pieChart(), }; @Override public String getChartName() { return "用户自定义图表"; } @Override public String[] getRequiredJS() { return new String[]{ "/com/fr/plugins/democharts/common/web/echarts.bridge.js" }; } @Override public String getWrapperName() { return "EChartsFactory"; } @Override public Chart[] getChartTypes() { return charts; } @Override public String getChartImagePath() { return "com/fr/plugins/democharts/pie/images/pie256.png"; } @Override public int currentAPILevel() { return CURRENT_API_LEVEL; } } |
package com.fr.design.chart.fun; /** * Created by eason on 14/12/29. * * @since 8.0 * 自定义图表类型设设计界面接口 */ public interface IndependentChartUIProvider extends Level { String XML_TAG = "IndependentChartUIProvider"; int CURRENT_API_LEVEL = 3; /** * 当前接口的API等级,用于判断是否需要升级插件 * * @return API等级 */ int currentAPILevel(); /** * 图表配置面板 * * @return图表配置面板 */ ThirdChartConfigPane getChartConfigPane(String plotID); ......(其他方法不用实现) } |
此接口您不必实现 ,只需要继承实现了该接口的抽象类: AbstractIndependentChartUI4Custom 类即可,并实现相应方法,示例如下:
package com.fr.plugins.democharts.pie; import com.fr.design.chart.fun.impl.AbstractIndependentChartUI4Custom; import com.fr.design.mainframe.chart.ChartEditPane; public class DemoChartsPieUI extends AbstractIndependentChartUI4Custom { @Override public ThirdChartConfigPane getChartConfigPane(String plotID) { return new ChartConfigPane(); } @Override public int currentAPILevel() { return CURRENT_API_LEVEL; } } |
package com.fr.design.mainframe.chart; import com.fr.chart.chartattr.ChartCollection; import com.fr.general.Inter; import javax.swing.*; /** * Created by mengao on 2017/5/16. */ public class ThirdChartConfigPane extends AbstractChartAttrPane { public final static String CHART_STYLE_TITLE = Inter.getLocText("Chart-Style_Name"); @Override public void populate(ChartCollection collection) { } @Override public void update(ChartCollection collection) { } @Override protected JPanel createContentPane() { return new JPanel(); } @Override public String getIconPath() { return "com/fr/design/images/chart/ChartStyle.png"; } @Override public String title4PopupWindow() { return CHART_STYLE_TITLE; } } |
您的图表配置面板需要继承此抽象类,并实现相应的方法,示例如下:
package com.fr.plugins.democharts.commenDataPie; import com.fr.chart.chartattr.ChartCollection; import com.fr.design.mainframe.chart.ThirdChartConfigPane; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /** * Created by mengao on 2017/4/26. * 图表样式面板,需要继承ThirdChartConfigPane * 需要实现方法:populate * 需要实现方法:update */ public class ChartConfigPane extends ThirdChartConfigPane { private ChartCollection chartCollection; JPanel northJpane = new JPanel(); JPanel centerJpane = new JPanel(); JLabel nameJLable = new JLabel("请输入内容:"); JTextField value = new JTextField(); JButton updateButton = new JButton("确定"); public ChartConfigPane() //构造方法 { this.setLayout(new BorderLayout()); northJpane.setLayout(new GridLayout(3, 2)); northJpane.add(nameJLable); northJpane.add(value); this.add(northJpane, BorderLayout.NORTH); centerJpane.add(updateButton, BorderLayout.CENTER); this.add(centerJpane, BorderLayout.CENTER); this.setSize(200, 200); this.setVisible(true); updateButton.addActionListener(new ColorEventListener()); } @Override public void populate(ChartCollection collection) { if (collection.getSelectedChart() instanceof pieChart) { this.chartCollection = collection; pieChart pieChart = (pieChart) collection.getSelectedChart(); value.setText(pieChart.getCustomData()); } } @Override public void update(ChartCollection collection) { if (collection.getSelectedChart() instanceof pieChart) { pieChart pieChart = (pieChart) collection.getSelectedChart(); pieChart.setCustomData(value.getText()); } } // 内部类EventListener,实现ActionListener接口 class ColorEventListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { update(chartCollection); } } } |
package com.fr.chart.chartattr; /** * Created by mengao on 2017/5/3. * 用户使用第三方图表需要继承chart父类 */ public abstract class ThirdChart extends Chart { protected ChartData ChartData; public ChartData getChartData() { return ChartData; } public void setChartData(ChartData chartData) { ChartData = chartData; } protected abstract String getChartID(); public ThirdChart() { ThirdChartPlot thirdChartPlot = new ThirdChartPlot(); thirdChartPlot.setPlotID(getChartID()); this.setPlot(thirdChartPlot); } @Override public BaseChartGlyph createGlyph(ChartData chartData) { ChartGlyph chartGlyph = new ChartGlyph(){ public JSONObject toJSONObject(Repository repo, double width, double height) throws JSONException { return toJSON(repo); } }; setChartData(chartData); chartGlyph.setWrapperName(this.getWrapperName()); chartGlyph.setRequiredJS(this.getRequiredJS()); chartGlyph.setChartImagePath(this.getImagePath()); return chartGlyph; } public abstract JSONObject toJSON (Repository repo) throws JSONException; } |
您的图表配置面板ChartConfig类需要继承此抽象类,并实现相应方法,示例如下:
package com.fr.plugins.democharts.commenDataPie; import com.fr.chart.chartattr.ThirdChart; import com.fr.chart.chartdata.NormalChartData; import com.fr.json.JSONArray; import com.fr.json.JSONException; import com.fr.json.JSONObject; import com.fr.stable.web.Repository; import com.fr.stable.xml.XMLPrintWriter; import com.fr.stable.xml.XMLableReader; /** * Created by mengao on 2017/4/26. * chart类,需要继承ThirdChart * 需要实现方法:getChartID * 需要实现方法:writeXML * 需要实现方法:readXML * 需要实现方法:toJSON */ public class pieChart extends ThirdChart { private String customData= "公共数据配置面板demo"; public String getCustomData() { return customData; } public void setCustomData(String customData) { this.customData = customData; } @Override public void writeXML(XMLPrintWriter xmlPrintWriter) { super.writeXML(xmlPrintWriter); xmlPrintWriter.startTAG("customChartDemo") .attr("custom", getCustomData()) .end(); } @Override public void readXML(XMLableReader xmLableReader) { super.readXML(xmLableReader); if (xmLableReader.isChildNode()) { String tagName = xmLableReader.getTagName(); if(tagName.equals("customChartDemo")) { setCustomData(xmLableReader.getAttrAsString("custom","111")); } } } /** * 读出字符串,然后传到前台 * 注意:需要获取数据配置中的数据,使用getChartData()方法 */ @Override //tojson的时候注意用getChartData()方法获取当前数据集,然后自主拼接成json public JSONObject toJSON(Repository repo) throws JSONException { //用默认的 NormalChartData 进行数据配置 JSONObject jsonObject = new JSONObject(); if (this.getChartData() instanceof NormalChartData) { NormalChartData normalChartData = (NormalChartData) this.getChartData(); JSONArray series = JSONArray.create(); int len = normalChartData.getCategory_array().length;//获取分类数组的长度 int cn = normalChartData.getSeries_array().length;//获取系列数组的长度 for (int c = 0; c < cn; c++) { //对系系列循环 JSONObject wrapper = JSONObject.create(); series.put(wrapper); JSONArray point = JSONArray.create(); wrapper.put("type", "pie"); //将每个系类值给data wrapper.put("data", point); if (c == 1) { int[] radius = {20,110}; String[] center = {"25%", "50%"}; wrapper.put("radius", radius); wrapper.put("center", center); }else{ int[] radius = {30,110}; String[] center = {"75%", "50%"}; wrapper.put("radius", radius); wrapper.put("center", center); } //将系列名给系列 wrapper.put("name", normalChartData.getSeries_array()[c].toString()); for (int i = 0; i < len; i++) { // String name = normalChartData.getCategory_array()[i].toString(); JSONObject item = JSONObject.create(); point.put(item); //将分类名给name item.put("name", name); if (normalChartData.getSeries_value_2D().length > 0) { //将点的值给data item.put("value",normalChartData.getSeries_value_2D()[c][i]); } } } jsonObject.put("series", series); JSONObject title=new JSONObject(); title.put("text",getCustomData()); jsonObject.put("title",title); } return jsonObject; } @Override public String getChartID() { return "CommenDataDemoChartsPie"; } } |
XML关键配置
<extra-core> <JavaScriptFileHandler class="com.fr.plugins.democharts.common.web.EChartsFileLoader"/> </extra-core> <extra-chart> <IndependentChartProvider class="com.fr.plugins.democharts.pie.DemoChartsPie" plotID="DemoChartsPiePlot"/> </extra-chart> <extra-chart-designer> <IndependentChartUIProvider class="com.fr.plugins.democharts.pie.DemoChartsPieUI" plotID="DemoChartsPiePlot"/> </extra-chart-designer> |
您可以自定义图表属性配置面板,更加灵活。
通过配置面板配置好数据后,您可以预览您图表配置好之后的效果,demo展示效果如下:
如果您希望看示例源码,您可以看这里: