【仅供内部供应商使用,不提供对外解答和培训】
10.0工程请移步:基于finekit
FineReport除了内置的图表、新特性图表插件外,还提供了第三方图表开发的API,方便进行个性化、第三方的图表开发。但是第三方图表API接口过于复杂,用户很难快速的实现并使用自己想使用的第三方新图表。
在原有的图表接口基础之上,对接口进行了简化和修改,让用户可以快速的写出第三方图表插件并使用。
下面介绍下重要的接口,和简单的实现(使用公共的数据配置面板,自定义数据面板参考页面底部链接demo):
(1)IndependentChartProvider
...
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();
} |
上述接口您不必实现,只需要继承实现了该接口的抽象类:AbstractIndependentChartsProvider
类即可,并实现里面具体的方法,示例如下:
Code Block | ||||
---|---|---|---|---|
| ||||
package com.fr. |
plugins. |
democharts. |
commenDataPanePie; |
import com.fr.chart.chartattr. |
Chart; |
import com.fr. |
chart.fun. |
impl. |
AbstractIndependentChartsProvider;
/**
* 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[]{
new pieChart(),
};
/**
* 图表的国际化的名字的key
*
* @return 图表国际化的名字的key
*/
@Override
public String getChartName() {
return "用公共的数据配置面板图表";
}
/**
* 图表在web端展现时需要的JS文件
*
* @return JS文件数组
*/
@Override
public String[] getRequiredJS() {
return new String[]{
"/com/fr/plugins/democharts/common/web/echarts.bridge.js"
};
}
/**
* JS对象名,该对象一般是一个函数,执行后会在给定的dom中绘制图表
*
* @return JS对象名
*/
@Override
public String getWrapperName() {
return "EChartsFactory";
}
/**
* 该种图表所有的图表类型,比如柱形图就有堆积柱形图,百分比堆积柱形图等等
*
* @return 所有的图表类型
*/
@Override
public Chart[] getChartTypes() {
return charts;
}
/**
* 定义在设计器里展现的图的路径
*
* @return 图的路径
*/
@Override
public String getChartImagePath() {
return "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 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); |
(1)IndependentChartProvider
......(其他方法不用实现)
} |
此接口您不必实现 ,只需要继承实现了该接口的抽象类: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. |
* |
/**
* 当前接口的API等级,用于判断是否需要升级插件
*
* @return API等级
*/
int currentAPILevel();
/**
* 图表配置面板
*
* @return图表配置面板
*/
public class ThemeGreen extends AbstractThemeVariousProvider { @Override public String name() { return "AcrossGreen" ; } @Override public String text() { return "横向目录" ; } @Override public String coverPath() { return "/com/fr/solution/theme/green/files/cover.png" ; } @Override public String scriptPath() { return "/com/fr/solution/theme/green/files/theme.js" ; } @Override public String stylePath() { return "/com/fr/solution/theme/green/files/style.css" ; } } |
用户使用第三方图表需要继承chart父类
*/
public abstract class Charts <T extends ChartData> extends Chart {
protected T ChartData;
public T getChartData() {
return ChartData;
}
public void setChartData(T chartData) {
ChartData = chartData;
}
protected abstract String getChartID();
public Charts() {
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 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 {
JSONObject jsonObject = JSONObject.create();
jsonObject.put("series", seriesJSONArray())
.put("title", JSONObject.create().put("text", getCustomData()));
return jsonObject;
}
private JSONArray seriesJSONArray() throws JSONException {
NormalChartData normalChartData = getChartData();
int seriesLen = normalChartData.getSeriesCount();
String radius = format.format(1.0 / seriesLen);
//对系列循环
JSONArray series = JSONArray.create();
for (int index = 0; index < seriesLen; index++) {
JSONObject wrapper = JSONObject.create()
.put("type", "pie")
.put("data", pointJSONArray(index)) //将每个系列值给data
.put("name", normalChartData.getSeries_array()[index].toString());//将系列名给系列
if (seriesLen > 1) {
JSONArray center = JSONArray.create()
.put(format.format((float) index / (seriesLen + 1) + 0.20))
.put("55%");
wrapper.put("radius", radius)
.put("center", center);
}
series.put(wrapper);
}
return series;
}
private JSONArray pointJSONArray(int index) throws JSONException {
NormalChartData normalChartData = getChartData();
int categoriesLen = normalChartData.getCategoryLabelCount();
JSONArray point = JSONArray.create();
for (int i = 0; i < categoriesLen; i++) {
JSONObject item = JSONObject.create();
//将分类名给name
String name = normalChartData.getCategory_array()[i].toString();
item.put("name", name);
if (normalChartData.getSeries_value_2D().length > 0) {
//将点的值给data
item.put("value", normalChartData.getSeries_value_2D()[index][i]);
}
point.put(item);
}
return point;
}
@Override
public String getChartID() {
return "ChartsPieWithCommenDataPane";
}
}
|
注意:在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 | ||||
---|---|---|---|---|
|