## Name
HTML::D3 - A simple Perl module for generating charts using D3.js.
## Version
Version 0.27
## 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.
Text in a chart's data and options is written into a `
```
#### 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\_Multi\_Series\_Line\_Chart\_Snippet
```perl
my $fragment = $chart->render_multi_series_line_chart_snippet(\@series);
my $fragment = $chart->render_multi_series_line_chart_snippet(\@series, \%opts);
# $fragment->{svg_id} - the id attribute of the element
# $fragment->{html} - embeddable HTML fragment (style + svg + script)
```
Generates an embeddable multi-series line chart fragment. Unlike
`render_multi_series_line_chart_with_interactive_legends`, this method returns
a bare fragment with no ``, ``, or `` wrapper;
D3.js must be loaded by the host page.
#### Arguments
- `\@series` - An array reference of series. Each series is a hash
reference with a `name` (string) and a `data` array reference of
`{ label => Str, value => Num }` points:
```perl
[
{ name => 'North', data => [ { label => 'Jan', value => 12 }, ... ] },
{ name => 'South', data => [ { label => 'Jan', value => 8 }, ... ] },
]
```
Series need not share labels: the X domain is the union of every series' labels,
in first-seen order. One line and one set of dots is drawn per series, and a
clickable legend toggles each series on and off.
- `\%opts` - Optional hash reference:
- `scheme` (string, default `'tableau10'`) - D3 categorical colour
scheme (for example `'category10'`, `'set2'`, `'set3'`, `'paired'`).
`categorical_schemes()` lists the names, and `palette()` hands a Perl caller
the colours of one.
- `x_label` (string, default `''`) - Label shown below the X axis.
- `y_label` (string, default `''`) - Label shown beside the Y axis.
- `animated` (boolean, default 0) - If true each line draws itself left
to right by animating its stroke dash offset. Respects
`prefers-reduced-motion`.
- `responsive` (boolean, optional) - SVG responsive sizing override.
- `id` (string, default `'chart'`) - `id` of the ` element.
Returns `{ svg_id => 'chart', html => Str }`.
#### Errors
- Throws `Data must be an array of series` when `\@series` is not an
ARRAY reference.
- Throws `Each series must be a hashref with name and data` when a
series is not a hashref, has no `name`, or has a `data` that is not an ARRAY
reference.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref' },
opts => {
type => 'hashref',
optional => 1,
keys => {
scheme => { type => 'string', optional => 1, default => 'tableau10' },
x_label => { type => 'string', optional => 1, default => '' },
y_label => { type => 'string', optional => 1, default => '' },
animated => { type => 'boolean', optional => 1, default => 0 },
responsive => { type => 'boolean', optional => 1 },
id => { type => 'string', optional => 1, default => 'chart' },
},
},
}
```
##### Output
```perl
HashRef -- { svg_id => 'chart', html => Str }
```
### 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), an optional third hash
reference of extra key/value pairs shown as extra tooltip rows, and an optional
fourth hash reference carrying the `series` (colour group) and `size` (bubble
radius) dimensions:
```perl
[$x, $y] # basic point
[$x, $y, \%row] # point with extra tooltip data
[$x, $y, \%row, { series => 'North', size => 42 }] # colour and size
```
- `\%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.
A value holding anything a CSS colour cannot, such as a quote or `<`, is
ignored and the default used.
- `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.
- `colour_by_series` (boolean, default 0) - Colour each point by its
`series` value instead of by point index, and draw a legend listing the series
to the right of the plot. Ignored for points with no `series` value.
- `scheme` (string, default `'tableau10'`) - D3 categorical colour
scheme used when `colour_by_series` is set, for example `'category10'`,
`'set2'`, `'set3'`, or `'paired'`.
`categorical_schemes()` lists the names, and `palette()` hands a Perl caller
the colours of one.
- `series_col` (string, default `'Series'`) - Row label for the series
value in the tooltip.
- `size_col` (string, default `'Size'`) - Row label for the size value
in the tooltip.
- `radius_range` (arrayref of two numbers, default `[3, 15]`) - Pixel
radii mapped from the smallest and largest observed `size` value. The mapping
is by area (`d3.scaleSqrt`), so a point twice as large is drawn with four
times the area. A point with no `size` value is drawn at the lower radius.
- `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' },
colour_by_series => { type => 'boolean', optional => 1, default => 0 },
scheme => { type => 'string', optional => 1, default => 'tableau10' },
series_col => { type => 'string', optional => 1, default => '' },
size_col => { type => 'string', optional => 1, default => '' },
radius_range => { type => 'arrayref', optional => 1, default => [3, 15] },
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` - the names
`categorical_schemes()` returns, whose colours `palette()` makes available to
Perl.
- `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.
A value holding anything a CSS colour cannot, such as a quote or `<`, is
ignored and the default used.
- `line_color` (string, optional CSS colour, default `'#e15759'`) - line stroke.
Checked as `bar_color` is.
- `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` - the names
`categorical_schemes()` returns, whose colours `palette()` makes available to
Perl.
- `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)`. Ignored when `binned` is set.
- `binned` (boolean, default 0) - treat `$data` as pre-computed bins
rather than as raw values. Each element is a hashref with a `count` and
either a `label` or a numeric `lo`/`hi` pair from which the label `[lo,hi)`
is derived:
```perl
{ label => '[0,10)', count => 3 }
{ lo => 10, hi => 20, count => 5 }
```
The caller owns the binning, so `d3.bin()` is never called: one bar is drawn
per entry, in the order supplied, and the supplied counts are authoritative.
The bin labels are drawn rotated. The plot gives up as much room as they need,
up to half the chart's height and a quarter of its width, so that they and
`x_label` do not overlap and stay inside the chart.
- `scheme` (string, optional) - D3 categorical colour scheme (for example
`'tableau10'` or `'category10'`) whose first colour is used as the bar fill
when `color` is not given.
That colour is `colour_at($scheme, 0)`, so a caller shading the same data by
hand starts from the same colour the bars do.
- `x_label` (string, optional) - label shown below the X axis.
- `color` (string, default `'steelblue'`) - bar fill colour.
A value holding anything a CSS colour cannot, such as a quote or `<`, is
ignored and the default used.
- `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.
- Throws `Data must contain at least one bin` when `binned` is set and
`$data` holds no bins.
- Throws `Each pre-binned entry must be a hash reference` when a
pre-binned element is not a hashref.
- Throws `Bin count must be numeric` when a pre-binned `count` is
missing or not numeric.
- Throws `Bin count must not be negative` when a pre-binned `count` is
negative.
- Throws `Each pre-binned entry must have a label or numeric lo and hi`
when a pre-binned entry has neither a `label` nor a numeric `lo`/`hi` pair.
#### Api Specification
##### Input
```perl
{
data => { type => 'arrayref' },
opts => {
type => 'hashref',
optional => 1,
keys => {
bins => { type => 'integer', optional => 1, default => 20 },
binned => { type => 'boolean', optional => 1, default => 0 },
x_label => { type => 'string', optional => 1, default => '' },
color => { type => 'string', optional => 1, default => 'steelblue' },
scheme => { type => 'string', optional => 1 },
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\_Multi\_Series\_Line\_Chart\_Snippet
```
render_multi_series_line_chart_snippet :
HTML::D3 × (ArrayRef | undef) × (HashRef | undef) → HashRef ∪ ⊥
pre ref(data) ≠ 'ARRAY' ⇒ die "Data must be an array of series"
pre ∃ s ∈ data . ref(s) ≠ 'HASH'
⇒ die "Each series must be a hashref with name and data"
pre ∃ s ∈ data . ¬defined(s.name) ∨ ref(s.data) ≠ 'ARRAY'
⇒ die "Each series must be a hashref with name and data"
post result ∈ HashRef
post result.svg_id = opts.id // "chart"
post result.html ∈ Str
post " expression
post opts.animated = 1 ⇒ "stroke-dashoffset" ⊆ result.html
∧ "prefers-reduced-motion" ⊆ result.html
```
### 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 "