Anton Antonov
JavaScript::D3 Raku package
December 2022
Here we load some packages that are used to generate, summarize, and modify datasets:
use Data::Generators;
use Data::Reshapers;
use Data::Summarizers;
use Data::ExampleDatasets;
This loads the "JavaScript::D3" package:
use JavaScript::D3;
%% javascript
require.config({
paths: {
d3: 'https://d3js.org/d3.v7.min'
}});
require(['d3'], function(d3) {
console.log(d3);
});
The code above can be obtained with the package function js-d3-config
:
js-d3-config()
require.config({ paths: { d3: 'https://d3js.org/d3.v7.min' }}); require(['d3'], function(d3) { console.log(d3); });
Verify that a D3 plot is obtained via a JavaScript cell (taken from [SF1]):
%%javascript
(function(element) { require(['d3'], function(d3) {
var data = [1, 2, 4, 8, 16, 8, 4, 2, 1]
var svg = d3.select(element.get(0)).append('svg')
.attr('width', 400)
.attr('height', 200);
svg.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr("cx", function(d, i) {return 40 * (i + 1);})
.attr("cy", function(d, i) {return 100 + 30 * (i % 3 - 1);})
.style("fill", "#1570a4")
.transition().duration(2000)
.attr("r", function(d) {return 2*d;})
;
}) })(element);
%% > js
say js-d3-list-plot(random-real(12,1000), height=>500, background=>'rgb(30,70,110)', color=>'yellow', title => "Yellow points");
%% js
my @ds2 = random-tabular-dataset(1200, <x y>,
generators=> {
x => { random-variate(NormalDistribution.new(30,12), $_)},
y => { random-variate(NormalDistribution.new(800,70), $_)}});
say dimensions(@ds2);
js-d3-list-plot(@ds2, height=>500, background=>'white', color=>'orange');
(1200 2)
%% js
js-d3-list-line-plot(@ds2.sort({ $_<x> }),
height=>500,
background=>'white', color=>'lightblue',
title => "List line plot",
x-axis-label=>'X coordinates',
y-axis-label=>'Y coordinates',
margins => %(top=>80, left=>60)
);
my @dsXYG = random-tabular-dataset(400, <x y group>,
generators => { x => { random-real(100, $_) },
y => { random-real(10, $_) },
group => <a b c d> });
@dsXYG = @dsXYG.map( -> $r { given $r<group> {
when 'a' { $r<y> = 1.2*$r<x> + $r<y> }
when 'b' { $r<y> = 5*sqrt($r<x>) + $r<y>}
when 'c' { $r<y> = $r<y> - $r<x>/3 + 50 }
};
$r
});
say dimensions(@dsXYG);
say deduce-type(@dsXYG);
(400 3) Vector(Struct([group, x, y], [Str, Num, Num]), 400)
%%js
js-d3-list-line-plot(@dsXYG.sort({ $_<x> }))
my @dsTest2 = random-tabular-dataset(12, <Country Value>, generators=>{Country => <USA UK UA RU CH BG FR GE ES PL DK SW>, Value => { random-real(100, $_) } } );
records-summary(@dsTest2);
dimensions(@dsTest2)
+--------------+------------------------------+ | Country | Value | +--------------+------------------------------+ | UA => 3 | Min => 12.526969888975048 | | BG => 2 | 1st-Qu => 37.36829211544143 | | PL => 2 | Mean => 54.34345039167076 | | CH => 1 | Median => 53.2452138507842 | | ES => 1 | 3rd-Qu => 71.95311337298517 | | DK => 1 | Max => 90.21550174232574 | | FR => 1 | | | (Other) => 1 | | +--------------+------------------------------+
(12 2)
%% js
rename-columns(@dsTest2, {Country => 'variable', Value => 'value'}) ==> js-d3-bar-chart(background => 'rgb(10, 10, 13)', color => 'rgb(160,70,70)')
%% js
js-d3-bar-chart(random-real(120,45), width=>1000)
%% > js
say js-d3-histogram(
random-variate(NormalDistribution.new(120,10), 500),
height=>500,
background=>'#484848',
title=>'Normal distribution example',
x-axis-label=>'random value',
y-axis-label=>'counts', margins => {top=>120} );
my $nPoints = 100;
my @arr3d = transpose( (random-real(12, $nPoints), random-real(12, $nPoints), random-real(12, $nPoints)) );
deduce-type(@arr3d)
Vector(Vector(Atom((Numeric)), 3), 100)
%%js
js-d3-bubble-chart(@arr3d,
color=>'rgb(255,180,0)',
background=>'rgb(50,56,65)',
tooltip=>Whatever)
my @ds3DGroups = random-tabular-dataset(100, <x y z group>,
generators => { x => { random-real(20, $_) },
y => { random-variate(NormalDistribution.new(200,50), $_) },
z => { random-variate(NormalDistribution.new(20,12), $_) },
group => <aspirin biscuit cookie>
} );
records-summary(@ds3DGroups, field-names=><x y z group>);
say deduce-type(@ds3DGroups);
+-------------------------------+------------------------------+-------------------------------+---------------+ | x | y | z | group | +-------------------------------+------------------------------+-------------------------------+---------------+ | Min => 0.28563882358593196 | Min => 58.657594428180005 | Min => 0.17337140098472048 | aspirin => 35 | | 1st-Qu => 6.17639542295039 | 1st-Qu => 164.17644575647307 | 1st-Qu => 11.932531777303495 | cookie => 35 | | Mean => 9.93982614234913 | Mean => 198.87279903218416 | Mean => 19.125657121928466 | biscuit => 30 | | Median => 9.577108853714691 | Median => 195.37934456337763 | Median => 17.854686316624154 | | | 3rd-Qu => 14.653302817677424 | 3rd-Qu => 228.75774234863587 | 3rd-Qu => 25.419818857852356 | | | Max => 19.886081343128687 | Max => 342.7947990427373 | Max => 61.07119845114756 | | +-------------------------------+------------------------------+-------------------------------+---------------+ Vector(Struct([group, x, y, z], [Str, Num, Num, Num]), 100)
%%js
js-d3-bubble-chart(@ds3DGroups,
x-axis-label=>'x coordinates',
y-axis-label=>'Normal distribution',
plot-label=>'Bubble chart over groups',
background=>'',
margins => %(left=>60, top=>60),
opacity=>0.5):tooltip:legends
my $k=0;
my @dsXY = (^1200)>>.rand>>.sqrt.map({ %(x=>$k++, y=>$_) });
#records-summary(@dsXY);
my $refDate = DateTime.new('2000-01-01');
my @dsTS = @dsXY.map({ %( date => ($refDate + $_<x> * 10e4).DateTime, value => $_<y> ) });
#records-summary(@dsTS);
#say dimensions(@dsTS);
my @dsTS2 = @dsTS.map({ %( date => $_<date>.Str.substr(0,10), value => $_<value>, group => <a b>.pick ) }).map({ if $_<group> eq 'a' { $_<value> *= -1 }; $_ });
records-summary(@dsTS2);
dimensions(@dsTS2)
+--------------------------------+--------------------+----------+ | value | date | group | +--------------------------------+--------------------+----------+ | Min => -33.09507540227694 | 2002-07-13 => 1 | a => 604 | | 1st-Qu => -14.866937369813902 | 2003-09-18 => 1 | b => 596 | | Mean => 0.018421512842551307 | 2000-10-05 => 1 | | | Median => -0.48072814381940876 | 2002-03-23 => 1 | | | 3rd-Qu => 14.734912882328251 | 2001-02-24 => 1 | | | Max => 33.96569042426868 | 2002-07-24 => 1 | | | | 2000-03-09 => 1 | | | | (Other) => 1193 | | +--------------------------------+--------------------+----------+
(1200 3)
%% js
js-d3-date-list-plot(@dsTS2, width=>1000);
[OV1] Olivia Vane, "D3 JavaScript visualisation in a Python Jupyter notebook", (2020), livingwithmachines.ac.uk.
[SF1] Stefaan Lippens, Custom D3.js Visualization in a Jupyter Notebook, (2018), stefaanlippens.net.
[AAp1] Anton Antonov, Data::Reshapers Raku package, (2021-2022), GitHub/antononcube.
[AAp2] Anton Antonov, Text::Plot Raku package, (2022), GitHub/antononcube.
[BD1] Brian Duggan, Jupyter::Kernel Raku package, (2017-2022), GitHub/bduggan.
[MLp1] Moritz Lenz, SVG::Plot Raku package (2009-2018), GitHub/moritz.