From 28afe57339031607e364e54b669305041666d59f Mon Sep 17 00:00:00 2001 From: wuduoyi Date: Thu, 29 Oct 2020 19:52:25 +0800 Subject: [PATCH] =?UTF-8?q?ECharts=20=E7=BC=96=E8=BE=91=E5=99=A8=E5=88=9D?= =?UTF-8?q?=E5=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .travis.yml | 2 +- examples/components/Echarts.tsx | 178 +++++++++++++++++++++ examples/components/Example.tsx | 8 + examples/components/Form/StyleBuilder.jsx | 1 + examples/components/echarts/Common.tsx | 86 ++++++++++ examples/components/echarts/Title.tsx | 80 +++++++++ examples/components/echarts/TitleStyle.tsx | 76 +++++++++ examples/style.scss | 8 + 8 files changed, 438 insertions(+), 1 deletion(-) create mode 100644 examples/components/Echarts.tsx create mode 100644 examples/components/echarts/Common.tsx create mode 100644 examples/components/echarts/Title.tsx create mode 100644 examples/components/echarts/TitleStyle.tsx diff --git a/.travis.yml b/.travis.yml index 9f5044948..79c20b6ce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ language: node_js node_js: - - 10 + - 12 script: sh deploy-gh-pages.sh diff --git a/examples/components/Echarts.tsx b/examples/components/Echarts.tsx new file mode 100644 index 000000000..eb586eb5c --- /dev/null +++ b/examples/components/Echarts.tsx @@ -0,0 +1,178 @@ +/** + * @file 基于 amis 实现 ECharts 图表可视化编辑 + */ + +import title from './echarts/Title'; +import titleStyle from './echarts/TitleStyle'; + +const titleControl = { + type: 'tabs', + tabs: [ + { + title: '内容', + controls: [title] + }, + { + title: '样式', + controls: [titleStyle] + } + ] +}; + +export default { + $schema: 'https://houtai.baidu.com/v2/schemas/page.json#', + title: 'ECharts 编辑器', + data: { + config: { + title: { + text: '未来一周气温变化', + subtext: '纯属虚构' + }, + tooltip: { + trigger: 'axis' + }, + legend: { + data: ['最高气温', '最低气温'] + }, + toolbox: { + show: true, + feature: { + mark: { + show: true + }, + dataView: { + show: true, + readOnly: true + }, + magicType: { + show: false, + type: ['line', 'bar'] + }, + restore: { + show: true + }, + saveAsImage: { + show: true + } + } + }, + calculable: true, + xAxis: [ + { + type: 'category', + boundaryGap: false, + data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] + } + ], + yAxis: [ + { + type: 'value', + name: '°C' + } + ], + series: [ + { + name: '最高气温', + type: 'line', + data: [11, 11, 15, 13, 12, 13, 10] + }, + { + name: '最低气温', + type: 'line', + data: [1, -2, 2, 5, 3, 2, 0] + } + ] + } + }, + body: [ + { + type: 'form', + title: '', + controls: [ + { + type: 'grid', + columns: [ + { + md: 7, + controls: [ + { + type: 'chart', + source: '${config}' + } + ] + }, + { + md: 5, + controls: [ + { + name: 'config', + type: 'combo', + label: '', + noBorder: true, + multiLine: true, + controls: [ + { + type: 'tabs', + mode: 'vertical', + className: 'echarts-editor', + tabs: [ + // { + // title: '基础', + // tab: 'Content 2' + // }, + { + title: '标题', + controls: [titleControl] + }, + { + title: '视区', + controls: [ + { + name: 'config.text', + type: 'text', + label: 'text' + } + ] + }, + { + title: 'X 轴', + tab: 'Content 2' + }, + { + title: 'Y 轴', + tab: 'Content 2' + }, + { + title: '图例', + tab: 'Content 2' + }, + { + title: '提示', + tab: 'Content 2' + }, + { + title: '工具', + tab: 'Content 2' + }, + { + title: '标题', + tab: 'Content 2' + } + ] + } + ] + } + ] + } + ] + }, + { + type: 'editor', + name: 'config', + language: 'json', + source: '${config}' + } + ] + } + ] +}; diff --git a/examples/components/Example.tsx b/examples/components/Example.tsx index 9176d571a..8c751b33c 100644 --- a/examples/components/Example.tsx +++ b/examples/components/Example.tsx @@ -59,6 +59,7 @@ import OptionsPageSchema from './Linkage/Options'; import OptionsLocalPageSchema from './Linkage/OptionsLocal'; import WizardSchema from './Wizard'; import ChartSchema from './Chart'; +import EchartsEditorSchema from './Echarts'; import HorizontalSchema from './Horizontal'; import VideoSchema from './Video'; import AudioSchema from './Audio'; @@ -481,6 +482,13 @@ export const examples = [ path: '/examples/chart', component: makeSchemaRenderer(ChartSchema) }, + + { + label: 'Echarts 编辑器', + icon: 'fa fa-bar-chart', + path: '/examples/echarts', + component: makeSchemaRenderer(EchartsEditorSchema) + }, { label: '轮播图', icon: 'fa fa-pause', diff --git a/examples/components/Form/StyleBuilder.jsx b/examples/components/Form/StyleBuilder.jsx index 7c5fac33d..4ee9742b8 100644 --- a/examples/components/Form/StyleBuilder.jsx +++ b/examples/components/Form/StyleBuilder.jsx @@ -262,6 +262,7 @@ export default { label: '属性', type: 'select', searchable: true, + unique: true, options: propertiesOptions }, ...valueTypeControls, diff --git a/examples/components/echarts/Common.tsx b/examples/components/echarts/Common.tsx new file mode 100644 index 000000000..ae3dc13c1 --- /dev/null +++ b/examples/components/echarts/Common.tsx @@ -0,0 +1,86 @@ +/** + * @file 生成一些通用的配置项 + */ + +/** + * 支持三种类型,一种是关键字,比如 auto,一种是数字,另一种是百分比 + * @param name + * @param label + * @param labelForRadio 切换按钮的文字 + * @param keywordList 关键字列表 + */ +export const keywordOrNumber = ( + name: string, + label: string, + labelForRadio: string, + keywordList: string[] +) => { + return [ + { + type: 'button-group', + name: name, + label: labelForRadio, + options: [ + { + label: '关键字', + value: keywordList[0] + }, + { + label: '数字', + value: 2 + }, + { + label: '百分比', + value: 3 + } + ], + pipeIn: value => { + if (typeof value === 'undefined') { + return keywordList[0]; + } + if (typeof value === 'string') { + if (value.indexOf('%') !== -1) { + return 3; + } else { + return keywordList[0]; + } + } else if (typeof value === 'number') { + return 2; + } else { + return keywordList[0]; + } + }, + pipeOut: (value, oldValue) => { + if (value === 1) { + return keywordList[0]; + } else if (value === 2) { + return 0; + } else if (value === 3) { + return '0%'; + } else { + return keywordList[0]; + } + } + }, + { + type: 'select', + name: name, + label: label, + options: keywordList, + value: keywordList[0], + visibleOn: `(typeof data.${name} === "undefined") || ((typeof data.${name} === "string") && (data.${name}.indexOf("%") === -1))` + }, + { + type: 'number', + name: name, + label: label, + visibleOn: `(typeof data.${name} === "number")` + }, + { + type: 'text', + name: name, + label: label, + visibleOn: `(typeof data.${name} === "string") && (data.${name}.indexOf("%") !== -1)` + } + ]; +}; diff --git a/examples/components/echarts/Title.tsx b/examples/components/echarts/Title.tsx new file mode 100644 index 000000000..be63e3704 --- /dev/null +++ b/examples/components/echarts/Title.tsx @@ -0,0 +1,80 @@ +/** + * @file Echarts title 的配置 + */ + +export default { + name: 'title', + type: 'combo', + label: '', + noBorder: true, + multiLine: true, + controls: [ + { + type: 'switch', + name: 'show', + value: true, + label: '是否显示标题组件' + }, + { + type: 'container', + visibleOn: 'data.show', + controls: [ + { + type: 'text', + name: 'text', + label: '主标题文本' + }, + { + type: 'text', + name: 'link', + visibleOn: 'data.text', + label: '主标题文本超链接', + validations: { + isUrl: true + } + }, + { + type: 'switch', + name: 'target', + value: 'blank', + visibleOn: 'data.link', + label: '指定窗口打开主标题超链接', + options: [ + {label: '但前窗口打开', value: 'self'}, + {label: '新窗口打开', value: 'blank'} + ] + }, + { + type: 'text', + name: 'subtext', + label: '副标题文本' + }, + { + type: 'text', + name: 'sublink', + visibleOn: 'data.subtext', + label: '副标题文本超链接', + validations: { + isUrl: true + } + }, + { + type: 'switch', + name: 'subtarget', + value: 'blank', + visibleOn: 'data.sublink', + label: '指定窗口打开副标题超链接', + options: [ + {label: '但前窗口打开', value: 'self'}, + {label: '新窗口打开', value: 'blank'} + ] + }, + { + type: 'switch', + name: 'triggerEvent', + label: '是否触发事件' + } + ] + } + ] +}; diff --git a/examples/components/echarts/TitleStyle.tsx b/examples/components/echarts/TitleStyle.tsx new file mode 100644 index 000000000..3306560de --- /dev/null +++ b/examples/components/echarts/TitleStyle.tsx @@ -0,0 +1,76 @@ +/** + * @file Echarts title 样式的配置 + */ + +import {keywordOrNumber} from './Common'; + +export default { + name: 'title', + type: 'combo', + label: '', + noBorder: true, + multiLine: true, + controls: [ + { + type: 'select', + name: 'textAlign', + value: 'auto', + label: '整体(包括 text 和 subtext)的水平对齐', + options: ['auto', 'left', 'right', 'center'] + }, + { + type: 'select', + name: 'textVerticalAlign', + value: 'auto', + label: '整体(包括 text 和 subtext)的垂直对齐', + options: ['auto', 'top', 'bottom', 'middle'] + }, + { + type: 'number', + name: 'padding', + hiddenOn: 'Array.isArray(data.padding)', + value: 5, + label: '标题内边距,单位px' + }, + { + type: 'switch', + name: 'padding', + label: '单独设置每个内边距', + pipeIn: (value, data) => { + return Array.isArray(value); + }, + pipeOut: (value, oldValue) => { + if (typeof oldValue !== 'undefined') { + return Array.isArray(oldValue) ? 5 : [0, 0, 0, 0, 0]; + } + return value ? [0, 0, 0, 0] : 5; + } + }, + { + type: 'array', + name: 'padding', + label: '设置标题内边距', + remark: + '设置两个值将分别是上下的内边距、坐右的内边距;设置四个值则分别是上、右、下、左', + visibleOn: 'Array.isArray(data.padding)', + minLength: 2, + maxLength: 4, + items: { + type: 'number' + } + }, + { + type: 'number', + value: 5, + name: 'itemGap', + label: '主副标题之间的间距' + }, + + ...keywordOrNumber('left', '标题离容器左侧的距离', '左侧距离值类型', [ + 'auto', + 'left', + 'center', + 'right' + ]) + ] +}; diff --git a/examples/style.scss b/examples/style.scss index 1e49985cc..1717a8597 100644 --- a/examples/style.scss +++ b/examples/style.scss @@ -912,3 +912,11 @@ a { background-color: #333538; } } + +// 让 echarts 编辑器的 tabs 更紧凑 +.echarts-editor > .a-Tabs-links { + width: 3rem; + > .a-Tabs-link > a { + padding: 5px 5px 5px 7px; + } +}