commit aa5852b3e89ade0fa163f0e65e224d3402c80b54 Author: Ivan.Guo-郭一凡 Date: Wed Jan 31 11:25:56 2024 +0800 0.0.1: 图表DEMO_EK diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fe6b94 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +*.iml +.idea/ +/target/ +/download/ +/webroot/ +.DS_Store +.gradle +build +local.properties +classes/ +transform-classes/ +tomcat.* \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..003865a --- /dev/null +++ b/build.gradle @@ -0,0 +1,123 @@ +apply plugin: 'java' + +[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' + +ext { + /** + * 项目中依赖的jar的路径 + * 1.如果依赖的jar需要打包到zip中,放置在lib根目录下 + * 2.如果依赖的jar仅仅是编译时需要,防止在lib下子目录下即可 + */ + libPath = "$projectDir/../../../webroot/WEB-INF/lib" + + /** + * 是否对插件的class进行加密保护,防止反编译 + */ + guard = true + + def pluginInfo = getPluginInfo() + pluginPre = "fine-plugin" + pluginName = pluginInfo.id + pluginVersion = pluginInfo.version + + outputPath = "$projectDir/../../../webroot/WEB-INF/plugins/plugin-" + pluginName + "-1.0/classes" +} + +group = 'com.fr.plugin' +version = '10.0' +sourceCompatibility = '8' + +sourceSets { + main { + java.outputDir = file(outputPath) + output.resourcesDir = file(outputPath) + } +} + +ant.importBuild("encrypt.xml") +//定义ant变量 +ant.projectDir = projectDir +ant.references["compile.classpath"] = ant.path { + fileset(dir: libPath, includes: '**/*.jar') + fileset(dir: ".", includes: "**/*.jar") +} + +classes.dependsOn('clean') + +task copyFiles(type: Copy, dependsOn: 'classes') { + from outputPath + into "$projectDir/classes" +} + +task preJar(type: Copy, dependsOn: guard ? 'compile_encrypt_javas' : 'compile_plain_javas') { + from "$projectDir/classes" + into "$projectDir/transform-classes" + include "**/*.*" +} +jar.dependsOn("preJar") + +task makeJar(type: Jar, dependsOn: preJar) { + from fileTree(dir: "$projectDir/transform-classes") + baseName pluginPre + appendix pluginName + version pluginVersion + destinationDir = file("$buildDir/libs") + + doLast() { + delete file("$projectDir/classes") + delete file("$projectDir/transform-classes") + } +} + +task copyFile(type: Copy, dependsOn: ["makeJar"]) { + from "$buildDir/libs" + from("$projectDir/lib") { + include "*.jar" + } + from "$projectDir/plugin.xml" + into file("$buildDir/temp/plugin") +} + +task zip(type: Zip, dependsOn: ["copyFile"]) { + from "$buildDir/temp/plugin" + destinationDir file("$buildDir/install") + baseName pluginPre + appendix pluginName + version pluginVersion +} + +//控制build时包含哪些文件,排除哪些文件 +processResources { +// exclude everything +// 用*.css没效果 +// exclude '**/*.css' +// except this file +// include 'xx.xml' +} + +/*读取plugin.xml中的version*/ + +def getPluginInfo() { + def xmlFile = file("plugin.xml") + if (!xmlFile.exists()) { + return ["id": "none", "version": "1.0.0"] + } + def plugin = new XmlParser().parse(xmlFile) + def version = plugin.version[0].text() + def id = plugin.id[0].text() + return ["id": id, "version": version] +} + +repositories { + mavenLocal() + maven { + url = uri('http://mvn.finedevelop.com/repository/maven-public/') + } +} + +dependencies { + //使用本地jar + implementation fileTree(dir: 'lib', include: ['**/*.jar']) + implementation fileTree(dir: libPath, include: ['**/*.jar']) +} + diff --git a/encrypt.xml b/encrypt.xml new file mode 100644 index 0000000..1401cd1 --- /dev/null +++ b/encrypt.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..aa1ad87 --- /dev/null +++ b/plugin.xml @@ -0,0 +1,24 @@ + + + com.finebi.plugin.tptj.ivan.chart.demo.amap + + yes + 0.0.1 + 11.0~11.0 + 2021-08-30 + DEMO + + + ]]> + 6.0~ + com.finebi.plugin.tptj.ivan.chart.demo.amap + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/LifecycleMonitorEK.java b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/LifecycleMonitorEK.java new file mode 100644 index 0000000..7d42ddf --- /dev/null +++ b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/LifecycleMonitorEK.java @@ -0,0 +1,19 @@ +package com.finebi.plugin.tptj.ivan.chart.demo.amap; + +import com.finebi.plugin.tptj.ivan.chart.demo.amap.config.MapHotConfig; +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; + +public class LifecycleMonitorEK extends AbstractPluginLifecycleMonitor { + + + @Override + public void afterRun(PluginContext pluginContext) { + MapHotConfig.getInstance(); + } + + @Override + public void beforeStop(PluginContext pluginContext) { + } + +} diff --git a/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/MapHotComponentProvider.java b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/MapHotComponentProvider.java new file mode 100644 index 0000000..3c3927d --- /dev/null +++ b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/MapHotComponentProvider.java @@ -0,0 +1,71 @@ +package com.finebi.plugin.tptj.ivan.chart.demo.amap; + +import com.finebi.common.context.OperationContext; +import com.finebi.plugin.tptj.ivan.chart.demo.amap.component.MapHotComponent; +import com.finebi.plugin.tptj.ivan.chart.demo.amap.constant.PluginConstantsEK; +import com.finebi.provider.api.component.AbstractCustomComponentProvider; +import com.fr.base.TemplateUtils; +import com.fr.general.IOUtils; +import com.fr.intelli.record.Focus; +import com.fr.intelli.record.Original; +import com.fr.record.analyzer.EnableMetrics; +import com.fr.web.struct.AssembleComponent; + +@EnableMetrics +public class MapHotComponentProvider extends AbstractCustomComponentProvider { + /** + * 图表名称 + */ + @Override + public String getName() { + return PluginConstantsEK.PLUGIN_MAP_NAME; + } + + /** + * @return 图表类型 + */ + @Override + public String getType() { + return PluginConstantsEK.PLUGIN_MAP_TYPE; + } + + /** + * 图标 + * + * @return icon的地址 + */ + @Override + public String getIcon() { + try { + String render = TemplateUtils.render("${fineServletURL}"); + return render + "/resources?path=/com/finebi/plugin/tptj/ivan/chart/demo/amap/icon.png"; + } catch (Exception ignore) { + } + return ""; + } + + /** + * @param context 上下文 + * @return 初始化时的页面元素 + */ + @Focus(id = PluginConstantsEK.PLUGIN_ID, text = PluginConstantsEK.PLUGIN_NAME, source = Original.PLUGIN) + @Override + public String getPreviewPageHTML(OperationContext context) { + return "
"; + } + + @Override + public AssembleComponent previewClient(OperationContext context) { + return MapHotComponent.KEY; + } + + /** + * 配置项,JSON字符串格式 + * + * @return + */ + @Override + public String config() { + return IOUtils.readResourceAsString("com/finebi/plugin/tptj/ivan/chart/demo/amap/config/config.json"); + } +} diff --git a/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/component/AMapComponent.java b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/component/AMapComponent.java new file mode 100644 index 0000000..405d501 --- /dev/null +++ b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/component/AMapComponent.java @@ -0,0 +1,27 @@ +package com.finebi.plugin.tptj.ivan.chart.demo.amap.component; + +import com.fr.web.struct.AssembleComponent; +import com.fr.web.struct.Atom; +import com.fr.web.struct.browser.RequestClient; +import com.fr.web.struct.category.FileType; +import com.fr.web.struct.category.ScriptPath; +import com.fr.web.struct.category.StylePath; + +public class AMapComponent extends AssembleComponent { + public static final AMapComponent KEY = new AMapComponent(); + + @Override + public Atom[] refer() { + return new Atom[0]; + } + + @Override + public ScriptPath script(RequestClient req) { + return ScriptPath.build("com.finebi.plugin.tptj.ivan.chart.demo.amap.component.AmapJSGenerator&time=" + System.currentTimeMillis(), FileType.CLASS); + } + + @Override + public StylePath style(RequestClient req) { + return StylePath.build("/com/finebi/plugin/tptj/ivan/chart/demo/amap/css/lib/demo-center.css"); + } +} diff --git a/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/component/AmapJSGenerator.java b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/component/AmapJSGenerator.java new file mode 100644 index 0000000..7459d3d --- /dev/null +++ b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/component/AmapJSGenerator.java @@ -0,0 +1,35 @@ +package com.finebi.plugin.tptj.ivan.chart.demo.amap.component; + +import com.finebi.plugin.tptj.ivan.chart.demo.amap.config.MapHotConfig; +import com.fr.base.TemplateUtils; +import com.fr.gen.TextGenerator; +import com.fr.general.http.HttpToolbox; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * 平台地址版权信息 + */ +public class AmapJSGenerator implements TextGenerator { + @Override + public String text(HttpServletRequest req, HttpServletResponse res) throws Exception { + return template(); + } + + @Override + public String mimeType() { + return "text/javascript"; + } + + private String template() throws IOException { + Map renderMap = new HashMap(); + renderMap.put("amapSecret", MapHotConfig.getInstance().getSecretKey()); + String amapSecurityJS = TemplateUtils.renderTemplate("/com/finebi/plugin/tptj/ivan/chart/demo/amap/js/lib/amap.js", renderMap); + String amapJS = HttpToolbox.get("https://webapi.amap.com/maps?v=2.0&key=" + MapHotConfig.getInstance().getKey() + "&plugin=AMap.MarkerCluster"); + return amapSecurityJS + amapJS; + } +} \ No newline at end of file diff --git a/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/component/MapHotComponent.java b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/component/MapHotComponent.java new file mode 100644 index 0000000..8bb0b78 --- /dev/null +++ b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/component/MapHotComponent.java @@ -0,0 +1,30 @@ +package com.finebi.plugin.tptj.ivan.chart.demo.amap.component; + +import com.fr.web.struct.AssembleComponent; +import com.fr.web.struct.Atom; +import com.fr.web.struct.browser.RequestClient; +import com.fr.web.struct.category.ScriptPath; +import com.fr.web.struct.category.StylePath; +import com.fr.web.struct.impl.FineUI; + +public class MapHotComponent extends AssembleComponent { + public static final MapHotComponent KEY = new MapHotComponent(); + + @Override + public Atom[] refer() { + return new Atom[]{ + FineUI.KEY, + AMapComponent.KEY + }; + } + + @Override + public ScriptPath script(RequestClient req) { + return ScriptPath.build("/com/finebi/plugin/tptj/ivan/chart/demo/amap/js/chart.js"); + } + + @Override + public StylePath style(RequestClient req) { + return StylePath.EMPTY; + } +} diff --git a/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/config/MapHotConfig.java b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/config/MapHotConfig.java new file mode 100644 index 0000000..c825689 --- /dev/null +++ b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/config/MapHotConfig.java @@ -0,0 +1,63 @@ +package com.finebi.plugin.tptj.ivan.chart.demo.amap.config; + +import com.finebi.plugin.tptj.ivan.chart.demo.amap.constant.PluginConstantsEK; +import com.fr.config.ConfigContext; +import com.fr.config.DefaultConfiguration; +import com.fr.config.Identifier; +import com.fr.config.Status; +import com.fr.config.Visualization; +import com.fr.config.holder.Conf; +import com.fr.config.holder.factory.Holders; + +/** + * @author Ivan.Guo + * @version 11.0 + */ +@Visualization(category = "Plugin-DEMO_CONF") +public class MapHotConfig extends DefaultConfiguration { + private static volatile MapHotConfig instance = null; + + @Override + public String getNameSpace() { + return PluginConstantsEK.PLUGIN_ID + this.getClass().getSimpleName(); + } + + public static MapHotConfig getInstance() { + if (instance == null) { + instance = ConfigContext.getConfigInstance(MapHotConfig.class); + } + return instance; + } + + @Identifier( + value = "key", + name = "Plugin-DEMO_CONF_KEY", + description = "Plugin-DEMO_CONF_KEY_DES", + status = Status.SHOW + ) + private Conf key = Holders.simple(""); + + @Identifier( + value = "secretKey", + name = "Plugin-DEMO_CONF_SECRET", + description = "Plugin-DEMO_CONF_SECRET_DES", + status = Status.SHOW + ) + private Conf secretKey = Holders.simple(""); + + public String getKey() { + return key.get(); + } + + public void setKey(String key) { + this.key.set(key); + } + + public String getSecretKey() { + return secretKey.get(); + } + + public void setSecretKey(String secretKey) { + this.secretKey.set(secretKey); + } +} diff --git a/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/constant/PluginConstantsEK.java b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/constant/PluginConstantsEK.java new file mode 100644 index 0000000..9ad354e --- /dev/null +++ b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/constant/PluginConstantsEK.java @@ -0,0 +1,19 @@ +package com.finebi.plugin.tptj.ivan.chart.demo.amap.constant; + + +/** + * @author Ivan.Guo + * @version 11.0 + * Created by Ivan.Guo on 2022/11/14 + * 全局常量 + */ +public class PluginConstantsEK { + + public static final String PLUGIN_ID = "com.finebi.plugin.tptj.ivan.chart.demo.amap"; + public static final String PLUGIN_JSD = "JSD-DEMO"; + public static final String PLUGIN_NAME = "图表DEMO_EK"; + public static final String PLUGIN_MAP_TYPE = "amap_demo"; + public static final String PLUGIN_MAP_NAME = "图表DEMO_EK"; + + +} \ No newline at end of file diff --git a/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/locale/CustomDatasetLocale.java b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/locale/CustomDatasetLocale.java new file mode 100644 index 0000000..3c0ce3f --- /dev/null +++ b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/locale/CustomDatasetLocale.java @@ -0,0 +1,11 @@ +package com.finebi.plugin.tptj.ivan.chart.demo.amap.locale; + +import com.fr.stable.fun.impl.AbstractLocaleFinder; + +public class CustomDatasetLocale extends AbstractLocaleFinder { + @Override + public String find() { + return "com/finebi/plugin/tptj/ivan/chart/demo/amap/locale/plugin"; + } + +} diff --git a/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/utils/LogUtil.java b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/utils/LogUtil.java new file mode 100644 index 0000000..7917eba --- /dev/null +++ b/src/main/java/com/finebi/plugin/tptj/ivan/chart/demo/amap/utils/LogUtil.java @@ -0,0 +1,64 @@ +package com.finebi.plugin.tptj.ivan.chart.demo.amap.utils; + +import com.finebi.plugin.tptj.ivan.chart.demo.amap.constant.PluginConstantsEK; +import com.fr.log.FineLoggerFactory; +import com.fr.log.FineLoggerProvider; + +/** + * @author Ivan.Guo + * @version 11.0 + * Created by Ivan.Guo on 2022/11/15 + */ +public class LogUtil { + private static final FineLoggerProvider LOGGER = FineLoggerFactory.getLogger(); + private static final String LOG_PREFIX = PluginConstantsEK.PLUGIN_JSD + "-" + PluginConstantsEK.PLUGIN_NAME + ": "; + + public static void debug(String msg) { + LOGGER.debug("DEBUG-" + LOG_PREFIX + msg); + } + + public static void debug(String msg, Object... objs) { + LOGGER.debug("DEBUG-" + LOG_PREFIX + msg, objs); + } + + public static void info(String msg) { + LOGGER.info("INFO-" + LOG_PREFIX + msg); + } + + public static void info(String msg, Object... objs) { + LOGGER.info("INFO-" + LOG_PREFIX + msg, objs); + } + + public static void warn(String msg) { + LOGGER.warn("WARN-" + LOG_PREFIX + msg); + } + + public static void warn(String msg, Object... objs) { + LOGGER.warn("WARN-" + LOG_PREFIX + msg, objs); + } + + public static void warn(String msg, Throwable ex) { + LOGGER.warn("WARN-" + LOG_PREFIX + msg, ex); + } + + public static void warn(Throwable ex, String msg, Object... objs) { + LOGGER.warn(ex, "WARN-" + LOG_PREFIX + msg, objs); + } + + public static void error(String msg) { + LOGGER.error("ERROR-" + LOG_PREFIX + msg); + } + + public static void error(String msg, Object... objs) { + LOGGER.error("ERROR-" + LOG_PREFIX + msg, objs); + } + + public static void error(String msg, Throwable ex) { + LOGGER.error("ERROR-" + LOG_PREFIX + msg, ex); + } + + public static void error(Throwable ex, String msg, Object... objs) { + LOGGER.error(ex, "ERROR-" + LOG_PREFIX + msg, objs); + } + +} diff --git a/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/config/config.json b/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/config/config.json new file mode 100644 index 0000000..63b6a9d --- /dev/null +++ b/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/config/config.json @@ -0,0 +1,99 @@ +{ + "dataRegions": [ + { + "name": "lat", + "text": "Plugin-DEMO_WEB_LAT" + }, + { + "name": "lng", + "text": "Plugin-DEMO_WEB_LNG" + } + ], + "attrRegions": [ + { + "name": "细粒度", + "text": "Plugin-DEMO_WEB_FG", + "multiFields": false, + "settings": [] + } + ], + "chartStyles": [ + { + "name": "mapProp", + "text": "Plugin-DEMO_WEB_MAP_ATTRIBUTE", + "multiFields": true, + "settings": [ + { + "name": "centerLng", + "text": "Plugin-DEMO_WEB_CENTER_LNG", + "type": "Input", + "defaultValue": "102.3716" + }, + { + "name": "centerLat", + "text": "Plugin-DEMO_WEB_CENTER_LAT", + "type": "Input", + "defaultValue": "36.6808" + }, + { + "name": "defaultZoom", + "text": "Plugin-DEMO_WEB_DEFAULT_ZOOM", + "type": "Input", + "defaultValue": "4" + }, + { + "name": "style", + "text": "Plugin-DEMO_WEB_STYLE", + "type": "Select", + "defaultValue": "normal", + "items": [ + { + "text": "标准", + "value": "normal" + }, + { + "text": "幻影黑", + "value": "dark" + }, + { + "text": "月光银", + "value": "light" + }, + { + "text": "远山黛", + "value": "whitesmoke" + }, + { + "text": "草色青", + "value": "fresh" + }, + { + "text": "雅士灰", + "value": "grey" + }, + { + "text": "涂鸦", + "value": "graffiti" + }, + { + "text": "马卡龙", + "value": "macaron" + }, + { + "text": "靛青蓝", + "value": "blue" + }, + { + "text": "极夜蓝", + "value": "darkblue" + }, + { + "text": "酱籽", + "value": "wine" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/css/lib/demo-center.css b/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/css/lib/demo-center.css new file mode 100644 index 0000000..59a9e8b --- /dev/null +++ b/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/css/lib/demo-center.css @@ -0,0 +1,431 @@ +html { + font-size: 12px; +} +.amap-copyright{ + box-sizing: content-box +} +* { + box-sizing: border-box +} +.input-textarea{ + color:grey; + height:8em; + overflow:auto; + border-radius:0.4rem; + border:1px solid #ced4da; + margin-bottom:1rem; +} +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + line-height: 1.5; + font-weight: 300; + color: #111213; +} + +hr { + margin: 0.5rem 0; + box-sizing: content-box; + height: 0; + overflow: visible; + border: 0; + border-top: 1px solid rgba(0, 0, 0, .1) +} + +p { + margin-top: 0; + margin-bottom: 0; +} + +label { + display: inline-block; + margin-bottom: 0.4rem; +} + +label, .btn { + margin-left: 0; + font-size: 1rem; +} + +button, input, select { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; + overflow: visible; + text-transform: none +} + +[type=button]::-moz-focus-inner, [type=reset]::-moz-focus-inner, [type=submit]::-moz-focus-inner, button::-moz-focus-inner { + padding: 0; + border-style: none; +} + +input[type=checkbox], input[type=radio] { + box-sizing: border-box; + padding: 0; + -webkit-box-sizing: border-box; + box-sizing: border-box; + padding: 0; + margin: 0 0.5rem 0 0; +} + +h4 { + font-family: inherit; + line-height: 1.8; + font-weight: 300; + color: inherit; + font-size: 1.1rem; + margin-top: 0; + margin-bottom: .5rem +} + +.btn { + display: inline-block; + font-weight: 400; + text-align: center; + white-space: nowrap; + vertical-align: middle; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + border: 1px solid transparent; + transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; + background-color: transparent; + background-image: none; + color: #25A5F7; + border-color: #25A5F7; + padding: .25rem .5rem; + line-height: 1.5; + border-radius: 1rem; + -webkit-appearance: button; + cursor:pointer; +} + +.btn:hover { + color: #fff; + background-color: #25A5F7; + border-color: #25A5F7 +} + +.btn:hover { + text-decoration: none +} + +.input-item { + position: relative; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -ms-flex-align: center; + align-items: center; + width: 100%; + height: 3rem; +} + +.input-item:last-child { + margin-bottom: 0; +} + +.input-item>select, .input-item>input[type=text], .input-item>input[type=date] { + position: relative; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + width: 1%; + margin-bottom: 0; +} + +.input-item>select:not(:last-child), .input-item>input[type=text]:not(:last-child), .input-item>input[type=date]:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.input-item>select:not(:first-child), .input-item>input[type=text]:not(:first-child), .input-item>input[type=date]:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.input-item-prepend { + margin-right: -1px; +} + +.input-item-text, input[type=text],input[type=date], select { + height: calc(2.2rem + 2px); +} + +.input-item-text { + width: 6rem; + text-align: justify; + padding: 0.4rem 0.7rem; + display: inline-block; + text-justify: distribute-all-lines; + /*ie6-8*/ + text-align-last: justify; + /* ie9*/ + -moz-text-align-last: justify; + /*ff*/ + -webkit-text-align-last: justify; + /*chrome 20+*/ + -ms-flex-align: center; + align-items: center; + margin-bottom: 0; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #495057; + text-align: center; + white-space: nowrap; + background-color: #e9ecef; + border: 1px solid #ced4da; + border-radius: .25rem; + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} + +.input-item-text input[type=checkbox], .input-item-text input[type=radio] { + margin-top: 0 +} + +.input-card { + display: flex; + flex-direction: column; + min-width: 0; + word-wrap: break-word; + background-color: #fff; + background-clip: border-box; + border-radius: .25rem; + border-width: 0; + border-radius: 0.4rem; + box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5); + position: fixed; + bottom: 1rem; + right: 1rem; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + padding: 0.75rem 1.25rem; +} + +.input-text { + line-height: 2rem; + margin-right: 2rem; +} + +.info hr { + margin-right: 0; + margin-left: 0; + border-top-color: grey; +} + +.info { + padding: .75rem 1.25rem; + margin-bottom: 1rem; + border-radius: .25rem; + position: fixed; + top: 1rem; + background-color: white; + width: auto; + min-width: 22rem; + border-width: 0; + right: 1rem; + box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5); +} + +.code { + left: 1.5rem; + right: 1.5rem; + top: 1.5rem; + bottom: 1.5rem; + overflow: auto; + margin-bottom: 0rem; +} + +.code .btn { + top: 1rem; + position: absolute; + right: 1rem; +} + +.code .result { + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 0.5rem; + padding: 1rem; + bottom: 1rem; + position: absolute; + top: 5.5rem; + right: 1rem; + left: 1rem; + overflow: auto; +} + +.code .status { + color: #80adff; + display: inline-block; + font-size: 14px; +} + +.code h4 { + display: inline-block; + max-width: 20rem; + margin-right: 1rem; + margin-bottom: 1rem; +} + +select, input[type=text], input[type=date] { + display: inline-block; + width: 100%; + padding: .375rem 1.75rem .375rem .75rem; + line-height: 1.5; + color: #495057; + vertical-align: middle; + background: #fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center; + background-size: 8px 10px; + border: 1px solid #ced4da; + border-radius: .25rem; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none +} + +input[type=text],input[type=date] { + background: #fff; + padding: .375rem .75rem; +} + +select:focus, input[type=text]:focus, input[type=date]:focus { + border-color: #80bdff; + outline: 0; + box-shadow: 0 0 0 .1rem rgba(128, 189, 255, .1) +} + +.btn:focus { + outline: 0; + box-shadow: none; +} + +select:focus::-ms-value, input[type=text]:focus::-ms-value,input[type=date]:focus::-ms-value { + color: #495057; + background-color: #fff +} + + +/* native toastr */ +.native-toast { + position: fixed; + background-color: rgba(50, 50, 50, .8); + border-radius: 33px; + color: white; + left: 50%; + text-align: center; + padding: 6px 12px; + opacity: 0; + z-index: 99999; + transition: transform .25s, opacity .25s, top .25s; + box-sizing: border-box; +} + +.native-toast-bottom { + bottom: 50px; + -ms-transform: translateX(-50%) translateY(50px); + transform: translateX(-50%) translateY(50px) +} + +.native-toast-bottom.native-toast-shown { + opacity: 1; + -ms-transform: translateX(-50%) translateY(0); + transform: translateX(-50%) translateY(0); +} + +.native-toast-bottom.native-toast-edge { + bottom: 0; +} + +.native-toast-top { + top: 50px; + -ms-transform: translateX(-50%) translateY(-50px); + transform: translateX(-50%) translateY(-50px) +} + +.native-toast-top.native-toast-shown { + opacity: 1; + -ms-transform: translateX(-50%) translateY(0); + transform: translateX(-50%) translateY(0); +} + +.native-toast-top.native-toast-edge { + top: 0; +} + +.native-toast-center { + top: 0; + -ms-transform: translateX(-50%) translateY(-50px); + transform: translateX(-50%) translateY(-50px) +} + +.native-toast-center.native-toast-shown { + opacity: 1; + top: 50%; + -ms-transform: translateX(-50%) translateY(-50%); + transform: translateX(-50%) translateY(-50%); +} + +.native-toast-edge { + border-radius: 0; + width: 100%; + text-align: left; +} + +@media screen and (min-width: 40rem) { +.native-toast:not(.native-toast-edge) { + max-width: 18rem; + } +} + +/* + max-width does not seem to work in small screen? +*/ + +/*@media screen and (max-width: 768px) { + .native-toast:not(.native-toast-edge) { + max-width: 400px; + } +} + +@media screen and (max-width: 468px) { + .native-toast:not(.native-toast-edge) { + max-width: 300px; + } +}*/ + +/* types */ + +.native-toast-error { + background-color: #d92727; + color: white; +} + +.native-toast-success { + background-color: #62a465; + color: white; +} + +.native-toast-warning { + background-color: #fdaf17; + color: white; +} + +.native-toast-info { + background-color: #5060ba; + color: white; +} + +[class^="native-toast-icon-"] { + vertical-align: middle; + margin-right: 8px +} + +[class^="native-toast-icon-"] svg { + width: 16px; + height: 16px; +} \ No newline at end of file diff --git a/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/icon.png b/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/icon.png new file mode 100644 index 0000000..b3d3eea Binary files /dev/null and b/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/icon.png differ diff --git a/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/js/chart.js b/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/js/chart.js new file mode 100644 index 0000000..65dc4ec --- /dev/null +++ b/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/js/chart.js @@ -0,0 +1,143 @@ +(function ($) { + function render( + data, // 数据 + config, // 配置 + saveSessionCallback, + closeSessionCallBack, + extensionCallBack + ) { + debugger; + + // 查找初始化时的dom对象 + const dom = document.getElementById("amap-demo-container"); + + // 一定要设置 宽高 不然图表渲染不出来 + dom.style.width = document.body.clientWidth + "px"; + dom.style.height = document.body.clientHeight + "px"; + + // 获取配置项 + const mapAttribute = config["chartStyle"]["mapProp"]["value"]; + + // 地图组件初始化 + const map = new AMap.Map(dom, { + resizeEnable: true, + center: [mapAttribute[0], mapAttribute[1]], + zoom: mapAttribute[2], + }); + + // 地图设置样式 + const styleName = "amap://styles/" + mapAttribute[3]; + map.setMapStyle(styleName); + + // 获取全部的经纬度点数据 + const points = _getAllPoint(data.dataMapping, data.dataModels[0]); + + if (points != null) { + // 创建聚合点图层 + var pointCluster = new AMap.MarkerCluster(map, points, { + gridSize: 60, // 设置网格像素大小 + renderClusterMarker: _renderCarClusterMarker, // 自定义聚合点样式 + renderMarker: _renderMarker, // 自定义非聚合点样式 + }); + } + + + window.addEventListener("resize", function () { + dom.style.width = document.body.clientWidth + "px"; + dom.style.height = document.body.clientHeight + "px"; + }); + } + + /** + * 自定义聚合点样式 + * @param context + * @private + */ + function _renderCarClusterMarker(context) { + let count = context.count; + let factor = context.count / count; + const div = document.createElement('div'); + const Hue = 180 - factor * 180; + let bgColor; + if (context.count < 10) { + bgColor = 'hsla(108,100%,40%,1)'; + } else if (context.count < 100) { + bgColor = 'hsl(201,100%,40%)'; + } else if (context.count < 1000) { + bgColor = 'hsla(36,100%,50%,1)'; + } else if (context.count < 10000) { + bgColor = 'hsla(0,100%,60%,1)'; + } else { + bgColor = 'hsla(0,100%,40%,1)'; + } + const fontColor = 'hsla(' + Hue + ',100%,90%,1)'; + const borderColor = bgColor; + const shadowColor = 'hsla(' + Hue + ',100%,90%,1)'; + div.style.backgroundColor = bgColor; + const size = Math.round(30 + Math.pow(context.count / count, 1 / 5) * 20); + div.style.width = div.style.height = size + 'px'; + div.style.border = 'solid 1px ' + borderColor; + div.style.borderRadius = size / 2 + 'px'; + div.style.boxShadow = '0 0 5px ' + shadowColor; + div.innerHTML = context.count; + div.style.lineHeight = size + 'px'; + div.style.color = fontColor; + div.style.fontSize = '14px'; + div.style.textAlign = 'center'; + context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2)); + context.marker.setContent(div) + } + + /** + * 自定义非聚合点样式 + * @param context + * @private + */ + function _renderMarker(context) { + var content = '
'; + var offset = new AMap.Pixel(-9, -9); + context.marker.setContent(content) + context.marker.setOffset(offset) + } + + /** + * + * @param dataMapping + * @param dataModel + * @returns {*[]} + * @private + */ + function _getAllPoint(dataMapping, dataModel) { + let lngId = dataMapping['lat']; + let latId = dataMapping['lng']; + + let files = dataModel.fields; + let rowCount = dataModel.rowCount + const colData = dataModel.colData; + + let lngIndex; + let latIndex; + + // demo这里没有考虑多维度多指标的情况,具体根据实际情况进行修改 + files.forEach((item, index) => { + if (lngId.indexOf(item.id) >= 0) { + lngIndex = index; + } + if (latId.indexOf(item.id) >= 0) { + latIndex = index; + } + }) + + var points = []; + for (let i = 0; i < rowCount; i++) { + points.push({ + lnglat: [colData[lngIndex][i], colData[latIndex][i]], + }) + } + + return points; + } + + // 注册渲染方法 + new BIPlugin().init(render); +})(jQuery); diff --git a/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/js/lib/amap.js b/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/js/lib/amap.js new file mode 100644 index 0000000..54d4495 --- /dev/null +++ b/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/js/lib/amap.js @@ -0,0 +1,5 @@ +!(function () { + window._AMapSecurityConfig = { + securityJsCode: "${amapSecret}", + }; +})(); \ No newline at end of file diff --git a/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/locale/plugin.properties b/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/locale/plugin.properties new file mode 100644 index 0000000..55d5498 --- /dev/null +++ b/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/locale/plugin.properties @@ -0,0 +1,15 @@ +Plugin-DEMO_= +Plugin-DEMO_CONF=\u56FE\u8868DEMO_EK\u914D\u7F6E +Plugin-DEMO_CONF_KEY=\u9AD8\u5FB7\u5730\u56FE\u5BC6\u94A5 +Plugin-DEMO_CONF_KEY_DES=\u9AD8\u5FB7\u5730\u56FE\u5BC6\u94A5 +Plugin-DEMO_CONF_SECRET=\u9AD8\u5FB7\u5730\u56FE\u5B89\u5168\u5BC6\u94A5 +Plugin-DEMO_CONF_SECRET_DES=\u9AD8\u5FB7\u5730\u56FE\u5B89\u5168\u5BC6\u94A5 +Plugin-DEMO_WEB_LNG_LAT=\u7ECF\u7EAC\u5EA6 +Plugin-DEMO_WEB_LAT=\u7EAC\u5EA6 +Plugin-DEMO_WEB_LNG=\u7ECF\u5EA6 +Plugin-DEMO_WEB_FG=\u7EC6\u7C92\u5EA6 +Plugin-DEMO_WEB_MAP_ATTRIBUTE=\u5730\u56FE\u5C5E\u6027 +Plugin-DEMO_WEB_CENTER_LNG=\u4E2D\u5FC3\u7ECF\u5EA6 +Plugin-DEMO_WEB_CENTER_LAT=\u4E2D\u5FC3\u7EAC\u5EA6 +Plugin-DEMO_WEB_DEFAULT_ZOOM=\u9ED8\u8BA4\u7F29\u653E\u7EA7\u522B +Plugin-DEMO_WEB_STYLE=\u6837\u5F0F \ No newline at end of file diff --git a/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/locale/plugin_zh_CN.properties b/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/locale/plugin_zh_CN.properties new file mode 100644 index 0000000..c211ad0 --- /dev/null +++ b/src/main/resources/com/finebi/plugin/tptj/ivan/chart/demo/amap/locale/plugin_zh_CN.properties @@ -0,0 +1,16 @@ +Plugin-DEMO_= +Plugin-DEMO_CONF=\u56FE\u8868DEMO_EK\u914D\u7F6E +Plugin-DEMO_CONF_KEY=\u9AD8\u5FB7\u5730\u56FE\u5BC6\u94A5 +Plugin-DEMO_CONF_KEY_DES=\u9AD8\u5FB7\u5730\u56FE\u5BC6\u94A5 +Plugin-DEMO_CONF_SECRET=\u9AD8\u5FB7\u5730\u56FE\u5B89\u5168\u5BC6\u94A5 +Plugin-DEMO_CONF_SECRET_DES=\u9AD8\u5FB7\u5730\u56FE\u5B89\u5168\u5BC6\u94A5 +Plugin-DEMO_WEB_LNG_LAT=\u7ECF\u7EAC\u5EA6 +Plugin-DEMO_WEB_LAT=\u7EAC\u5EA6 +Plugin-DEMO_WEB_LNG=\u7ECF\u5EA6 +Plugin-DEMO_WEB_FG=\u7EC6\u7C92\u5EA6 +Plugin-DEMO_WEB_TYPE=\u7C7B\u578B +Plugin-DEMO_WEB_MAP_ATTRIBUTE=\u5730\u56FE\u5C5E\u6027 +Plugin-DEMO_WEB_CENTER_LNG=\u4E2D\u5FC3\u7ECF\u5EA6 +Plugin-DEMO_WEB_CENTER_LAT=\u4E2D\u5FC3\u7EAC\u5EA6 +Plugin-DEMO_WEB_DEFAULT_ZOOM=\u9ED8\u8BA4\u7F29\u653E\u7EA7\u522B +Plugin-DEMO_WEB_STYLE=\u6837\u5F0F \ No newline at end of file diff --git a/说明/fine-plugin-com.finebi.plugin.tptj.ivan.chart.demo.amap-0.0.1.zip b/说明/fine-plugin-com.finebi.plugin.tptj.ivan.chart.demo.amap-0.0.1.zip new file mode 100644 index 0000000..3cc0c8d Binary files /dev/null and b/说明/fine-plugin-com.finebi.plugin.tptj.ivan.chart.demo.amap-0.0.1.zip differ diff --git a/说明/聚合数据.xlsx b/说明/聚合数据.xlsx new file mode 100644 index 0000000..f55f234 Binary files /dev/null and b/说明/聚合数据.xlsx differ