This is an automated email from the ASF dual-hosted git repository. shenyi pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/echarts-handbook.git
The following commit(s) were added to refs/heads/master by this push: new ebd55ec add md-live component ebd55ec is described below commit ebd55ece846a880742e70c84d62f14f9f92f94f1 Author: pissang <bm2736...@gmail.com> AuthorDate: Wed Jun 2 20:45:55 2021 +0800 add md-live component --- components/helper/loadScripts.ts | 53 +++++++++ components/markdown/Live.vue | 124 +++++++++++++++++++++ components/markdown/global.ts | 2 + .../zh/application/chart-types/line/area-line.md | 5 +- .../zh/application/chart-types/line/basic-line.md | 25 ++--- .../zh/application/chart-types/line/smooth-line.md | 5 +- .../application/chart-types/line/stacked-line.md | 8 +- .../zh/application/chart-types/line/step-line.md | 5 +- contents/zh/meta/get-started.md | 36 +++++- layouts/default.vue | 3 + nuxt.config.js | 2 + package-lock.json | 5 + package.json | 3 +- 13 files changed, 246 insertions(+), 30 deletions(-) diff --git a/components/helper/loadScripts.ts b/components/helper/loadScripts.ts new file mode 100644 index 0000000..cff54ed --- /dev/null +++ b/components/helper/loadScripts.ts @@ -0,0 +1,53 @@ +const promisesCache = {} +interface ScriptObj { + url: string + type: 'css' | 'js' +} +export function loadScriptsAsync(scripts: (string | ScriptObj)[]) { + return Promise.all( + scripts + .map(scriptUrl => { + if (typeof scriptUrl === 'string') { + return { + url: scriptUrl, + // TODO Not supported type + type: scriptUrl.match(/\.css$/) ? 'css' : 'js' + } + } + return scriptUrl + }) + .map(function(scriptUrl) { + if (promisesCache[scriptUrl.url]) { + return promisesCache[scriptUrl.url] + } + + const promise = new Promise((resolve, reject) => { + if (scriptUrl.type === 'js') { + const script = document.createElement('script') + script.src = scriptUrl.url + script.async = false + script.onload = function() { + resolve(null) + } + script.onerror = function() { + reject() + } + document.body.appendChild(script) + } else if (scriptUrl.type === 'css') { + const link = document.createElement('link') + link.rel = 'stylesheet' + link.href = scriptUrl.url + link.onload = function() { + resolve(null) + } + link.onerror = function() { + reject() + } + document.body.appendChild(link) + } + }) + promisesCache[scriptUrl.url] = promise + return promise + }) + ) +} diff --git a/components/markdown/Live.vue b/components/markdown/Live.vue new file mode 100644 index 0000000..21b6832 --- /dev/null +++ b/components/markdown/Live.vue @@ -0,0 +1,124 @@ +<template> + <div class="md-live" v-if="innerCode"> + <div class="md-live-editor"> + <prism-editor v-model="innerCode" :highlight="highlighter"> + </prism-editor> + <div class="md-live-tag">live</div> + </div> + <div class="md-live-preview"></div> + </div> +</template> + +<script lang="ts"> +import Vue, { PropType } from 'vue' +import { PrismEditor } from 'vue-prism-editor' +import 'vue-prism-editor/dist/prismeditor.min.css' +import { highlight, languages } from 'prismjs/components/prism-core' +import 'prismjs/components/prism-clike' +import 'prismjs/components/prism-javascript' +import 'prism-themes/themes/prism-material-oceanic.css' +import { loadScriptsAsync } from '../helper/loadScripts' + +function ensureECharts() { + if (typeof echarts === 'undefined') { + return loadScriptsAsync([ + 'https://cdn.jsdelivr.net/npm/echarts/dist/echarts.js' + ]).then(() => {}) + } + return Promise.resolve() +} + +export default Vue.extend({ + components: { + PrismEditor + }, + props: { + lang: { + type: String, + default: 'js' + } + }, + data() { + return { + innerCode: '' + } + }, + computed: {}, + mounted() { + this.innerCode = ( + (this.$slots.default && this.$slots.default[0].text) || + '' + ).trim() + }, + methods: { + highlighter(code) { + return highlight(code, languages[this.lang] || languages.js) + } + }, + watch: { + innerCode() { + ensureECharts().then(() => { + // TODO type, resize, throttle + if (!this._chartInstance) { + this._chartInstance = echarts.init( + this.$el.querySelector('.md-live-preview') + ) + } + const func = new Function(this.innerCode + '\n return option;') + try { + const option = func() + this._chartInstance.setOption(option) + } catch (e) {} + }) + } + } +}) +</script> + +<style lang="postcss"> +.md-live { + @apply shadow-lg rounded-lg mt-10 mb-20; +} +/* required class */ +.md-live-editor { + @apply rounded-t-lg; + position: relative; + /* we dont use `language-` classes anymore so thats why we need to add background and text color manually */ + background: #263238; + + font-size: 13px; + padding: 10px; + + pre { + color: #c3cee3; + } + + .md-live-tag { + position: absolute; + right: 0; + top: 0; + text-transform: uppercase; + margin-right: 1rem; + margin-top: 0.75rem; + color: #f7fafc; + z-index: 10; + } +} + +.md-live-preview { + height: 300px; + @apply rounded-b-lg; +} + +.prism-editor-wrapper .prism-editor__editor, +.prism-editor-wrapper .prism-editor__textarea { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, + 'Liberation Mono', 'Courier New', monospace; + line-height: 1.5; +} + +/* optional class for removing the outline */ +.prism-editor__textarea:focus { + outline: none; +} +</style> diff --git a/components/markdown/global.ts b/components/markdown/global.ts index f48a156..ada0e5e 100644 --- a/components/markdown/global.ts +++ b/components/markdown/global.ts @@ -1,6 +1,8 @@ import Vue from 'vue' import Example from './Example.vue' import Alert from './Alert.vue' +import Live from './Live.vue' Vue.component('md-example', Example) Vue.component('md-alert', Alert) +Vue.component('md-live', Live) diff --git a/contents/zh/application/chart-types/line/area-line.md b/contents/zh/application/chart-types/line/area-line.md index 921fc33..fa8421f 100644 --- a/contents/zh/application/chart-types/line/area-line.md +++ b/contents/zh/application/chart-types/line/area-line.md @@ -2,8 +2,7 @@ 区域面积折线图将折线到坐标轴的空间设置背景色,用区域面积表达数据。相比普通的折线图,区域面积折线图的视觉效果更加饱满丰富,在系列不多的场景下尤其适用。 -<!-- embed --> -```js +<md-live> option = { xAxis: { data: ['A', 'B', 'C', 'D', 'E'] @@ -22,6 +21,6 @@ option = { } }] }; -``` +</md-live> 通过 [`areaStyle`](${optionPath}series-line.areaStyle) 设置折线图的填充区域样式,将其设为为 `{}` 表示使用默认样式,即使用系列的颜色以半透明的方式填充区域。如果想指定特定的样式,可以通过设置 `areaStyle` 下的配置项覆盖,如第二个系列将填充区域的颜色设为不透明度为 0.5 的黄色。 diff --git a/contents/zh/application/chart-types/line/basic-line.md b/contents/zh/application/chart-types/line/basic-line.md index 2eee0b9..7f24b51 100644 --- a/contents/zh/application/chart-types/line/basic-line.md +++ b/contents/zh/application/chart-types/line/basic-line.md @@ -6,8 +6,7 @@ 如果我们想建立一个横坐标是类目型(category)、纵坐标是数值型(value)的折线图,我们可以使用这样的方式: -<!-- embed --> -```js +<md-live> option = { xAxis: { type: 'category', @@ -21,7 +20,7 @@ option = { type: 'line' }] }; -``` +</md-live> 在这个例子中,我们通过 `xAxis` 将横坐标设为类目型,并指定了对应的值;通过 `type` 将 `yAxis` 的类型设定为数值型。在 `series` 中,我们将系列类型设为 `line`,并且通过 `data` 指定了折线图三个点的取值。这样,就能得到一个最简单的折线图了。 @@ -32,8 +31,7 @@ option = { 如果我们希望折线图在横坐标和纵坐标上都是连续的,即在笛卡尔坐标系中,应该如何实现呢?答案也很简单,只要把 `series` 的 `data` 每个数据用一个包含两个元素的数组表示就行了。 -<!-- embed --> -```js +<md-live> option = { xAxis: {}, yAxis: {}, @@ -42,7 +40,7 @@ option = { type: 'line' }] }; -``` +</md-live> ## 折线图样式设置 @@ -51,8 +49,7 @@ option = { 折线图中折线的样式可以通过 `lineStyle` 设置。可以为其指定颜色、线宽、折线类型、阴影、不透明度等等,具体的可以参考配置项手册 [`series.lineStyle`](${optionPath}series-line.lineStyle) 了解。这里,我们以设置颜色(color)、线宽(width)和折线类型(type)为例说明。 -<!-- embed --> -```js +<md-live> option = { xAxis: { data: ['A', 'B', 'C', 'D', 'E'] @@ -70,7 +67,7 @@ option = { } }] }; -``` +</md-live> 这里设置折线宽度时,数据点描边的宽度是不会跟着改变的,而应该在数据点的配置项中另外设置。 @@ -83,8 +80,7 @@ option = { 在系列中,这数据点的标签通过 [`series.label`](${optionPath}series-line.label) 属性指定。如果将 `label` 下的 `show` 指定为`true`,则表示该数值默认时就显示;如果为 `false`,而 [`series.emphasis.label.show`](${optionPath}series-line.emphasis.label.show) 为 `true`,则表示只有在鼠标移动到该数据时,才显示数值。 -<!-- embed --> -```js +<md-live> option = { xAxis: { data: ['A', 'B', 'C', 'D', 'E'] @@ -102,7 +98,7 @@ option = { } }] }; -``` +</md-live> ## 空数据 @@ -111,8 +107,7 @@ option = { 在 ECharts 中,我们使用字符串 `'-'` 表示空数据,这对其他系列的数据也是适用的。 -<!-- embed --> -```js +<md-live> option = { xAxis: { data: ['A', 'B', 'C', 'D', 'E'] @@ -123,6 +118,6 @@ option = { type: 'line' }] }; -``` +</md-live> > 注意区别这个例子中,“空”数据与取值为 0 的数据。 diff --git a/contents/zh/application/chart-types/line/smooth-line.md b/contents/zh/application/chart-types/line/smooth-line.md index 387cefc..c29f6cc 100644 --- a/contents/zh/application/chart-types/line/smooth-line.md +++ b/contents/zh/application/chart-types/line/smooth-line.md @@ -2,8 +2,7 @@ 平滑曲线图也是折线图的一种变形,这种更柔和的样式也是一种不错的视觉选择。使用时,只需要将折线图系列的 `smooth` 属性设置为 `true` 即可。 -<!-- embed --> -```js +<md-live> option = { xAxis: { data: ['A', 'B', 'C', 'D', 'E'] @@ -15,4 +14,4 @@ option = { smooth: true }] }; -``` +</md-live> diff --git a/contents/zh/application/chart-types/line/stacked-line.md b/contents/zh/application/chart-types/line/stacked-line.md index b022056..843f45f 100644 --- a/contents/zh/application/chart-types/line/stacked-line.md +++ b/contents/zh/application/chart-types/line/stacked-line.md @@ -3,7 +3,7 @@ 与[堆叠柱状图](./zh/application_chart-types_bar_stacked-bar)类似,堆叠折线图也是用系列的 `stack` 设置哪些系列堆叠在一起。 <!-- embed --> -```js +<md-live> option = { xAxis: { data: ['A', 'B', 'C', 'D', 'E'] @@ -19,12 +19,12 @@ option = { stack: 'x' }] }; -``` +</md-live> 但是不同的是,如果不加说明的话,我们很难判断出这是一个堆叠折线图,还是一个普通的折线图。所以,对于堆叠折线图而言,一般建议使用区域填充色以表明堆叠的情况。 <!-- embed --> -```js +<md-live> option = { xAxis: { data: ['A', 'B', 'C', 'D', 'E'] @@ -42,4 +42,4 @@ option = { areaStyle: {} }] }; -``` +</md-live> diff --git a/contents/zh/application/chart-types/line/step-line.md b/contents/zh/application/chart-types/line/step-line.md index d271602..ad73928 100644 --- a/contents/zh/application/chart-types/line/step-line.md +++ b/contents/zh/application/chart-types/line/step-line.md @@ -4,8 +4,7 @@ 在 ECharts 中,系列的 `step` 属性用来表征阶梯线图的连接类型,它共有三种取值:`'start'`、`'middle'` 和 `'end'`,分别表示在当前点,当前点与下个点的中间点,下个点拐弯。 -<!-- embed --> -```js +<md-live> option = { xAxis: { type: 'category', @@ -33,6 +32,6 @@ option = { data: [450, 432, 401, 454, 590, 530, 510] }] }; -``` +</md-live> > 请注意这个例子中不同的 `step` 取值对应的数据点和连线的区别。 diff --git a/contents/zh/meta/get-started.md b/contents/zh/meta/get-started.md index 95d27a3..d70a4d4 100644 --- a/contents/zh/meta/get-started.md +++ b/contents/zh/meta/get-started.md @@ -88,6 +88,8 @@ option = { ### md-alert +提示组件 + ```markdown <md-alert type="info"> This is an info alert. @@ -114,4 +116,36 @@ This is an warning alert. </md-alert> <md-alert type="danger"> This is an danger alert. -</md-alert> \ No newline at end of file +</md-alert> + + +### md-live + +实时代码预览组件 +```markdown +<md-live> +option = { + xAxis: { + data: ['A', 'B', 'C', 'D', 'E'] + }, + yAxis: {}, + series: [{ + data: [0, 22, '-', 23, 19], + type: 'line' + }] +}; +</md-live> +``` + +<md-live> +option = { + xAxis: { + data: ['A', 'B', 'C', 'D', 'E'] + }, + yAxis: {}, + series: [{ + data: [0, 22, '-', 23, 19], + type: 'line' + }] +}; +</md-live> \ No newline at end of file diff --git a/layouts/default.vue b/layouts/default.vue index 02ea4d5..43b69a9 100644 --- a/layouts/default.vue +++ b/layouts/default.vue @@ -129,6 +129,9 @@ export default { @apply bg-blue-100 border-blue-400 rounded-lg; + code { + @apply bg-blue-200 shadow-none border-0 text-current; + } :first-child { margin-top: 0; } diff --git a/nuxt.config.js b/nuxt.config.js index 3df2268..38ba4cc 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -3,6 +3,8 @@ import zhPosts from './contents/zh/posts' import config from './configs/config' export default { + ssr: false, + target: 'static', router: { diff --git a/package-lock.json b/package-lock.json index ae4ecd0..3336c4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20668,6 +20668,11 @@ "resolved": "https://registry.npmjs.org/vue-no-ssr/-/vue-no-ssr-1.1.1.tgz", "integrity": "sha512-ZMjqRpWabMPqPc7gIrG0Nw6vRf1+itwf0Itft7LbMXs2g3Zs/NFmevjZGN1x7K3Q95GmIjWbQZTVerxiBxI+0g==" }, + "vue-prism-editor": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/vue-prism-editor/-/vue-prism-editor-1.2.2.tgz", + "integrity": "sha512-Lq2VgVygTx3Whn/tC8gD4m1ajA4lzSyCTqPLZA1Dq/ErbBaZA93FWRblwCoDR7AD2nXhGWuiTzb5ih3guzB7DA==" + }, "vue-router": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.1.tgz", diff --git a/package.json b/package.json index 8bad855..fec488d 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "markdown-it-table-of-contents": "^0.5.2", "nuxt": "^2.15.6", "nuxt-i18n": "^6.27.0", - "scroll-into-view": "^1.15.0" + "scroll-into-view": "^1.15.0", + "vue-prism-editor": "^1.2.2" }, "devDependencies": { "@nuxt/content": "^1.14.0", --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@echarts.apache.org For additional commands, e-mail: commits-h...@echarts.apache.org