This is the multi-page printable view of this section. .

Return to the regular view of this page.

Apache ECharts

Build responsive, local-first charts from structured JSON or YAML.

The echarts shortcode renders an Apache ECharts options object with the versioned runtime bundled by Oink. Hugo parses JSON or YAML at build time, serializes the result into the page, and loads ECharts only on pages that use the component.

Use ECharts for quantitative charts whose axes, encodings, tooltips, or series need more control than a diagram or table provides. Keep a nearby textual summary so the conclusion does not depend on color, pointer interaction, or JavaScript.

Quick start

{{< echarts height="300px" >}}
xAxis:
  type: category
  data: [Draft, Review, Publish]
yAxis:
  type: value
series:
  - type: bar
    data: [12, 9, 4]
{{< /echarts >}}

The example shows 12 draft pages, nine pages in review, and four pages ready to publish.

How Oink loads a chart

The shortcode creates a unique chart container and stores the parsed options in an application/json element. The page includes the local ECharts runtime and Oink initializer once, even when it contains several charts.

If theme is not set, Oink initializes the chart for the current site color mode and redraws it when the reader changes modes. A ResizeObserver resizes the chart with its container. Setting an explicit ECharts theme opts out of automatic site-theme switching for that chart.

Shortcode parameters

Parameter Default Behavior
height 400px Accepts a nonnegative number with px, rem, em, vh, vw, or %
theme unset Uses a named ECharts theme; when unset, follows the site’s light or dark color mode
full false Set to true to remove Oink’s normal content-width clamp

Invalid height values fail the Hugo build. The shortcode body must decode to an ECharts options object; malformed JSON or YAML also fails at build time instead of creating a blank chart silently.

Choose a guide

  • Chart gallery demonstrates datasets, bars, lines, areas, pies, scatter plots, legends, and visual encodings.
  • Callbacks and trusted code explains formatter functions, data-dependent styles, the $fn:name bridge, and its security boundary.

Start with declarative JSON or YAML. Add JavaScript callbacks only when the ECharts option cannot be expressed as data.

Authoring checklist

  • State the chart’s conclusion and data scope in prose.
  • Label axes, units, series, and time ranges explicitly.
  • Do not use color as the only way to distinguish important values.
  • Keep legends and tooltips readable in both site color modes.
  • Test the chart at narrow widths and with long translated labels.
  • Prefer a shared dataset when several series use the same records.
  • Record the data source and observation date for nonillustrative data.
  • Avoid animation when it does not help comprehension, and respect reduced motion for custom effects.

Further reference

OINK documents its wrapper and delivery behavior; the full options schema belongs to Apache ECharts. Use the ECharts concepts handbook, dataset guide, and option reference for chart-specific settings. The theme’s VENDOR.json records the exact runtime version and license shipped by a release.

1 - ECharts gallery

Copy practical declarative ECharts patterns for documentation pages.

These examples use only structured YAML. They require no callback code and therefore stay within the simplest ECharts authoring and review boundary. The numbers are illustrative.

Reuse a dataset

ECharts dataset keeps records separate from their visual encoding. Series can refer to dimensions by name, which is easier to review than repeating parallel arrays.

Bar chart from a dataset

{{< echarts height="320px" >}}
dataset:
  source:
    - [stage, minutes]
    - [Draft, 18]
    - [Review, 11]
    - [Publish, 4]
xAxis: { type: category }
yAxis: { type: value, name: Minutes }
series:
  - type: bar
    encode: { x: stage, y: minutes }
{{< /echarts >}}

The example shows the median duration falling from 18 minutes for drafting to four minutes for publication.

Line and area comparison

Use a shared category axis when several series describe the same intervals. The area fill emphasizes volume; the lines preserve the individual trends.

{{< echarts height="340px" >}}
tooltip: { trigger: axis }
legend: { data: [English, Chinese] }
xAxis:
  type: category
  data: [Mon, Tue, Wed, Thu, Fri]
yAxis: { type: value, name: Pages }
series:
  - name: English
    type: line
    smooth: true
    areaStyle: { opacity: 0.12 }
    data: [5, 8, 7, 11, 13]
  - name: Chinese
    type: line
    smooth: true
    areaStyle: { opacity: 0.12 }
    data: [4, 6, 8, 9, 13]
{{< /echarts >}}

