## Name
HTML::D3 - A simple Perl module for generating charts using D3.js.
## Version
Version 0.19
## Synopsis
```perl
use HTML::D3;
my $chart = HTML::D3->new(
width => 1024,
height => 768,
title => 'Sample Bar Chart'
);
my $data = [
['Category 1', 10],
['Category 2', 20],
['Category 3', 30]
];
my $html = $chart->render_bar_chart($data);
print $html;
$chart = HTML::D3->new(title => 'Sales Data');
$data = [
['Product A', 100],
['Product B', 150],
['Product C', 200]
];
$html = $chart->render_line_chart($data);
print $html;
```
## Description
HTML::D3 is a Perl module that provides functionality to create simple charts using D3.js.
The module generates HTML and JavaScript code to render the chart in a web browser.
## Methods
The `=head3 API SPECIFICATION` subsections use [Params::Validate::Strict](https://metacpan.org/pod/Params%3A%3AValidate%3A%3AStrict)
schema syntax (`type => 'arrayref'` etc.) as a documentation convention.
The module is also used at runtime in `new()` to validate constructor
arguments; it is therefore a required runtime dependency. The schemas describe
the parameter contract in machine-readable notation and can be plumbed into a
WAF or test generator if desired.
### New
```perl
my $chart = HTML::D3->new(%args);
```
Creates a new HTML::D3 object.
Accepts the following optional arguments:
- `width` - The width of the chart (default: 800).
- `height` - The height of the chart (default: 600).
- `title` - The title of the chart (default: 'Chart').
- `responsive` - If true, SVG elements are rendered with
`viewBox` and `width="100%" height="auto"` instead of fixed pixel
dimensions, so the chart scales fluidly with its container.
For snippet methods the per-call `opts => { responsive => 1 }`
takes precedence over this object-level setting (default: 0).
### Render\_Bar\_Chart
```perl
my $html = $chart->render_bar_chart($data);
```
Generates HTML and JavaScript code to render a bar chart. Accepts the following arguments:
- `$data` - An array reference containing data points. Each data point should
be an array reference with two elements: the label (string) and the value (numeric).
Returns a string containing the HTML and JavaScript code for the chart.
#### Errors
- Throws `Data is not optional` when `$data` is `undef`.
- Throws `Data must be an array of arrays` when `$data` is not an ARRAY reference.
#### Api Specification
##### Input
```perl
{
data => {
type => 'arrayref',
element_type => [ 'string', 'number' ]
}
}
Each element of C<$data> is C<[ Str, Num ]>; passing C or a
non-arrayref dies.
```
##### Output
```
Str -- complete HTML5 document starting with C<< >>;
D3.js loaded from CDN; bar chart rendered with C.
```
### Render\_Animated\_Bar\_Chart
```perl
my $html = $chart->render_animated_bar_chart($data);
```
Generates HTML and JavaScript code to render a bar chart where each bar grows
upward from the baseline on page load. Bars are staggered so they rise
one-after-another from left to right.
Accepts the following arguments:
- `$data` - An array reference of data points. Each data point is an
array reference with two elements: the label (string) and the value (numeric).
Returns a string containing the complete HTML5 document.
#### Errors
- Throws `Data is not optional` when `$data` is `undef`.
- Throws `Data must be an array of arrays` when `$data` is not an ARRAY reference.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref' },
}
Each element of C<$data> is C<[ Str, Num ]>; passing C or a
non-arrayref dies.
```
##### Output
```
Str -- complete HTML5 document; each bar animates from height=0 upward
using C with a staggered per-bar delay.
```
### Render\_Line\_Chart
```perl
my $html = $chart->render_line_chart($data);
```
Generates HTML and JavaScript code to render a line chart. Accepts the following arguments:
- `$data` - An array reference containing data points. Each data point should
be an array reference with two elements: the label (string) and the value (numeric).
Returns a string containing the HTML and JavaScript code for the chart.
#### Errors
- Throws `Data must be an array of arrays` when `$data` is not an ARRAY reference.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref' },
}
Each element of C<$data> is C<[ Str, Num ]>; passing C or a
non-arrayref dies.
```
##### Output
```
Str -- complete HTML5 document; line chart with C and C.
```
### Render\_Animated\_Line\_Chart
```perl
my $html = $chart->render_animated_line_chart($data);
```
Generates HTML and JavaScript code to render a line chart where the line
draws itself from left to right on page load, followed by each data-point
circle fading in once the line is complete.
Accepts the following arguments:
- `$data` - An array reference of data points. Each data point is an
array reference with two elements: the label (string) and the value (numeric).
Returns a string containing the complete HTML5 document.
#### Errors
- Throws `Data must be an array of arrays` when `$data` is not an ARRAY reference.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref' },
}
Each element of C<$data> is C<[ Str, Num ]>; passing C or a
non-arrayref dies.
```
##### Output
```
Str -- complete HTML5 document; the line path animates via
C with C; data-point circles
fade in with C after the line transition completes.
```
### Render\_Pie\_Chart
```perl
my $html = $chart->render_pie_chart($data);
my $html = $chart->render_pie_chart($data, { separator => ':' });
```
Generates HTML and JavaScript code to render a pie chart.
Each slice is coloured with `d3.schemeCategory10`; percentage labels appear
inside each slice and a colour legend is shown to the right of the pie.
Accepts the following arguments:
- `$data` - An array reference of data points. Each data point is an
array reference with two elements: the label (string) and the value (numeric).
- `%opts` - Optional hashref of options.
- `separator` (string, default `'/'`) - Character shown between the
label and value in the SVG legend.
Returns a string containing the complete HTML5 document.
#### Errors
- Throws `Data is not optional` when `$data` is `undef`.
- Throws `Data must be an array of arrays` when `$data` is not an ARRAY reference.
#### Api Specification
##### Input
```perl
{
data => {
type => 'arrayref',
element_type => [ 'string', 'number' ]
},
opts => { type => 'hashref', optional => 1, default => {} },
}
Each element of C<$data> is C<[ Str, Num ]>; passing C or a
non-arrayref dies.
Recognised C key: C (string, default C<'/'>)
- character shown between label and value in the SVG legend.
```
##### Output
```
Str -- complete HTML5 document; pie rendered with C and
C; slices coloured with C;
percentage label inside each slice; legend to the right.
```
### Render\_Animated\_Pie\_Chart
```perl
my $html = $chart->render_animated_pie_chart($data);
my $html = $chart->render_animated_pie_chart($data, { separator => ':' });
```
Generates HTML and JavaScript code to render an animated pie chart where each
slice fans out from zero angle on page load using `attrTween` and
`d3.interpolate`. Percentage labels fade in once all slices are drawn.
Accepts the following arguments:
- `$data` - An array reference of data points. Each data point is an
array reference with two elements: the label (string) and the value (numeric).
- `%opts` - Optional hashref of options.
- `separator` (string, default `'/'`) - Character shown between the
label and value in the SVG legend.
Returns a string containing the complete HTML5 document.
#### Errors
- Throws `Data is not optional` when `$data` is `undef`.
- Throws `Data must be an array of arrays` when `$data` is not an ARRAY reference.
#### Api Specification
##### Input
```perl
{
data => {
type => 'arrayref',
element_type => [ 'string', 'number' ]
},
opts => { type => 'hashref', optional => 1, default => {} },
}
Each element of C<$data> is C<[ Str, Num ]>; passing C or a
non-arrayref dies.
Recognised C key: C (string, default C<'/'>)
- character shown between label and value in the SVG legend.
```
##### Output
```
Str -- complete HTML5 document; slices animate via C with
C (1000 ms); percentage labels fade in afterwards.
```
### Render\_Pie\_Chart\_Snippet
```perl
my $fragment = $chart->render_pie_chart_snippet(\@slices);
my $fragment = $chart->render_pie_chart_snippet(\@slices, \%opts);
# $fragment->{svg_id} - always 'pie_chart'
# $fragment->{html} - embeddable fragment; caller must load D3 v7
```
Generates an embeddable pie or donut chart fragment for use in existing HTML
layouts. Returns `{ svg_id => 'pie_chart', html => Str }`. The
caller is responsible for loading D3 v7 before embedding the fragment.
#### Data Format
Each element of `\@slices` is `[$label, $value]` or `[$label, $value, \%extra]`.
Negative values are silently converted to their absolute value. Zero-value
slices are silently omitted. `\%extra` key/value pairs are shown as
additional rows in the hover tooltip.
#### Options (`\%Opts`)
- `animated` (bool, default 0) - fan slices in from arc-length 0 on
first render using `attrTween` / `d3.easeBackOut` (800 ms, staggered).
Respects `prefers-reduced-motion`.
- `donut` (bool, default 0) - render as a donut chart (inner radius
38% of outer radius); the total sum appears in the centre hole.
- `sort_slices` (string, default `'none'`) - `'value'` for
largest-first, `'label'` for alphabetical, `'none'` for input order.
- `max_slices` (int, default 0) - when > 0, only the top N-1
slices are shown individually; the rest are collapsed into an `"Other"` slice.
- `legend` (bool, default 1) - render an HTML legend panel beside the chart.
- `color_scheme` (string, default `'tableau10'`) - D3 categorical
colour scheme. Supported: `tableau10`, `category10`, `set2`, `set3`,
`paired`.
- `separator` (string, default `'/'`) - Character shown between the
label and value in each legend entry (e.g. `'/'` produces
`Label / 12.34 (42.0%)`, `':'` produces `Label : 12.34 (42.0%)`).
#### Errors
- Throws `Data must be an array of arrays` when `\@slices` is not an ARRAY reference.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref' },
opts => { type => 'hashref', optional => 1, default => {} },
}
Each element of C<$data> is C<[ Str, Num ]> or C<[ Str, Num, HashRef ]>;
passing C or a non-arrayref dies.
Recognised C keys: C (boolean, default C<0>),
C (boolean, default C<0>), C (string: C<'value'>,
C<'label'>, or C<'none'>; default C<'none'>), C (integer,
default C<0>), C (boolean, default C<1>),
C (string, default C<'tableau10'>),
C (string, default C<'/'> - shown between label and value in
legend entries).
```
##### Output
```
HashRef -- C<{ svg_id =E 'pie_chart', html =E Str }>;
embeddable fragment; no DOCTYPE, no page shell, no D3 CDN tag.
```
### Render\_Heatmap\_Snippet
```perl
my $fragment = $chart->render_heatmap_snippet(\@triples);
my $fragment = $chart->render_heatmap_snippet(\@triples, \%opts);
# $fragment->{svg_id} - always 'heatmap'
# $fragment->{html} - embeddable fragment; caller must load D3 v7
```
Generates an embeddable grid heatmap for use in existing HTML layouts.
Each cell sits at the intersection of an X-axis label and a Y-axis label;
its colour encodes the cell's numeric value using a sequential D3 colour
scale. Returns `{ svg_id => 'heatmap', html => Str }`. The
caller is responsible for loading D3 v7 before embedding the fragment.
#### Data Format
Each element of `\@triples` is `[$x_label, $y_label, $value]`.
`$value` must be numeric or `undef` (`undef` rows are silently
skipped). Zero is a valid value and maps to the lightest cell colour.
The caller is responsible for any aggregation: if multiple triples share
the same (x\_label, y\_label) pair, the last one wins.
#### Options (`\%Opts`)
- `color_scheme` (string, default `'YlOrRd'`) - D3 sequential
colour scheme. Supported: `YlOrRd`, `Blues`, `Greens`, `Purples`,
`RdPu`, `YlGnBu`.
- `x_label` (string, default `''`) - Axis title below the X axis.
The value is JavaScript-escaped (backslash, double-quote, newline, carriage
return) before being embedded in the page; other characters are taken
literally.
- `y_label` (string, default `''`) - Axis title left of the Y axis.
Same JS-escaping as `x_label` applies.
- `val_label` (string, default `'Value'`) - Tooltip value label.
Same JS-escaping as `x_label` applies.
- `show_values` (bool, default 0) - Print value inside each cell.
Auto-suppressed when any cell is narrower than 28 px.
- `cell_padding` (int 0-8, default 2) - Gap in pixels between cells.
- `legend` (bool, default 1) - Render a colour-scale legend bar.
- `animated` (bool, default 0) - Fade cells in on first load.
Respects `prefers-reduced-motion`.
#### Errors
- Dies with `Data must be an array of arrays` when `\@triples`
is not an ARRAY reference.
- Dies with `Each data point must be an array reference` when a
triple element is not an arrayref.
- Dies with `Each data point must have at least 3 elements` when
a triple has fewer than 3 elements.
- Dies with `Value must be numeric` when `$value` is defined but
not numeric.
- Dies with `Unknown color_scheme: ` for an
unsupported `color_scheme` value.
- Dies with `cell_padding must be between 0 and 8` when
`cell_padding` is outside the valid range.
#### Side Effects
Appends a tooltip `div` to the page when the fragment is rendered in
the browser.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref' },
opts => { type => 'hashref', optional => 1, default => {} },
}
Each element of C<$data> is C<[ Str, Str, Num|undef ]>.
Recognised C keys: C (string, default C<'YlOrRd'>),
C (string, default C<''>), C (string, default C<''>),
C (string, default C<'Value'>), C (boolean,
default C<0>), C (integer 0-8, default C<2>),
C (boolean, default C<1>), C (boolean, default C<0>).
```
##### Output
```
HashRef -- C<{ svg_id =E 'heatmap', html =E Str }>;
embeddable fragment; no DOCTYPE, no page shell, no D3 CDN tag.
```
### Render\_Bar\_Chart\_Snippet
```perl
my $result = $chart->render_bar_chart_snippet(\@bars);
my $result = $chart->render_bar_chart_snippet(\@bars, \%opts);
```
Generates an embeddable D3.js v7 bar chart fragment. Returns a hashref
`{ svg_id => 'bar_chart', html => $str }` where `$str` is a
self-contained HTML fragment (no page shell, no D3 CDN tag) that the caller
embeds directly after loading D3.js. `$str` is a Perl character string
with the UTF-8 flag set (or pure ASCII when all labels are ASCII).
Each element of `\@bars` is an array reference:
```
[ $label, $value ]
[ $label, $value, \%extra ]
```
`$label` is the category name (string); `$value` is a non-negative number
(negative values are silently converted to their absolute value); the optional
`\%extra` hashref supplies additional key/value pairs shown in the hover
tooltip. Data points with an undefined `$value` are silently skipped.
#### Options (`\%Opts`)
- `orientation` (string, default `'vertical'`)
`'vertical'` draws bars rising from a horizontal category axis.
`'horizontal'` draws bars extending from a vertical category axis.
- `sort_bars` (string, default `'none'`)
Sort order applied before rendering: `'value'` sorts descending by bar
height, `'label'` sorts ascending alphabetically, `'none'` preserves the
input order.
- `max_bars` (integer, default `0`)
When non-zero, only the first `max_bars` entries (after any sort) are
rendered; the remaining entries are collapsed into a single `Other` bar
whose value equals their sum. Zero means no limit.
- `color` (string, default `'steelblue'`)
Either a CSS colour value (e.g. `'steelblue'`, `'#4e79a7'`) applied to all
bars, or the special token `'categorical'`, which colours each bar
distinctively using D3's Tableau-10 palette.
- `show_values` (bool, default `0`)
When true, the numeric value of each bar is printed above vertical bars or
to the right of horizontal bars.
- `animated` (bool, default `0`)
When true, bars grow from the baseline on page load: vertical bars rise from
the bottom; horizontal bars extend from the left. An 800 ms D3 transition
with a per-bar stagger up to 100 ms is used. The animation is suppressed
when `prefers-reduced-motion` is set in the viewer's OS.
- `value_label` (string, default `'Value'`)
Label shown in the hover tooltip before the numeric value. The value is
JavaScript-escaped before being embedded in the page.
- `x_label` (string, default `''`)
When non-empty, a text label is rendered below the bottom axis. The value
is JavaScript-escaped before being embedded in the page.
#### Errors
- Throws `Data must be an array of arrays` when `$data` is not an
ARRAY reference.
- Throws `Each data point must be an array reference` when an element
is not an array reference.
- Throws `Each data point must have at least 2 elements` when an
element has fewer than 2 items.
- Throws `Value must be numeric` when a `$value` is not a number.
- Throws `orientation must be 'vertical' or 'horizontal'` on an
invalid orientation value.
- Throws `sort_bars must be 'value', 'label', or 'none'` on an
invalid sort\_bars value.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref' },
opts => { type => 'hashref', optional => 1 },
orientation => { type => 'string', memberof => [ 'vertical', 'horizontal' ], optional => 1 },
sort_bars => { type => 'string', memberof => [ 'value', 'label', 'none' ], optional => 1 }
}
Each element of C<$data>: C<[ Str, Num ]> or C<[ Str, Num, HashRef ]>;
undef C<$value> silently skipped; negative C<$value> becomes positive.
```
##### Output
```perl
HashRef -- { svg_id => 'bar_chart', html => Str }
html is a Perl character string (UTF-8 flag set, or pure ASCII).
```
### Render\_Line\_Chart\_With\_Tooltips
```
$html = $chart->render_line_chart_with_tooltips($data);
```
Generates HTML and JavaScript code to render a line chart with mouseover tooltips.
Accepts the following arguments:
- `$data` - An array reference containing data points. Each data point should
be an array reference with two elements: the label (string) and the value (numeric).
Returns a string containing the HTML and JavaScript code for the chart.
The JavaScript tooltip strings use `<\/b>` (with a backslash) rather than
`` to satisfy html-tidy's requirement that `` followed by a
letter not appear literally inside `
```
#### Arguments
- `$data` - An array reference of data points. Each point is an array
reference with two required elements - the label (string) and the value
(numeric) - and an optional third element: a hash reference of extra key/value
pairs to display in the tooltip after the label and value rows.
```
[$x, $y] # basic point
[$x, $y, \%row] # point with extra tooltip data
```
- `\%opts` - Optional hash reference of rendering options:
- `id` (string, default `'chart'`) - Override the `id` attribute of
the ` element. Use this when embedding multiple charts on the same page.
- `responsive` (boolean, default `0`) - If true, emit
`viewBox="0 0 W H" width="100%" height="auto"` instead of fixed pixel
dimensions, so the chart scales with its container. Falls back to
`$self->{responsive}` when not set per call.
#### Return Value
A hash reference with:
- `svg_id` - The `id` attribute used on the ` element.
- `html` - The embeddable fragment string (Perl character string).
#### Errors
- Dies with `'Data must be an array of arrays'` when `$data` is not an
ARRAY reference.
#### Side Effects
None. The method is read-only.
#### Api Specification
```perl
{
data => { type => 'arrayref' },
opts => {
type => 'hashref',
optional => 1,
keys => {
id => { type => 'string', optional => 1 },
responsive => { type => 'boolean', optional => 1 },
},
},
}
```
### Render\_Zoomable\_Line\_Chart\_Snippet
```perl
my $fragment = $chart->render_zoomable_line_chart_snippet($data);
my $fragment = $chart->render_zoomable_line_chart_snippet($data, { animated => 1 });
# $fragment->{svg_id} - the id attribute of the element
# $fragment->{html} - embeddable HTML fragment (style + button + svg + script)
```
Like `render_line_chart_snippet`, but adds brush-to-zoom: the user can drag
across a range of the x-axis to zoom into that region. A _Reset zoom_ button
(hidden until a zoom is active) returns the chart to its original extent.
Subsequent brushes on the zoomed view zoom in further; Reset always returns to
the full dataset.
The caller is responsible for loading D3 in the page `.
Accepts the same arguments as `render_line_chart_snippet`: an array reference
of data points, each `[$x, $y]` or `[$x, $y, \%extra]`, plus an optional
second argument `$opts` (hashref).
#### Options
- `animated` (boolean, default `0`) - when true, the initial page load
animates the line drawing left-to-right via the `stroke-dashoffset` technique
(1200 ms, `d3.easeLinear`), then fades in data-point circles after the line
finishes (300 ms after a 1200 ms delay). Respects
`prefers-reduced-motion`: when the user has requested reduced motion the line
is drawn immediately at full opacity. Subsequent zoom and reset redraws are
never animated regardless of this flag.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref' },
opts => { type => 'hashref', optional => 1, default => {} },
}
Each element of C<$data> is C<[ Str, Num ]> or C<[ Str, Num, HashRef ]>;
passing C or a non-arrayref dies.
Recognised C key: C (boolean, default C<0>).
```
##### Output
```
HashRef -- C<{ svg_id =E 'chart', html =E Str }>;
embeddable fragment; no DOCTYPE, no page shell, no D3 CDN tag.
```
#### Errors
Dies with _Data must be an array of arrays_ if `$data` is not an arrayref.
### Render\_Multi\_Series\_Line\_Chart\_With\_Tooltips
```
$html = $chart->render_multi_series_line_chart_with_tooltips($data);
```
Generates HTML and JavaScript code to render a chart of many lines with mouseover tooltips.
Accepts the following arguments:
- `$data` - An array reference of series hashes. Each element is a hashref
with a `name` key (string) and a `data` key (array reference of `{label, value}`
hashrefs).
```perl
[
{ name => 'Series A', data => [{ label => 'Jan', value => 100 }, ...] },
...
]
```
Returns a string containing the HTML and JavaScript code for the chart.
Tooltip strings use `<\/b>` rather than `` for html-tidy compliance.
#### Errors
- Throws `Data must be an array of hashes` when `$data` is not an ARRAY reference.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref' },
}
Each element of C<$data> is a hashref with keys C (string) and
C (arrayref of hashrefs with C and C keys);
passing C or a non-arrayref dies.
```
##### Output
```
Str -- complete HTML5 document; one coloured line per series with mouseover tooltips.
```
### Render\_Multi\_Series\_Line\_Chart\_With\_Animated\_Tooltips
```
$html = $chart->render_multi_series_line_chart_with_animated_tooltips($data);
```
Generates HTML and JavaScript code to render a chart of many lines with animated mouseover tooltips.
Accepts the following arguments:
- `$data` - Same format as `render_multi_series_line_chart_with_tooltips`:
an array reference of `{ name, data }` series hashes.
Returns a string containing the complete HTML5 document.
The tooltip appears with a CSS `translateY` slide-in animation.
Tooltip strings use `<\/b>` for html-tidy compliance.
#### Errors
- Throws `Data must be an array of hashes` when `$data` is not an ARRAY reference.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref' },
}
Each element of C<$data> is a hashref with keys C (string) and
C (arrayref of hashrefs with C and C keys);
passing C or a non-arrayref dies.
```
##### Output
```
Str -- complete HTML5 document; animated tooltip uses CSS translateY transition.
```
### Render\_Multi\_Series\_Line\_Chart\_With\_Legends
```
$html = $chart->render_multi_series_line_chart_with_legends($data);
```
Generates HTML and JavaScript code to render a chart of many lines with a static
colour legend. Each series gets a labelled colour swatch in the legend area.
Accepts the following arguments:
- `$data` - Same format as `render_multi_series_line_chart_with_tooltips`:
an array reference of `{ name, data }` series hashes.
Returns a string containing the complete HTML5 document. The stylesheet defines
a `.legend` CSS class used by the D3-generated legend elements.
#### Errors
- Throws `Data must be an array of hashes` when `$data` is not an ARRAY reference.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref' },
}
Each element of C<$data> is a hashref with keys C (string) and
C (arrayref of hashrefs with C and C keys);
passing C or a non-arrayref dies.
```
##### Output
```
Str -- complete HTML5 document; static colour legend rendered as SVG C elements
with the C<.legend> CSS class applied via D3 C<.attr("class", "legend")>.
```
### Render\_Multi\_Series\_Line\_Chart\_With\_Interactive\_Legends
```
$html = $chart->render_multi_series_line_chart_with_interactive_legends($data);
```
Generates HTML and JavaScript code to render a chart of many lines with interactive legends to filter, highlight or modify elements based on legend selections.
Accepts the following arguments:
- `$data` - Same format as `render_multi_series_line_chart_with_tooltips`:
an array reference of `{ name, data }` series hashes.
Returns a string containing the complete HTML5 document. Clicking a legend entry
toggles that series' opacity using an `isVisible` boolean flag in the D3 click
handler (opacity is set to `isVisible ? 0 : 1` on each click).
#### Errors
- Throws `Data must be an array of hashes` when `$data` is not an ARRAY reference.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref' },
}
Each element of C<$data> is a hashref with keys C (string) and
C (arrayref of hashrefs with C and C keys);
passing C or a non-arrayref dies.
```
##### Output
```
Str -- complete HTML5 document; legend clicks toggle series visibility.
The C JS variable tracks current visibility state.
Opacity toggled by C.
```
### Render\_Scatter\_Chart\_Snippet
```perl
my $fragment = $chart->render_scatter_chart_snippet($data);
my $fragment = $chart->render_scatter_chart_snippet($data, \%opts);
# $fragment->{svg_id} - the id attribute of the element
# $fragment->{html} - embeddable HTML fragment (style + svg + script)
```
Generates an embeddable HTML fragment for a scatter plot with mouseover
tooltips. Returns a fragment with no `, `, `, or
` wrapper; the caller is responsible for loading D3 in the page.
#### Arguments
- `$data` - An array reference of data points. Each point is an array
reference with two required numeric elements (x, y) and an optional third
hash reference of extra key/value pairs shown as extra tooltip rows.
```
[$x, $y] # basic point
[$x, $y, \%row] # point with extra tooltip data
```
- `\%opts` - Optional hash reference:
- `id` (string, default `'scatter_chart'`) - `id` of the ` element.
- `color` (CSS colour or `'categorical'`, default `'steelblue'`) -
Fill colour for the data points. `'categorical'` uses the Tableau-10 palette.
- `x_label` (string, default `''`) - Label for the X axis.
- `y_label` (string, default `''`) - Label for the Y axis.
- `value_label` (string, default `'Value'`) - Prefix for the tooltip value row.
- `animated` (boolean, default 0) - If true, circles fade in from
opacity 0 on page load (400 ms). Respects `prefers-reduced-motion`.
- `responsive` (boolean, default 0) - See `render_bar_chart_snippet`.
#### Return Value
A hash reference with `svg_id` (string) and `html` (Perl character string).
#### Errors
- Dies with `'Data must be an array of arrays'` when `$data` is not an ARRAY ref.
- Dies with `'Each data point must be an array reference'` when an element is not an ARRAY ref.
- Dies with `'Each data point must have at least 2 elements'` when a point has fewer than 2 items.
- Dies with `'X value must be numeric'` when the x element is not a number.
- Dies with `'Y value must be numeric'` when the y element is not a number.
#### Api Specification
```perl
{
data => { type => 'arrayref' },
opts => {
type => 'hashref',
optional => 1,
keys => {
id => { type => 'string', optional => 1 },
color => { type => 'string', optional => 1, default => 'steelblue' },
x_label => { type => 'string', optional => 1, default => '' },
y_label => { type => 'string', optional => 1, default => '' },
value_label => { type => 'string', optional => 1, default => 'Value' },
animated => { type => 'boolean', optional => 1, default => 0 },
responsive => { type => 'boolean', optional => 1, default => 0 },
},
},
}
```
### Render\_Table\_Snippet
```perl
my $fragment = $chart->render_table_snippet($data);
my $fragment = $chart->render_table_snippet($data, \%opts);
# $fragment->{table_id} - the id attribute of the element
# $fragment->{html} - embeddable HTML fragment (style + table + script)
```
Generates an embeddable HTML fragment for a sortable, filterable data table.
Returns a fragment with no page-shell wrapper; the caller loads D3 if needed.
#### Arguments
- `$data` - An array reference of row array references. The first row
is treated as the header row. Every subsequent row must have the same number
of columns as the header.
```
[ ['Name', 'Value', 'Category'], # header
['Alpha', 300, 'A'],
['Beta', 150, 'B'],
]
```
- `\%opts` - Optional hash reference:
- `id` (string, default `'data_table'`) - `id` of the ` element.
- `sortable` (boolean, default 1) - If true, clicking a column header
sorts the table by that column (toggle ascending/descending).
- `caption` (string, default `''`) - Optional ` element text.
#### Return Value
A hash reference with `table_id` (string) and `html` (Perl character string).
Note: returns `table_id`, not `svg_id`, because this method renders an HTML
table rather than an SVG chart.
#### Errors
- Dies with `'Data must be an array of arrays'` when `$data` is not an ARRAY ref.
- Dies with `'Data must have at least one row (header row)'` when `$data` is empty.
- Dies with `'Each row must be an array reference'` when a row is not an ARRAY ref.
#### Api Specification
```perl
{
data => { type => 'arrayref' },
opts => {
type => 'hashref',
optional => 1,
keys => {
id => { type => 'string', optional => 1, default => 'data_table' },
sortable => { type => 'boolean', optional => 1, default => 1 },
caption => { type => 'string', optional => 1, default => '' },
},
},
}
```
### Render\_Stacked\_Bar\_Snippet
```perl
my $result = $chart->render_stacked_bar_snippet(\@rows, \%opts);
```
Generates an embeddable stacked bar chart (no page shell, no CDN tag).
Each element of `\@rows` is a hashref with three keys named by `opts`:
`cat_col` (the X-axis grouping), `seg_col` (the stacking segment), and
`val_col` (the numeric measure). Multiple rows sharing the same
cat+seg combination are summed.
Accepted `\%opts` keys:
- `cat_col` (string, default `'cat'`) - row key for the X-axis category.
- `seg_col` (string, default `'seg'`) - row key for the stacking segment.
- `val_col` (string, default `'val'`) - row key for the numeric value.
- `orient` (string `'v'` or `'h'`, default `'v'`) - bar orientation.
- `scheme` (string, default `'tableau10'`) - D3 categorical colour scheme.
Supported: `tableau10`, `category10`, `set2`, `set3`, `paired`.
- `x_label` (string, optional) - axis label shown below the category axis.
- `sort` (string, optional) - sort categories: `'value'` (desc total)
or `'label'` (alpha).
- `id` (string, optional) - override the default `svg_id` value.
- `responsive` (boolean, optional) - SVG responsive sizing override.
Returns `{ svg_id => 'stacked_bar', html => Str }`.
#### Errors
- Throws `Data must be an array of hashes` when `$data` is not an ARRAY reference.
- Throws `Each data point must be a hash reference` when a row is not a hashref.
- Throws `Value must be numeric` when a value field is not a number.
- Throws `orient must be 'v' or 'h'` for an invalid `orient` value.
- Throws `sort must be 'value' or 'label'` for an invalid `sort` value.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref' },
opts => {
type => 'hashref',
optional => 1,
keys => {
cat_col => { type => 'string', optional => 1, default => 'cat' },
seg_col => { type => 'string', optional => 1, default => 'seg' },
val_col => { type => 'string', optional => 1, default => 'val' },
orient => { type => 'string', optional => 1, default => 'v' },
scheme => { type => 'string', optional => 1, default => 'tableau10' },
x_label => { type => 'string', optional => 1, default => '' },
sort => { type => 'string', optional => 1 },
id => { type => 'string', optional => 1, default => 'stacked_bar' },
responsive => { type => 'boolean', optional => 1 },
},
},
}
```
##### Output
```perl
HashRef -- { svg_id => Str, html => Str }
```
### Render\_Combo\_Snippet
```perl
my $result = $chart->render_combo_snippet(\@rows, \%opts);
```
Generates an embeddable combo chart: bars for one measure on the left Y
axis, a line for another measure on the right Y axis, sharing the same
X (category) axis.
Each element of `\@rows` is a hashref with at least three keys named by
`opts`: `x_col` (X-axis label), `bar_col` (bar measure), and
`line_col` (line measure).
Accepted `\%opts` keys:
- `x_col` (string, default `'x'`) - row key for the X-axis label.
- `bar_col` (string, default `'bar_val'`) - row key for the bar measure.
- `line_col` (string, default `'line_val'`) - row key for the line measure.
- `bar_label` (string, default `'Bar'`) - legend/axis label for bars.
- `line_label` (string, default `'Line'`) - legend/axis label for line.
- `bar_color` (string, optional CSS colour, default `'steelblue'`) - bar fill.
- `line_color` (string, optional CSS colour, default `'#e15759'`) - line stroke.
- `id` (string, optional) - override the default `svg_id` value.
- `responsive` (boolean, optional) - SVG responsive sizing override.
Returns `{ svg_id => 'combo_chart', html => Str }`.
#### Errors
- Throws `Data must be an array of hashes` when `$data` is not an ARRAY reference.
- Throws `Each data point must be a hash reference` when a row is not a hashref.
- Throws `Bar value must be numeric` when a bar value field is not a number.
- Throws `Line value must be numeric` when a line value field is not a number.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref' },
opts => {
type => 'hashref',
optional => 1,
keys => {
x_col => { type => 'string', optional => 1, default => 'x' },
bar_col => { type => 'string', optional => 1, default => 'bar_val' },
line_col => { type => 'string', optional => 1, default => 'line_val' },
bar_label => { type => 'string', optional => 1, default => 'Bar' },
line_label => { type => 'string', optional => 1, default => 'Line' },
bar_color => { type => 'string', optional => 1, default => 'steelblue' },
line_color => { type => 'string', optional => 1, default => '#e15759' },
id => { type => 'string', optional => 1, default => 'combo_chart' },
responsive => { type => 'boolean', optional => 1 },
},
},
}
```
##### Output
```perl
HashRef -- { svg_id => Str, html => Str }
```
### Render\_Treemap\_Snippet
```perl
my $result = $chart->render_treemap_snippet(\@rows_or_tree, \%opts);
```
Generates an embeddable treemap (no page shell, no CDN tag).
Leaf area is proportional to the numeric measure.
Accepts two data formats:
- **Flat path** (arrayref of hashrefs): each row must have a `path`
key (e.g. `'Root/A/X'`) and a `value` key. The module converts this
to a D3 stratify hierarchy in JS. Override the path separator with
`opts->{path_sep}`.
- **Nested tree** (hashref): a pre-built D3-compatible hierarchy
with `name`/`children`/`value` structure. Passed directly to
`d3.hierarchy()`.
Accepted `\%opts` keys:
- `path_sep` (string, default `'/'`) - path separator (flat format only).
- `scheme` (string, default `'tableau10'`) - D3 categorical colour scheme.
Supported: `tableau10`, `category10`, `set2`, `set3`, `paired`.
- `label` (boolean, default `1`) - show node labels inside cells.
- `id` (string, optional) - override the default `svg_id` value.
- `responsive` (boolean, optional) - SVG responsive sizing override.
Returns `{ svg_id => 'treemap', html => Str }`.
#### Errors
- Throws `Data must be an array of hashes or a hash tree`
when `$data` is neither an ARRAY nor a HASH reference.
- Throws `Each flat row must be a hash reference` when a flat row is not a hashref.
- Throws `Each flat row must have a 'path' key` when a flat row lacks `path`.
- Throws `Each flat row must have a numeric 'value' key` when a value is not numeric.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref | hashref' },
opts => {
type => 'hashref',
optional => 1,
keys => {
path_sep => { type => 'string', optional => 1, default => '/' },
scheme => { type => 'string', optional => 1, default => 'tableau10' },
label => { type => 'boolean', optional => 1, default => 1 },
id => { type => 'string', optional => 1, default => 'treemap' },
responsive => { type => 'boolean', optional => 1 },
},
},
}
```
##### Output
```perl
HashRef -- { svg_id => Str, html => Str }
```
### Render\_Histogram\_Snippet
```perl
my $result = $chart->render_histogram_snippet(\@values, \%opts);
```
Generates an embeddable frequency histogram (no page shell, no CDN tag).
`\@values` is an arrayref of numeric scalars (already extracted and
coerced by the caller).
Accepted `\%opts` keys:
- `bins` (integer or `undef`, default `20`) - number of bins.
Pass `undef` for automatic bin count using Sturges' rule:
`ceil(log2(n) + 1)`.
- `x_label` (string, optional) - label shown below the X axis.
- `color` (string, default `'steelblue'`) - bar fill colour.
- `id` (string, optional) - override the default `svg_id` value.
- `responsive` (boolean, optional) - SVG responsive sizing override.
Returns `{ svg_id => 'histogram', html => Str }`.
#### Errors
- Throws `Data must be an array of numeric values` when `$data` is
not an ARRAY reference.
- Throws `Each value must be numeric` when any element is non-numeric.
- Throws `bins must be a positive integer` when `bins` is defined
but not a positive integer.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref' },
opts => {
type => 'hashref',
optional => 1,
keys => {
bins => { type => 'integer', optional => 1, default => 20 },
x_label => { type => 'string', optional => 1, default => '' },
color => { type => 'string', optional => 1, default => 'steelblue' },
id => { type => 'string', optional => 1, default => 'histogram' },
responsive => { type => 'boolean', optional => 1 },
},
},
}
```
##### Output
```perl
HashRef -- { svg_id => Str, html => Str }
```
## Support
This module is provided as-is without any warranty.
Please report any bugs or feature requests to `bug-html-d3 at rt.cpan.org`,
or through the web interface at
[http://rt.cpan.org/NoAuth/ReportBug.html?Queue=HTML-D3](http://rt.cpan.org/NoAuth/ReportBug.html?Queue=HTML-D3).
I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.
You can find documentation for this module with the perldoc command.
```
perldoc HTML::D3
```
You can also look for information at:
## Bugs
It would help to have the render routine to return the head and body components separately.
## See Also
- [Configure an Object at Runtime](https://metacpan.org/pod/Object%3A%3AConfigure)
- [Test Dashboard](https://nigelhorne.github.io/HTML-D3/coverage/)
## Author
Nigel Horne
## Formal Specification
### Render\_Bar\_Chart
```
render_bar_chart : HTML::D3 × (ArrayRef | undef) → Str ∪ ⊥
pre data = undef ⇒ die "Data is not optional"
pre ref(data) ≠ 'ARRAY' ⇒ die "Data must be an array of arrays"
post result ∈ Str
post " N
⇒ |result_slices| = N ∧ "Other" ∈ result_labels
post opts.separator = S ⇒ " S " ⊆ result.html (HTML legend: label S value (pct%))
```
### Render\_Heatmap\_Snippet
```
render_heatmap_snippet :
HTML::D3 × (ArrayRef | undef) × (HashRef | undef) → HashRef ∪ ⊥
pre ref(data) ≠ 'ARRAY' ⇒ die "Data must be an array of arrays"
pre ∃ pt ∈ data . ref(pt) ≠ 'ARRAY'
⇒ die "Each data point must be an array reference"
pre ∃ pt ∈ data . |pt| < 3 ⇒ die "Each data point must have at least 3 elements"
pre ∃ pt ∈ data . defined(pt[2]) ∧ ¬numeric(pt[2])
⇒ die "Value must be numeric"
pre opts.color_scheme = S ∧ S ∉ {YlOrRd,Blues,Greens,Purples,RdPu,YlGnBu}
⇒ die "Unknown color_scheme: S"
pre opts.cell_padding = N ∧ (N < 0 ∨ N > 8)
⇒ die "cell_padding must be between 0 and 8"
pre ∀ pt ∈ data . pt[2] = undef ⇒ pt ∉ result -- undef rows skipped
pre ∃ pt₁,pt₂ ∈ data . pt₁[0]=pt₂[0] ∧ pt₁[1]=pt₂[1]
⇒ last-write wins
post result ∈ HashRef
post result.svg_id = "heatmap"
post result.html ∈ Str
post " N
⇒ |result_bars| = N ∧ "Other" ∈ result_labels
```
### Render\_Scatter\_Chart\_Snippet
```
render_scatter_chart_snippet :
HTML::D3 × (ArrayRef | undef) × (HashRef | undef) → HashRef ∪ ⊥
pre ref(data) ≠ 'ARRAY' ⇒ die "Data must be an array of arrays"
pre ∃ pt ∈ data . ref(pt) ≠ 'ARRAY'
⇒ die "Each data point must be an array reference"
pre ∃ pt ∈ data . |pt| < 2 ⇒ die "Each data point must have at least 2 elements"
pre ∃ pt ∈ data . ¬numeric(pt[0])
⇒ die "X value must be numeric"
pre ∃ pt ∈ data . ¬numeric(pt[1])
⇒ die "Y value must be numeric"
post result ∈ HashRef
post result.svg_id = opts.id // "scatter_chart"
post result.html ∈ Str
post "" ∉ result.html ∧ "<\/b>" ∈ result.html
```
### Render\_Treemap\_Snippet
```
render_treemap_snippet :
HTML::D3 × (ArrayRef | HashRef | undef) × (HashRef | undef) → HashRef ∪ ⊥
pre ref(data) ∉ {'ARRAY','HASH'}
⇒ die "Data must be an array of hashes or a hash tree"
pre ref(data) = 'ARRAY' ∧ ∃ row ∈ data . ref(row) ≠ 'HASH'
⇒ die "Each flat row must be a hash reference"
pre ref(data) = 'ARRAY' ∧ ∃ row ∈ data . ¬exists(row.path)
⇒ die "Each flat row must have a 'path' key"
pre ref(data) = 'ARRAY' ∧ ∃ row ∈ data . ¬numeric(row.value)
⇒ die "Each flat row must have a numeric 'value' key"
post result ∈ HashRef
post result.svg_id = opts.id // "treemap"
post result.html ∈ Str
post "" ∉ result ∧ "<\/b>" ∈ result
```
### Render\_Multi\_Series\_Line\_Chart\_With\_Tooltips
```
render_multi_series_line_chart_with_tooltips : HTML::D3 × (ArrayRef | undef) → Str ∪ ⊥
pre ref(data) ≠ 'ARRAY' ⇒ die "Data must be an array of hashes"
post result ∈ Str
post "" ∉ result ∧ "<\/b>" ∈ result
```
### Render\_Multi\_Series\_Line\_Chart\_With\_Animated\_Tooltips
```
render_multi_series_line_chart_with_animated_tooltips : HTML::D3 × (ArrayRef | undef) → Str ∪ ⊥
pre ref(data) ≠ 'ARRAY' ⇒ die "Data must be an array of hashes"
post result ∈ Str
post "" ∉ result ∧ "<\/b>" ∈ result
```
### Render\_Multi\_Series\_Line\_Chart\_With\_Legends
```
render_multi_series_line_chart_with_legends : HTML::D3 × (ArrayRef | undef) → Str ∪ ⊥
pre ref(data) ≠ 'ARRAY' ⇒ die "Data must be an array of hashes"
post result ∈ Str
post "