This is the multi-page printable view of this section. .
Apache ECharts
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:namebridge, 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
datasetwhen 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
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
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.