【仅供内部供应商使用,不提供对外解答和培训】
10.0工程请移步:基于finekit
FineReport除了内置的图表、新特性图表插件外,还提供了第三方图表开发的API,方便进行个性化、第三方的图表开发。但是第三方图表API接口过于复杂,用户很难快速的实现并使用自己想使用的第三方新图表。
...
在原有的图表接口基础之上,对接口进行了简化和修改,让用户可以快速的写出第三方图表插件并使用。
下面介绍下重要的接口,和简单的实现(使用公共的数据配置面板,自定义数据面板参考页面底部链接demo):
...
Code Block | ||||
---|---|---|---|---|
| ||||
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类即可,并实现里面具体的方法,示例如下:上述接口您不必实现,只需要继承实现了该接口的抽象类:AbstractIndependentChartsProvider
类即可,并实现里面具体的方法,示例如下:
Code Block | ||||
---|---|---|---|---|
| ||||
package com.fr.plugins.democharts.piecommenDataPanePie; import com.fr.chart.chartattr.Chart; import com.fr.chart.fun.impl.AbstractIndependentChartProvider4CustomAbstractIndependentChartsProvider; public class DemoChartsPie extends AbstractIndependentChartProvider4Custom { public static pieChart[] charts = new pieChart[] { new pieChart(), }; @Override/** * Created by mengo on 16/5/11. * 自定义图表,需要继承AbstractIndependentChartsProvider * 需要实现方法:getChartName * 需要实现方法:getWrapperName * 需要实现方法:getChartTypes * 需要实现方法:getChartImagePath * 需要实现方法:getRequiredJS * 需要实现方法:currentAPILevel */ public class DemoChartsPie extends AbstractIndependentChartsProvider { public static pieChart[] charts = new pieChart[]{ public String getChartName() { return "用户自定义图表";new pieChart(), }; @Override/** public String[] getRequiredJS() {* 图表的国际化的名字的key return new String[]{* * @return 图表国际化的名字的key "/com/fr/plugins/democharts/common/web/echarts.bridge.js"*/ }; } @Override public String getWrapperNamegetChartName() { return "EChartsFactory用公共的数据配置面板图表"; } @Override/** public Chart[] getChartTypes() { * 图表在web端展现时需要的JS文件 * * return@return charts;JS文件数组 }*/ @Override public String[] getChartImagePathgetRequiredJS() { return new String[]{ "/com/fr/plugins/democharts/piecommon/imagesweb/pie256echarts.bridge.pngjs"; } @Override public int currentAPILevel() { }; return CURRENT_API_LEVEL; } } |
title | IndependentChartUIProvider |
---|---|
collapse | true |
/** * |
JS对象名,该对象一般是一个函数,执行后会在给定的dom中绘制图表 |
|
|
|
* * |
@return |
JS对象名 |
|
*/ |
@Override public String getWrapperName() { return "EChartsFactory"; } /** |
* 该种图表所有的图表类型,比如柱形图就有堆积柱形图,百分比堆积柱形图等等 * * @return |
所有的图表类型 */ |
此接口您不必实现 ,只需要继承实现了该接口的抽象类: AbstractIndependentChartUI4Custom 类即可,并实现相应方法,示例如下:
title | DemoChartsPieUI extends AbstractIndependentChartUI4Custom |
---|---|
collapse | true |
@Override public Chart[] getChartTypes() { return charts; } /** * 定义在设计器里展现的图的路径 * * @return 图的路径 */ @Override public |
String |
getChartImagePath() { return |
title | ThirdChartConfigPane |
---|---|
collapse | true |
"com/fr/plugins/democharts/customDataPanePie/images/pie256.png"; } /** * @return 插件的API等级 */ @Override public int currentAPILevel() { return CURRENT_API_LEVEL; } } |
Code Block | ||||
---|---|---|---|---|
| ||||
package com.fr.design.chart.fun; /** * Created @Override by eason on 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; } } |
您的图表配置面板需要继承此抽象类,并实现相应的方法,示例如下:
title | ChartConfigPane extends ThirdChartConfigPane |
---|---|
collapse | true |
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);
......(其他方法不用实现)
} |
此接口您不必实现 ,只需要继承实现了该接口的抽象类:AbstractIndependentChartsUI类即可,并实现相应方法,示例如下:
Code Block | ||||
---|---|---|---|---|
| ||||
package com.fr.plugins.democharts. |
commenDataPanePie; import com.fr.design.chart. |
fun.impl. |
AbstractIndependentChartsUI; import com.fr.design.mainframe.chart. |
ChartsConfigPane; |
/** * Created by mengao on 2017/4/26. * |
自定义图表类型设设计界面,需要继承AbstractIndependentChartsUI * |
需要实现方法:getChartConfigPane * |
需要实现方法:currentAPILevel */ public class |
DemoChartsPieUI extends |
AbstractIndependentChartsUI { |
/** |
|
* |
@param plotID |
|
* |
@return |
图表样式面板,用户需要实现 |
*/ |
|
|
@Override |
public |
ChartsConfigPane |
getChartConfigPane(String plotID) { |
|
return new |
ChartConfigPane( |
);
|
} |
|
/ |
** |
* @return 插件的API等级 |
*/ |
@Override public int |
currentAPILevel( |
) |
{ |
return CURRENT_API_LEVEL; |
}
}
|
注意:如果您想使用自己的数据配置面板,需要覆写getTableDataSourcePane(Plot plot, ChartDataPane parent)和getReportDataSourcePane(Plot plot, ChartDataPane parent)方法,并自定义数据编辑面板、chartData、Definition等类,具体参考底部链接中的plugins-demoChart插件。
Code Block | ||||
---|---|---|---|---|
| ||||
package com.fr.design.mainframe.chart; import com.fr.chart.chartattr.ChartCollection; import com.fr.chart.chartattr.Charts; import com.fr.general.Inter; import com.fr.stable.StableUtils; import javax.swing.*; /** * Created by mengao on 2017/5/16. */ public abstract class ChartsConfigPane <T extends Charts> extends AbstractChartAttrPane { public final static String CHART_STYLE_TITLE = Inter.getLocText("Chart-Style_Name"); public abstract Class<? extends Charts> accptType(); @Override public void populate(ChartCollection collection) { if (StableUtils.classInstanceOf(collection.getSelectedChart().getClass() |
,accptType())) { |
populate(collection, (T)collection.getSelectedChart()); } |
} protected abstract void populate(ChartCollection collection, |
T selectedChart); @Override public void update(ChartCollection collection) { if (StableUtils.classInstanceOf(collection.getSelectedChart() |
.getClass(),accptType())) { |
update(collection, (T)collection.getSelectedChart()); } |
} protected abstract void update(ChartCollection collection, T |
selectedChart); |
@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; } |
} |
|
Code Block | |
---|---|
|
| |||
package com.fr.plugins. |
democharts. |
commenDataPanePie; |
import com.fr.chart.chartattr.ChartCollection; import com.fr.design.mainframe.chart.ChartsConfigPane; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /** * Created by mengao on 2017/ |
4/ |
26. * |
图表样式面板,需要继承ChartsConfigPane * 需要实现方法:populate * 需要实现方法:update */ public |
class |
ChartConfigPane extends |
ChartsConfigPane<PieChart> { private JPanel |
northJpane = |
new |
JPanel(); |
private JPanel centerJpane = |
new |
JPanel() |
; private JLabel nameJLable = |
new JLabel("请输入内容:"); private JButton updateButton = |
new JButton("确定"); protected JTextField value = new JTextField(); protected ChartCollection chartCollection; 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()); } // 内部类EventListener,实现ActionListener接口 class ColorEventListener implements ActionListener { @Override |
|
|
public |
void |
actionPerformed(ActionEvent e) { |
update(chartCollection, (T)chartCollection.getSelectedChart());
}
}
@Override
public Class<? extends Charts> accptType() {
return PieChart.class;
}
@Override
protected void populate(ChartCollection collection, PieChart selectedChart) {
this.chartCollection=collection;
value.setText(selectedChart.getCustomData());
}
@Override
protected void update(ChartCollection collection, PieChart selectedChart) {
selectedChart.setCustomData(value.getText());
}
}
|
Code Block | ||||
---|---|---|---|---|
| ||||
package com.fr.chart.chartattr; import com.fr.base.chart.BaseChartGlyph; import com.fr.base.chart.chartdata.ChartData; import com.fr.chart.chartglyph.ChartGlyph; import com.fr.json.JSONException; import com.fr.json.JSONObject; import com.fr.stable.web.Repository; /** * Created by mengao on 2017/5/3. * 用户使用第三方图表需要继承chart父类 */ public abstract class Charts <T extends ChartData> extends Chart { protected T ChartData; public T getChartData() { chartGlyph.setWrapperName(this.getWrapperName())return ChartData; } public void chartGlyph.setRequiredJS(this.getRequiredJS()); setChartData(T chartData) { ChartData chartGlyph.setChartImagePath(this.getImagePath())= chartData; } return chartGlyphprotected abstract String getChartID(); } public Charts() { public abstract JSONObject toJSON (Repository repo) throws JSONException; } |
您的图表配置面板ChartConfig类需要继承此抽象类,并实现相应方法,示例如下:
title | pieChart extends ThirdChart |
---|---|
collapse | true |
ChartsPlot chartsPlot = new ChartsPlot(); chartsPlot.setPlotID(getChartID()); this.setPlot(chartsPlot); } @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((T)chartData); |
chartGlyph.setWrapperName(this.getWrapperName()); chartGlyph.setRequiredJS(this.getRequiredJS()); chartGlyph. |
setChartImagePath(this.getImagePath()); |
return chartGlyph; } |
public |
abstract JSONObject toJSON (Repository |
repo) |
throws JSONException;
}
|
您的图表配置面板ChartConfig类需要继承此抽象类,并实现相应方法,示例如下:
Code Block | ||||
---|---|---|---|---|
| ||||
package com.fr.plugins.democharts.commonpie; import com.fr.chart.chartattr.Charts; 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; import java.text.DecimalFormat; import java.text.NumberFormat; /** * Created by mengao on 2017/4/26. * chart类,需要继承Charts * 需要实现方法:getChartID * 需要实现方法:writeXML * 需要实现方法:readXML * 需要实现方法:toJSON */ public class PieChart extends Charts<NormalChartData> { private String customData = "公共数据配置面板demo"; private static final NumberFormat format = new DecimalFormat("##%"); public JSONObjectString toJSONgetCustomData(Repository repo) throws JSONException { //用默认的 NormalChartData 进行数据配置return customData; } JSONObjectpublic jsonObjectvoid = new JSONObject();setCustomData(String customData) { if (this.getChartData()customData instanceof NormalChartData) {= customData; } @Override NormalChartDatapublic normalChartDatavoid = writeXML(NormalChartData) this.getChartData(); XMLPrintWriter xmlPrintWriter) { super.writeXML(xmlPrintWriter); JSONArray series = JSONArrayxmlPrintWriter.createstartTAG("customChartDemo"); int len = normalChartData.getCategory_array().length;//获取分类数组的长度 .attr("custom", getCustomData()) int cn = normalChartData.getSeries_arrayend().length;//获取系列数组的长度; } @Override public void readXML(XMLableReader xmLableReader) { for (int c = 0; c < cn; c++) { super.readXML(xmLableReader); if (xmLableReader.isChildNode()) { //对系系列循环 String tagName = xmLableReader.getTagName(); JSONObject wrapper =if JSONObject(tagName.createequals();"customChartDemo")) { seriessetCustomData(xmLableReader.put(wrappergetAttrAsString("custom", "111")); } JSONArray} point = JSONArray.create(); } /** * 读出字符串,然后传到前台 * wrapper.put("type", "pie");注意:需要获取数据配置中的数据,使用getChartData()方法 */ @Override //tojson的时候注意用getChartData()方法获取当前数据集,然后自主拼接成json public JSONObject toJSON(Repository repo) throws JSONException //将每个系类值给data{ JSONObject jsonObject = JSONObject.create(); wrapper jsonObject.put("dataseries", pointseriesJSONArray()); if (c == 1) {.put("title", JSONObject.create().put("text", getCustomData())); return jsonObject; } private JSONArray int[] radius = {20,110};seriesJSONArray() throws JSONException { String[] center = {"25%", "50%"}; NormalChartData normalChartData = getChartData(); int seriesLen = normalChartData.getSeriesCount(); String radius = wrapperformat.put("radius", radiusformat(1.0 / seriesLen); //对系列循环 JSONArray series = wrapperJSONArray.put("center", centercreate(); for (int index = 0; index < }else{ seriesLen; index++) { int[]JSONObject radiuswrapper = {30,110};JSONObject.create() String[] center = {"75%.put("type", "50%pie"};) wrapper.put("radiusdata", radius);pointJSONArray(index)) //将每个系列值给data wrapper.put("centername", center);normalChartData.getSeries_array()[index].toString());//将系列名给系列 if (seriesLen > 1) }{ //将系列名给系列 JSONArray center = JSONArray.create() wrapper.put("name", normalChartData.getSeries_array()[c].toString()); for (int i = 0; i < len; i++) {.put(format.format((float) index / (seriesLen + 1) + 0.20)) // .put("55%"); String name = normalChartData.getCategory_array()[i].toString();wrapper.put("radius", radius) JSONObject item = JSONObject.create(.put("center", center); } point series.put(itemwrapper); } return series; //将分类名给name} private JSONArray pointJSONArray(int index) throws JSONException { NormalChartData item.put("name", namenormalChartData = getChartData(); int categoriesLen = normalChartData.getCategoryLabelCount(); JSONArray if (normalChartData.getSeries_value_2D().length > 0) { point = JSONArray.create(); for (int i = 0; i < categoriesLen; i++) { JSONObject item //将点的值给data = JSONObject.create(); //将分类名给name item.put("value",normalChartData.getSeries_value_2D()[c][i]String name = normalChartData.getCategory_array()[i].toString(); item.put("name", name); } if (normalChartData.getSeries_value_2D().length > 0) { } //将点的值给data } jsonObjectitem.put("seriesvalue", series); JSONObject title=new JSONObject( normalChartData.getSeries_value_2D()[index][i]); title.put("text",getCustomData());} jsonObjectpoint.put("title",titleitem); } return jsonObjectpoint; } @Override public String getChartID() { return "CommenDataDemoChartsPieChartsPieWithCommenDataPane"; } } |
注意:在toJSON中您如果需要获取数据配置中的数据,请使用getChartData()方法获取chartData对象,并将其转化为您需要的格式,具体参考demo
XML关键配置
Code Block | ||
---|---|---|
| ||
<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展示效果如下:(左:默认数据配置面板demo,右:自定义数据配置面板demo)
如果您希望看示例源码,您可以看这里:
demo工程:
View file | ||||
---|---|---|---|---|
|