Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

echarts: simplify usage and remove current limitations #735

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,31 @@ The basic chart types ECharts supports include [line series](https://echarts.apa

Just insert your ECharts option in `JSON`/`YAML`/`TOML` format in the `echarts` shortcode and that’s it.

Example `echarts` input in `JSON` format:
You have 2 ways to use this shortcode:

**Direct embedding**
: You can either [embed]({{< ref "#embedded" >}}) the definition of the chart in the body of the shortcode itself, as TOML.

**Import a JS module**
: Or you can [reference]({{< ref "#referenced" >}}) the path to a separate `.js` file which contains the JS specification of the chart, thereby supporting echarts with full JavaScript.

You can also mix shortcodes of both types within the same page.

## Embedded echart {#embedded}

This is the simplest form of use. You simply embed the echart specification inside of the body of the `echarts` shortcode, in `JSON`, `YAML` or `TOML` format.

Pros:

- Simple to use and maintain.
- Content of the chart visible in your page source itself.

Cons:

- Does not support JavaScript logic in chart.
- Does not allow re-using charts.

Here's an example `echarts` input in `JSON` format:

```json
{{</* echarts */>}}
Expand Down Expand Up @@ -403,7 +427,38 @@ The rendered output looks like this:
}
{{< /echarts >}}

The `echarts` shortcode has also the following named parameters:
## Referenced echart {#referenced}

In this way of use, your `echarts` shortcode references a JS file which contains the specification of the chart.

Pros:

- Your echart supports any JavaScript code, including logic to load or transform data.
- Enables copy/paste prototyping from [echarts' online builder](https://echarts.apache.org/en/builder.html), without conversion to JSON / TOML / YAML.
- Enables re-using a chart in multiple posts.
- Avoids bloating your content with long chart specifications.
- Accelerates page and chart loading by reducing page size and allowing browser to cache compiled chart.

Cons:

- Charts are separate files from posts.

Here's how you use the shortcode in this way:

1. Create a directory `content/charts/` inside your `content` directory
2. Create a file `summary_line_chart.js` inside of that folder
3. Paste any echart specification into that file; copy one e.g. from the [echarts gallery of examples](https://echarts.apache.org/examples/en/editor.html?c=area-stack-gradient).
4. Change the prefix of the specification from ~~`option = {`~~ to `export const option = {`.
5. Finally, add the following shortcode in your post, wherever you want the chart to be loaded:

```
{{</* echarts file="charts/summary_line_chart.js" >}}
{{< /echarts */>}}
```

## echarts options

The `echarts` shortcode has also the following named parameters, supported in both ways of use (direct and referenced):

* **width** *[optional]* (**first** positional parameter)

Expand Down
22 changes: 19 additions & 3 deletions layouts/shortcodes/echarts.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
{{- $content := .Inner | transform.Unmarshal | jsonify -}}
{{- $id := dict "Content" $content "Scratch" .Page.Scratch | partial "function/id.html" -}}
{{- $width := cond .IsNamedParams (.Get "width") (.Get 0) | default "100%" -}}
{{- $height := cond .IsNamedParams (.Get "height") (.Get 1) | default "30rem" -}}
<div class="echarts" id="{{ $id }}" style="width: {{ $width }}; height: {{ $height }};"></div>
{{- if (.Get "file") -}}
{{- $chart_filename := (.Get "file") -}}
{{- $scratch := newScratch -}}
{{- $scratch.Set "absolute_filename" "" -}}
{{- with .Get "file" -}}
{{- $chart_name := index (split (path.Base $chart_filename) ".") 0 -}}
{{- $chart_absolute_filename := add "/" $chart_filename -}}
{{- $scratch.Set "absolute_filename" $chart_absolute_filename -}}
{{- $id := add "echart_" $chart_name -}}
{{- $scratch.Set "divid" $id -}}
{{- end -}}
{{ $id := $scratch.Get "divid" }}
{{ $chart_absolute_filename := $scratch.Get "absolute_filename" }}
<div class="echarts" data-filename="{{- $chart_absolute_filename -}}" id="{{ $id }}" style="width: {{ $width }}; height: {{ $height }};"></div>
{{- else -}}
{{- $content := .Inner | transform.Unmarshal | jsonify -}}
{{- $id := dict "Content" $content "Scratch" .Page.Scratch | partial "function/id.html" -}}
<div class="echarts" id="{{ $id }}" style="width: {{ $width }}; height: {{ $height }};"></div>
{{- end -}}
{{- .Page.Scratch.SetInMap "this" "echarts" true -}}
16 changes: 14 additions & 2 deletions src/js/theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -515,8 +515,20 @@ class Theme {
}
this._echartsArr = [];
this.util.forEach(document.getElementsByClassName('echarts'), $echarts => {
const chart = echarts.init($echarts, this.isDark ? 'dark' : 'light', {renderer: 'svg'});
chart.setOption(JSON.parse(this.data[$echarts.id]));
let filename = $echarts.dataset.filename;
const chart = echarts.init($echarts, this.isDark ? 'dark' : 'macarons', {renderer: 'svg'});
if (! filename) {
// has chart config stored in some element ID as JSON
chart.setOption(JSON.parse(this.data[$echarts.id]));
} else {
// has data-filename attribute => load chart config from external file
$echarts.innerHTML = '';
import(filename).then(module => {
chart.setOption(module.option);
}).catch((err) => {
console.error("While loading eChart for " + filename + ": " + err);
})
}
this._echartsArr.push(chart);
});
});
Expand Down