diff --git a/docs/claim.md b/docs/claim.md index 3934d83..1fa8ccb 100644 --- a/docs/claim.md +++ b/docs/claim.md @@ -58,7 +58,7 @@ com.fr.design.dialog.DialogActionAdapter ## 图表类别 -com.fr.chart.ChartWebPara +com.fr.extended.chart.HyperLinkPara com.fr.chartx.data.field.ColumnField diff --git a/src/main/java/com/fanruan/api/design/chart/DefaultOtherPane.java b/src/main/java/com/fanruan/api/design/chart/DefaultOtherPane.java new file mode 100644 index 0000000..940b9f1 --- /dev/null +++ b/src/main/java/com/fanruan/api/design/chart/DefaultOtherPane.java @@ -0,0 +1,146 @@ +package com.fanruan.api.design.chart; + +import com.fanruan.api.report.chart.BaseChartWithData; +import com.fr.design.chartx.component.HyperLinkPane; +import com.fr.design.gui.ibutton.UIButtonGroup; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.ispinner.UISpinner; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.js.NameJavaScriptGroup; +import com.fr.van.chart.designer.TableLayout4VanChartHelper; + +import javax.swing.JPanel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.util.Arrays; +import java.awt.BorderLayout; +import java.awt.Component; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2019-10-09 + * 默认包含超链和自动刷新的面板 + */ +public class DefaultOtherPane extends BaseOtherPane { + + private HyperLinkPane hyperLinkPane; + + private UIButtonGroup refreshEnabled; + private UISpinner autoRefreshTime; + private JPanel contentPane; + + /** + * 根据图表对象属性还原面板选项 + */ + @Override + public void populate(BaseChartWithData ob) { + if (ob.getNameJavaScriptGroup() == null) { + ob.setNameJavaScriptGroup(new NameJavaScriptGroup()); + } + if (hyperLinkPane != null) { + hyperLinkPane.populate(ob.getNameJavaScriptGroup(), ob.getHyperLinkEditorMap()); + } + if (contentPane != null) { + autoRefreshTime.setValue(ob.getAutoRefreshTime()); + refreshEnabled.setSelectedIndex(ob.isRefreshEnabled() ? 0 : 1); + } + checkRefreshEnable(); + } + + /** + * 根据面板选项更新图表对象属性 + */ + @Override + public void update(BaseChartWithData ob) { + if (hyperLinkPane != null) { + hyperLinkPane.update(ob.getNameJavaScriptGroup()); + } + if (contentPane != null) { + ob.setAutoRefreshTime(autoRefreshTime.getValue()); + ob.setRefreshEnabled(refreshEnabled.getSelectedIndex() == 0); + } + } + + /** + * 创建包含自动刷新和超链选择的面板 + * + * @return 面板 + */ + @Override + protected JPanel createContentPane() { + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double e = TableLayout4VanChartHelper.EDIT_AREA_WIDTH; + double[] columnSize = {f, e}; + Component[][] components = new Component[][]{ + new Component[]{createRefreshPane(), null}, + new Component[]{createHyperlinkPane(), null} + }; + double[] rowSize = new double[components.length]; + Arrays.fill(rowSize, p); + + return TableLayoutHelper.createTableLayoutPane(components, rowSize, columnSize); + } + + /** + * 默认的标题名称 + * + * @return 标题名称 + */ + @Override + public String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Chart_Animation_Special"); + } + + private void checkRefreshEnable() { + contentPane.setVisible(refreshEnabled.getSelectedIndex() == 0); + } + + /** + * 创建自动刷新面板 + * + * @return 自动刷新面板 + */ + protected JPanel createRefreshPane() { + + refreshEnabled = new UIButtonGroup(new String[]{Toolkit.i18nText("Fine-Design_Chart_Open"), Toolkit.i18nText("Fine-Design_Chart_Close")}); + refreshEnabled.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + checkRefreshEnable(); + } + }); + + autoRefreshTime = new UISpinner(0, Integer.MAX_VALUE, 1, 0); + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] columnSize = {p, f, 20}; + double[] rowSize = {p}; + + Component[][] components = new Component[][]{ + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Time_Interval")), autoRefreshTime, new UILabel(Toolkit.i18nText("Fine-Design_Chart_Time_Seconds"))}, + }; + contentPane = TableLayout4VanChartHelper.createGapTableLayoutPane(components, rowSize, columnSize); + + JPanel panel = new JPanel(new BorderLayout(0, 4)); + panel.add(refreshEnabled, BorderLayout.NORTH); + panel.add(contentPane, BorderLayout.CENTER); + + JPanel gapPane = TableLayout4VanChartHelper.createGapTableLayoutPane(Toolkit.i18nText("Fine-Design_Chart_Auto_Refresh"), panel); + + return TableLayout4VanChartHelper.createExpandablePaneWithTitle(Toolkit.i18nText("Fine-Design_Chart_Use_Refresh"), gapPane); + } + + /** + * 创建超链面板 + * + * @return 超链面板 + */ + protected JPanel createHyperlinkPane() { + hyperLinkPane = new HyperLinkPane(); + return TableLayout4VanChartHelper.createExpandablePaneWithTitle(Toolkit.i18nText("Fine-Design_Report_M_Insert_Hyperlink"), hyperLinkPane); + } +} diff --git a/src/main/java/com/fanruan/api/report/chart/BaseChartWithData.java b/src/main/java/com/fanruan/api/report/chart/BaseChartWithData.java index fcedd04..e6bc3a2 100644 --- a/src/main/java/com/fanruan/api/report/chart/BaseChartWithData.java +++ b/src/main/java/com/fanruan/api/report/chart/BaseChartWithData.java @@ -2,10 +2,13 @@ package com.fanruan.api.report.chart; import com.fanruan.api.report.chart.field.BaseColumnFieldCollection; import com.fr.base.chart.cross.FormulaProcessor; -import com.fr.chart.ChartWebPara; +import com.fr.chart.ChartWebParaProvider; import com.fr.chart.impl.AbstractChartWithData; +import com.fr.extended.chart.HyperLinkPara; import com.fr.js.NameJavaScriptGroup; import com.fr.json.JSONObject; +import com.fr.stable.xml.XMLPrintWriter; +import com.fr.stable.xml.XMLableReader; import java.awt.Image; @@ -40,17 +43,55 @@ public abstract class BaseChartWithData extends AbstractChartWithData { * @return 图片 */ @Override - public Image toImage(int width, int height, int resolution, ChartWebPara chartWebPara) { - return super.toImage(width, height, resolution, chartWebPara); + protected Image designImage(int width, int height, int resolution, ChartWebParaProvider chartWebPara) { + return super.designImage(width, height, resolution, chartWebPara); } /** - * 生成图表预览的options + * 导出的图片,默认返回空白图片 + * + * @return 图片 + */ + @Override + protected Image exportImage(int width, int height, int resolution, ChartWebParaProvider chartWebPara) { + return super.exportImage(width, height, resolution, chartWebPara); + } + + /** + * 生成图表预览的options,子类先调用父类该方法生成JSON后添加自己的属性 * * @return JSON对象 */ @Override - public abstract JSONObject createAttributeConfig(ChartWebPara chartWebPara); + public JSONObject createAttributeConfig(ChartWebParaProvider chartWebPara) { + return super.createAttributeConfig(chartWebPara); + } + + /** + * 返回新增特殊的超链中参数下拉可选项 + * + * @return 超链参数对象集合 + */ + @Override + protected HyperLinkPara[] hyperLinkParas() { + return super.hyperLinkParas(); + } + + /** + * 读取xml中的基本数据类型属性,子类覆写该方法需要先调用父类的该方法 + */ + @Override + protected void readAttr(XMLableReader xmLableReader) { + super.readAttr(xmLableReader); + } + + /** + * 将基本数据类型属性写入xml,子类覆写该方法需要先调用父类的该方法 + */ + @Override + protected void writeAttr(XMLPrintWriter xmlPrintWriter) { + super.writeAttr(xmlPrintWriter); + } /** * 定义图表的ID,与plugin.xml中的chartID对应 diff --git a/src/main/java/com/fanruan/api/script/FineCanvas.java b/src/main/java/com/fanruan/api/script/FineCanvas.java new file mode 100644 index 0000000..4cd1e20 --- /dev/null +++ b/src/main/java/com/fanruan/api/script/FineCanvas.java @@ -0,0 +1,110 @@ +package com.fanruan.api.script; + +import com.fr.general.IOUtils; +import com.fr.graph.g2d.canvas.CanvasPainter; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; + +import java.io.InputStream; +import java.awt.image.BufferedImage; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2019-09-30 + */ +public class FineCanvas { + + CanvasPainter.Builder canvasBuilder; + + /** + * 构造函数,创建js引擎并加载绘制使用的通用适配js文件 + */ + public FineCanvas() throws Exception { + canvasBuilder = CanvasPainter.newDefaultBuilder(); + } + + /** + * 构造函数,创建js引擎并加载绘制使用的通用适配js文件,并加载指定的js文件 + * + * @param filePath 指定的js文件路径的集合,使用相对路径即可。 + */ + public FineCanvas(String... filePath) throws Exception { + canvasBuilder = CanvasPainter.newDefaultBuilder(); + loadAndExecute(filePath); + } + + /** + * 将js语句加载到缓存区。 + * + * @param text js语句集合 + */ + public void loadText(String... text) { + canvasBuilder.loadText(text); + } + + /** + * 立即执行js语句 + * + * @param text js语句集合 + */ + public void loadTextAndExecute(String... text) throws Exception { + canvasBuilder.loadTextAndExecute(text); + } + + /** + * 加载js文件 + * + * @param filePath 指定的js文件路径的集合,使用相对路径即可。 + */ + public void loadAndExecute(String... filePath) throws Exception { + for (String path : filePath) { + String content = readFileBody(path); + canvasBuilder.build().execute(content); + } + } + + /** + * 执行缓存区的js语句,并返回canvas中的BufferedImage对象 + * + * @return 绘制完成的图片对象 + */ + public BufferedImage paint() throws Exception { + CanvasPainter painter = canvasBuilder.build(); + try { + return painter.paint(); + } catch (Exception ex) { + throw ex; + } finally { + painter.close(); + } + } + + /** + * 执行指定的js方法,并返回canvas中的BufferedImage对象 + * + * @return 绘制完成的图片对象 + */ + public BufferedImage paint(String functionName, Object... parameters) throws Exception { + CanvasPainter painter = canvasBuilder.build(); + try { + return painter.paint(functionName, parameters); + } catch (Exception ex) { + throw ex; + } finally { + painter.close(); + } + } + + private String readFileBody(String filePath) { + InputStream in = FineCanvas.class.getResourceAsStream(filePath); + String script = StringUtils.EMPTY; + try { + script = IOUtils.inputStream2String(in); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return script; + } + +}