Both language queues reach 13 reviewed pages on Friday; the Chinese queue catches up after starting one page lower.

Donut breakdown

A donut works for a small part-to-whole comparison. Keep the categories few, show labels directly, and provide the totals in text.

{{< echarts height="340px" >}}
tooltip: { trigger: item }
legend: { bottom: 0 }
series:
  - name: Documentation pages
    type: pie
    radius: [42%, 68%]
    avoidLabelOverlap: true
    label: { formatter: "{b}: {c}" }
    data:
      - { name: Guides, value: 28 }
      - { name: Reference, value: 17 }
      - { name: Tutorials, value: 11 }
      - { name: Concepts, value: 8 }
{{< /echarts >}}

The 64-page set contains 28 guides, 17 reference pages, 11 tutorials, and eight concept pages.

Scatter plot with visual encoding

visualMap can encode a third dimension without callback code. The following plot maps build size to point size and build status to color.

{{< echarts height="360px" >}}
tooltip: { trigger: item }
xAxis: { type: value, name: Build seconds }
yAxis: { type: value, name: Pages }
visualMap:
  - type: continuous
    dimension: 2
    min: 10
    max: 50
    inRange: { symbolSize: [10, 32], color: ["#60a5fa", "#f97316"] }
    right: 0
    top: middle
series:
  - type: scatter
    encode: { x: 0, y: 1, tooltip: [0, 1, 2] }
    data:
      - [1.8, 24, 12]
      - [2.6, 41, 22]
      - [3.9, 67, 35]
      - [5.1, 92, 48]
{{< /echarts >}}

Larger sites take longer to build in this illustrative sample; point size and color both encode the third value so color is not the only cue.

Production notes

Keep example data close to the chart only when it is small and editorial. For larger or generated datasets, produce the options during the site’s content pipeline and review the resulting page source. Oink does not fetch chart data from a remote endpoint automatically; adding a network request is an explicit site integration and changes the local-first and privacy boundary.

2 - ECharts callbacks and trusted code

Use reviewed formatter and styling functions when structured options are not enough.

Most ECharts options should remain declarative JSON or YAML. Some valid options, including custom formatters and data-dependent styles, require functions. Oink supports those cases through fenced JavaScript blocks and $fn:name references.

Trusted-author boundary

Callback code runs in every visitor’s browser with the page’s origin and normal JavaScript privileges. Oink safely serializes structured chart options, but it does not sandbox author-supplied callbacks. Only trusted project authors should add or review them.

Callbacks can also change a site’s Content Security Policy requirements because the shortcode emits an inline registration script. Prefer declarative options when they can express the same behavior.

Register and reference functions

Place one or more js or javascript fences inside the shortcode. Declare each function with a named var, let, const, or function declaration, then refer to it from YAML or JSON as $fn:name.

{{< echarts height="320px" >}}
```js
var formatMinutes = function (value) {
  return value + ' min';
};
```

```yaml
yAxis:
  type: value
  axisLabel: { formatter: $fn:formatMinutes }
```
{{< /echarts >}}

Oink removes the JavaScript fences before parsing the remaining options, registers the named functions, and replaces $fn:name values before calling chart.setOption().

Example: labels and colors

The following chart formats duration labels and highlights the slowest stage. Its data says writing takes 18 minutes, review takes 11, and publication takes four.

Callback checklist

  • Keep functions deterministic and limited to chart presentation.
  • Do not read cookies, credentials, storage, or unrelated page content.
  • Do not fetch remote data from a formatter or style callback.
  • Use a unique, descriptive function name on pages with several charts.
  • Treat code copied from an external example as source code that requires review and license checking.
  • Exercise callbacks with missing, null, string, and numeric values as appropriate.
  • Test both site color modes, narrow layouts, printing, and reduced motion.

Troubleshooting

If a $fn:name value remains unresolved, verify that the spelling matches a named declaration inside the same page and that the fence language is js or javascript. Anonymous expressions that are not assigned to a name cannot be registered.

If Hugo fails before rendering, reduce the body to valid JSON or YAML first, then add one callback. A browser console error means the structured options parsed successfully but callback execution or an ECharts option still needs inspection.