Skip to content

Instantly share code, notes, and snippets.

@DrYak
Last active September 30, 2019 11:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DrYak/e8cee92b5d1280168d73b735011f33f6 to your computer and use it in GitHub Desktop.
Save DrYak/e8cee92b5d1280168d73b735011f33f6 to your computer and use it in GitHub Desktop.
experimental local haplotype report
#!/usr/bin/env perl
use strict;
use Encode;
my $path = 'support';
my $report_html = <<'END_MESSAGE';
<!DOCTYPE html>
<meta charset="utf-8">
<title>Stacked-to-Grouped Bars</title>
<link rel="stylesheet" type="text/css" href="./inspector.css">
<script src="https://d3js.org/d3.v5.min.js"></script>
<body>
<form id=form name=form>
<label style="margin-right:0.5em;"><input type=radio name=radio value="stacked" onchange="chrt.update(form.radio.value);" checked> Stacked</label>
<label style="margin-right:0.5em;"><input type=radio name=radio value="grouped" onchange="chrt.update(form.radio.value);"> Grouped</label>
<label style="margin-right:0.5em;">Palette <select name=palette onChange="chrt.recolor(form.palette.value);"><option value="blue" selected>Blues</option><option value="ryb" selected>RdYlBu</option><option value="spectral" selected>Spectral</option><option value="rainbow">Less Angry Rainbow</option><option value="set3">Discrete Set3</option><option value="paired">Discrete Paired</option></select></label>
</form>
<div style="position: absolute;
overflow: hidden;
top: 0;
right: 0;
z-index: 9999;
"><button onclick="filterselector.toggle()
">Filter:</button> <br/><svg id="scatter_filter"></div>
<svg id="stackedSVG" width=975 height=700 viewBox="0,0,975,700"></svg>
<script>
function selector() {
// set the dimensions and margins of the graph
const margin = {top: 10, right: 30, bottom: 30, left: 60},
width = 460 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
// append the svg object to the body of the page
const svg = d3.select("#scatter_filter")
.attr("cursor", "crosshair")
.on("click", function() {
var p = d3.mouse(this)
;
updatefilter(x.invert(p[0] - margin.left), y.invert(p[1], margin.top));
})
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("overflow", "hidden")
.append("g")
.attr("transform",
`translate(${margin.left},${margin.top})`);
//Read the data
const data = @PS_SCATTER@;
// Add X axis
const x = d3.scaleLinear()
.domain([0, 1.2])
.range([ 0, width ]);
svg.append("g")
.attr("transform", `translate(0,${height})`)
.call(d3.axisBottom(x));
// Add Y axis
const y = d3.scaleLog()
.domain([0.01, 10000])
.range([ height, 0 ])
.base(10);
svg.append("g")
.call(d3.axisLeft(y));
// Add dots
svg.append('g')
.selectAll("dot")
.data(data)
.enter()
.append("circle")
.attr("cx", d => x(d[0]) )
.attr("cy", d => y(d[1]) )
.attr("r", 1.5)
.style("fill", "#69b3a2")
;
// Add selector
const filterselector = svg
.append('g')
.style("fill", "#69b3a2")
.style("opacity", ".2")
.append("rect")
.attr("y", 0);
function updatefilter(p, s) {
const fx = x(p);
const fy = y(s);
filterselector.attr("x", fx).attr("width", width-fx)
.attr("height", fy);
}
var filter_visible = 1;
function toggle() {
svg.transition().duration(500).style('opacity', filter_visible ^= 1)
}
return Object.assign(svg.node(), {updatefilter, toggle});
};
var filterselector = selector();
filterselector.updatefilter(.9, 5);
const m = @M@; // number of values per series
const n = @N@; // number of series
const yz = @YZ_ARRAY@;
const xz = @XZ_ARRAY@; // list of X
const xp = @XP_ARRAY@; // window position to be used as X-axis label
function chart() {
const margin = ({top: 5, right: 5, bottom: 20, left: 30});
const width = 975;
const height = 500;
// for inspiration, go here: https://github.com/d3/d3-scale-chromatic#schemeAccent
const z = {
"blue": d3.scaleSequential(d3.interpolateBlues)
.domain([-0.5 * n, 1.5 * n]),
"ryb": d3.scaleSequential(d3.interpolateRdYlBu)
.domain([0, n]),
"spectral": d3.scaleSequential(d3.interpolateSpectral)
.domain([0, n]),
"rainbow": d3.scaleSequential(d3.interpolateRainbow)
.domain([0, 12]),
"set3": d3.scaleOrdinal(d3.schemeSet3)
.domain([0, n]),
"paired": d3.scaleOrdinal(d3.schemePaired)
.domain([0, n])
};
const y01z = d3.stack()
.keys(d3.range(n))
(d3.transpose(yz)) // stacked yz
.map((data, i) => data.map(([y0, y1]) => [y0, y1, i]));
const y1Max = d3.max(y01z, y => d3.max(y, d => d[1]));
const yMax = d3.max(yz, y => d3.max(y));
const y = d3.scaleLinear()
.domain([0, y1Max])
.range([height - margin.bottom, margin.top]);
const x = d3.scaleBand()
.domain(xz)
.rangeRound([margin.left, width - margin.right])
.padding(0.08);
const xAxis = svg => svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.style("font-size", `${Math.min((width/m).toFixed(2),10.00)}px`)
.call(d3.axisBottom(x).tickSizeOuter(0).tickFormat((d, i) => xp[i]));
const svg = d3.select('#stackedSVG')
.style("width", "100%")
.style("height", "auto");
const gs = svg.selectAll("g")
.data(y01z)
.enter().append("g")
.attr("fill", (d, i) => z["blue"](i))
const rect = gs.selectAll("rect")
.data(d => d)
.join("rect")
.attr("x", (d, i) => x(i))
.attr("y", height - margin.bottom)
.attr("width", x.bandwidth())
.attr("height", 0);
svg.append("g")
.call(xAxis)
.selectAll("text")
.attr("y", 0)
.attr("x", 7)
.attr("dy", ".35em")
.attr("transform", "rotate(90)")
.style("text-anchor", "start");
svg.append("g")
.attr("class", "axis")
.style("font-size", "8px")
.attr("transform", `translate(${margin.left}, 0)`)
.call(d3.axisLeft(y).ticks(null, "s"));
function transitionGrouped() {
y.domain([0, yMax]);
rect.transition()
.duration(500)
.delay((d, i) => i * 20)
.attr("x", (d, i) => x(i) + x.bandwidth() / n * d[2])
.attr("width", x.bandwidth() / n)
.transition()
.attr("y", d => y(d[1] - d[0]))
.attr("height", d => y(0) - y(d[1] - d[0]));
}
function transitionStacked() {
y.domain([0, y1Max]);
rect.transition()
.duration(500)
.delay((d, i) => i * 20)
.attr("y", d => y(d[1]))
.attr("height", d => y(d[0]) - y(d[1]))
.transition()
.attr("x", (d, i) => x(i))
.attr("width", x.bandwidth());
}
function update(layout) {
if (layout === "stacked") transitionStacked();
else transitionGrouped();
}
function recolor(palette) {
if (palette in z)
gs.transition()
.duration(500)
.delay((d, i) => i * 20)
.attr("fill", (d, i) => z[palette](i));
else
alert("Wrong color " + palette);
}
return Object.assign(svg.node(), {update, recolor});
}
var chrt = chart();
chrt.update('stacked');
</script>
</body>
END_MESSAGE
my @H; # all haplotypes (over all windows of complete run)
my %H;
my %W; # all windows
# my %d;
my @d; # per-haplotype list of all "position->reads"
my %HN; # per-window local number of local haplotypes
# for the filter's scatter plot
my @F;
my $file = 0;
opendir(my $dh, $path) or die "Can't open ${path}: $!";
while (readdir $dh) {
# "support/w-HXB2-5849-5950.reads-support.fas.gz"
next unless $_ =~ m{w-(?<chr>.*)-(?<w>[[:digit:]]+)-(?<e>[[:digit:]]+).reads-support.fas.gz};
print STDERR $file++ . " - <$_> : ";
my $w = $+{'w'}; # this windows' position
my $hn = 0; # counting haplotypes inside this windows
my $htot = 0;
open my $fh, "gunzip -kc $path/$_|" or die "Can't open ${path}: $!";
while (<$fh>) {
chomp;
# ">hap_3|posterior=1 ave_reads=1224.37"
next unless $_ =~ m{^\>(?<h>[^\|]+)\|posterior=(?<p>[[:digit:].]*) *ave_reads=(?<s>[[:digit:].]*)};
my $h=$+{'h'}; # haplotype name ('hap_nnn')
my $s=$+{'s'}; # support (as average number of reads per base)
my $p=$+{'p'}; # posterior
push @F, +[ $p, $s ];
$h =~ m{_(?<n>[[:digit:]]+)$}; # just the number of the haplotype
$H[$+{'n'}] = $h;
$H{$h} = $+{'n'};
$W{$w} = 1;
$htot++;
next unless ($s > 5.0 and $p > .8); # filter low quality
# if (exists $d{$h} and ref $d{$h} eq ref {}) {
if (exists $d[$hn] and ref $d[$hn] eq ref {}) {
$d[$hn]->{$w} = $s;
# $d{$h}->{$w} = $s;
} else {
$d[$hn] = +{ $w => $s };
# $d{$h} = +{ $w => $s };
}
$hn++;
}
close $fh;
$HN{$w} = $hn;
print STDERR "$htot haplotypes, $hn filtered\n";
}
close $dh;
print STDERR "creating report...";
# scatter plot for filter selector
my $PS_SCATTER = '[' . join(',', map { '[' . join(',', @{$_} ) . ']' } @F ) . ']';
# every single window
my @W = sort { $a <=> $b } keys %W;
my $m = @W;
# old style : every single haplotype...
my $n = @H;
die "\nIs there a missing haplotype ? Highest number is $n: $H[$#H] but only found " . (scalar keys %H) . "haplotypes"
if ( $n != scalar keys %H );
# ...actually no only keep the filtered
$n = @d;
my $XZ = '[' . join(',', ( 0 .. $#W) ) . ']';
my $NZ = '[' . join(',', map { $HN{$_} } @W ) . ']';
my $XP = '[' . join(',', @W ) . ']';
my $YZ = '[' . join(",\n", map { my $hd = $_;
'[' . join(',', map { (exists $hd->{$_} ) ? $hd->{$_} : 0 } @W) . ']'
} @d) . ']';
# my $YZ = '[' . join(",\n", map { my $h = $_;
# '[' . join(',', map { (exists $d{$h} and exists $d{$h}->{$_} ) ? $d{$h}->{$_} : 0 } @W) . ']'
# } @H) . ']';
$report_html =~ s{\@M\@}{$m};
$report_html =~ s{\@N\@}{$n};
$report_html =~ s{\@NZ_ARRAY\@}{$NZ};
$report_html =~ s{\@XZ_ARRAY\@}{$XZ};
$report_html =~ s{\@XP_ARRAY\@}{$XP};
$report_html =~ s{\@YZ_ARRAY\@}{$YZ};
$report_html =~ s{\@PS_SCATTER\@}{$PS_SCATTER};
open my $o, '>', "report.html" or die "Cannot write report";
print $o $report_html;
close $o;
print STDERR "done\n";
exit 0;
<!DOCTYPE html>
<meta charset="utf-8">
<title>Stacked-to-Grouped Bars</title>
<link rel="stylesheet" type="text/css" href="./inspector.css">
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<form id=form name=form>
<label style="margin-right:0.5em;"><input type=radio name=radio value="stacked" onchange="chrt.update(form.radio.value);" checked> Stacked</label>
<label style="margin-right:0.5em;"><input type=radio name=radio value="grouped" onchange="chrt.update(form.radio.value);"> Grouped</label>
</form>
<svg id="stackedSVG" width=975 height=700 viewBox="0,0,975,700"></svg>
<script>
const margin = ({top: 0, right: 0, bottom: 10, left: 0});
const width = 975;
const height = 500;
const m = 21; // number of values per series
const n = 5; // number of series
const yz = [[37,53.9142,69.9611,88.7078,70.8582,82.9792,81.906,90.9153,82,87.9981,76,94.7667,104.696,76,81,68,72,68,72.7003,64.8661,16],
[39.2597,47,67,65,62.9975,76.9958,74,90,90.5048,87,88.802,85,89,90.7665,85.8044,86.8043,72.9517,75.6065,56,47,27.9167],
[0.168831,0,0,0.0281385,0,0,0,0.0184162,0.0558767,0,0.0222222,0.0111111,0.0463918,0.0379242,0.0139721,0.0150538,0,0.0393519,0.0335917,0.0238095,0.0151515],
[0.012987,0,0,0,0,0,0,0,0.0500963,0,0,0,0.0120275,0,0,0,0,0.037037,0.0129199,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.0138889,0,0,0]];
const xz = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
const z = d3.scaleSequential(d3.interpolateBlues)
.domain([-0.5 * n, 1.5 * n]);
const y01z = d3.stack()
.keys(d3.range(n))
(d3.transpose(yz)) // stacked yz
.map((data, i) => data.map(([y0, y1]) => [y0, y1, i]));
const y1Max = d3.max(y01z, y => d3.max(y, d => d[1]));
const yMax = d3.max(yz, y => d3.max(y));
const y = d3.scaleLinear()
.domain([0, y1Max])
.range([height - margin.bottom, margin.top]);
const x = d3.scaleBand()
.domain(xz)
.rangeRound([margin.left, width - margin.right])
.padding(0.08);
const xAxis = svg => svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).tickSizeOuter(0).tickFormat(() => ""));
function chart() {
const svg = d3.select('#stackedSVG')
.style("width", "100%")
.style("height", "auto");
const rect = svg.selectAll("g")
.data(y01z)
.enter().append("g")
.attr("fill", (d, i) => z(i))
.selectAll("rect")
.data(d => d)
.join("rect")
.attr("x", (d, i) => x(i))
.attr("y", height - margin.bottom)
.attr("width", x.bandwidth())
.attr("height", 0);
svg.append("g")
.call(xAxis);
function transitionGrouped() {
y.domain([0, yMax]);
rect.transition()
.duration(500)
.delay((d, i) => i * 20)
.attr("x", (d, i) => x(i) + x.bandwidth() / n * d[2])
.attr("width", x.bandwidth() / n)
.transition()
.attr("y", d => y(d[1] - d[0]))
.attr("height", d => y(0) - y(d[1] - d[0]));
}
function transitionStacked() {
y.domain([0, y1Max]);
rect.transition()
.duration(500)
.delay((d, i) => i * 20)
.attr("y", d => y(d[1]))
.attr("height", d => y(d[0]) - y(d[1]))
.transition()
.attr("x", (d, i) => x(i))
.attr("width", x.bandwidth());
}
function update(layout) {
if (layout === "stacked") transitionStacked();
else transitionGrouped();
}
return Object.assign(svg.node(), {update});
}
var chrt = chart();
chrt.update('stacked');
</script>
</body>
<!DOCTYPE html>
<meta charset="utf-8">
<title>Stacked-to-Grouped Bars</title>
<link rel="stylesheet" type="text/css" href="./inspector.css">
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<form id=form name=form>
<label style="margin-right:0.5em;"><input type=radio name=radio value="stacked" onchange="chrt.update(form.radio.value);" checked> Stacked</label>
<label style="margin-right:0.5em;"><input type=radio name=radio value="grouped" onchange="chrt.update(form.radio.value);"> Grouped</label>
<label style="margin-right:0.5em;">Palette <select name=palette onChange="chrt.recolor(form.palette.value);"><option value="blue" selected>Blues</option><option value="ryb" selected>RdYlBu</option><option value="spectral" selected>Spectral</option><option value="rainbow">Less Angry Rainbow</option><option value="set3">Discrete Set3</option><option value="paired">Discrete Paired</option></select></label>
</form>
<svg id="stackedSVG" width=975 height=700 viewBox="0,0,975,700"></svg>
<script>
const margin = ({top: 0, right: 0, bottom: 10, left: 0});
const width = 975;
const height = 500;
const m = 282; // number of values per series
const n = 23; // number of series
const nz = [6,3,3,2,1,2,1,4,2,3,2,0,0,1,4,4,4,4,9,6,3,4,15,13,11,16,9,19,13,10,10,9,11,15,16,10,4,7,7,5,12,3,4,3,4,15,10,13,9,5,6,5,10,10,15,14,11,7,5,5,8,7,16,7,14,8,3,5,3,8,7,5,4,3,6,3,4,5,4,1,4,4,6,5,5,4,3,3,3,8,3,8,6,2,2,5,7,8,8,8,9,11,7,6,4,9,7,12,8,7,9,7,14,15,21,23,8,8,12,13,7,7,3,11,3,5,4,4,4,4,9,6,9,14,9,7,3,1,2,1,5,5,11,7,5,3,5,6,6,12,13,22,16,5,2,4,9,12,8,14,9,11,10,9,15,14,10,13,10,6,6,4,10,8,7,5,12,6,12,4,10,11,13,11,10,13,4,4,4,4,10,5,9,5,5,7,12,9,6,7,3,6,6,7,12,9,11,11,10,7,8,10,5,4,6,8,7,7,12,16,10,11,6,7,11,6,5,6,8,10,13,7,5,5,6,12,10,15,8,13,9,7,8,8,18,11,13,9,12,12,16,10,9,15,17,14,15,18,6,19,13,21,13,14,7,8,7,6,11,12,21,16,20,11,15,8,5,4,4,4,3,0]; // number of series in each value
const yz = [[180.246,413.23,512.774,742.719,764.229,736.495,701.913,520.011,297.842,168.259,57.1891,0,0,7.92424,558.003,933.084,1508.11,1410.78,2125.7,4240.41,2476.31,2184.64,112.771,2324.64,2222.29,1126.52,1325.8,1201.58,1317.06,2196.95,2835.48,3379.12,650.498,74.2504,3715.93,3258.79,3222.26,3461.45,506.959,2938.28,2549.88,3908.18,4021.52,6970.53,4366.12,384.987,1979.23,1275.2,1564.51,3008.11,2767.62,3891.68,3519.99,3143.28,473.614,238.158,435.383,2739.02,5922.31,4904.36,2236.37,3018.01,2140.7,1926.49,1774.67,3524.75,3083.27,3483.45,7443.28,300.161,4748.45,4197.43,4091.06,5497.91,4882.59,6590.27,5215.19,2304.07,7728.53,12367.1,5091.32,4411.27,5393.35,4940.1,5118.37,1669.42,6977.7,3938.52,5302.36,2443.7,7148.49,6562.14,9327.79,13065.3,12743.5,4370.57,2430.24,2407.73,2342.1,2157.79,6321.93,208.221,5471.21,9077.48,6270.02,2054.37,2022.39,5586.66,941.86,831.405,2125.64,4897.92,1748.25,112.622,318.255,5631.44,2793.31,1756.32,1942.05,66.3879,3154.89,118.221,7305.59,1294.49,7056.83,6830.18,4121.2,3248.21,3385.48,4271.26,2832.37,6363.85,5675.22,2646.65,4320.02,3632.2,4353.64,5696.11,4257.43,5494.76,2261.96,1980.84,2088.61,2415.72,2501.08,3326.03,1173.76,3294.49,2701.81,2565.7,2517.73,51.1784,2803.58,1990.68,8736.92,1852.44,668.693,48.0111,453.999,38.6368,2025.24,3310.27,3173.88,1965.61,1747.19,49.0103,31.2533,3068.61,36.5413,42.6531,811.552,3040.04,3654.35,3979.14,3705.68,4280.28,46.0116,1254.27,443,1235.52,9.92173,3835.14,1957.2,2046.58,8.0518,16.1614,3282.96,2717.17,2216.44,1645.13,22.9991,1455.67,4399.25,752.455,8.98976,1051.93,21.6816,6.86974,3026.08,147.976,3165.27,28.2236,759.957,660.39,4570.02,5380.89,4814.25,4358.39,1467.55,241,5.18105,16.5891,3075.3,2959.87,918.998,562.39,3391.19,18.8794,1160.14,11.0016,310.105,1857.84,1808.43,1796.87,152.954,2528.92,3063.5,3532.72,2075.57,1629.52,1640.73,447.043,1688.3,3149.72,1708.95,16.7233,21.4293,16.0058,4280.51,3225.46,5115.4,4386.57,3323.8,1908.61,2137.19,2143.8,129.228,13.682,2903.77,3102.68,3686.77,4048.75,3072.03,2982.69,44.4004,1927.49,54.1538,75.8446,42.4505,3033.61,92.9888,61.2858,313.295,45.5594,1983.11,2626.59,3939.4,99.9365,3367.25,2583.88,44.8929,59.0372,20.9016,36.0372,1289.75,958.426,233.393,835.083,965.933,415.351,196.18,0],
[9.58926,9.96212,19.7114,19.8379,0,5.03679,0,9.97644,8,5.06878,5.66169,0,0,0,29.9825,70.4076,831.743,942.772,1848.03,101.358,2516.02,2533.93,2155.14,1839.15,1885.44,13.0795,1857.99,1751.38,1838.59,1447.82,46.1346,629.895,3327.03,675.562,2933.95,3326.19,500.877,3434.63,2651.54,2601.47,2890.26,2953.78,3053.75,2278.19,3848.76,146.729,2234.92,1832.75,300.659,2638.55,3538.4,1854.99,87.8008,1541.58,1990.81,1852.97,49.4039,52.7771,3436.74,558.273,2852.44,2655.64,1641.58,1448.45,1504.8,1997.55,6132.02,3534.9,4038.4,282.776,3711.44,3089.83,4284.37,2462.65,78.3051,9267.89,2879.5,2416.32,1974.48,0,4789.2,4789,3878.57,4350.66,2069.31,2259.53,1768.84,1670.15,4575.52,1882.29,2042.14,2246.35,2255.84,2166.36,2153.29,5082.77,2830.84,5589.79,2502.32,905.235,2612.2,5973.22,1060.08,109.858,3029.13,1007.45,4739.98,2180.91,21.659,2663.14,2487.59,695.29,667.642,34.6245,53.9792,77.6558,1978.21,2523.73,34.5013,5427.88,6505.36,4081.56,4232.23,2712.44,3865.13,3437.7,7304.68,5120.5,4601.96,7331.18,4127.6,3466.22,17.789,2454.87,2551.98,1996.47,435.201,0,128.561,0,1783.05,402.821,350.77,2665.04,2806.81,1471.95,2686.84,2456.6,435.811,468.625,2701.97,19.3806,17.8751,3642.2,2088.83,3369.83,3464.69,554.021,794,764.608,9.73813,543.865,21.6725,3337.53,519.11,50.0107,6.01477,36.2197,92.7564,1661.11,2008,1099.85,9.78562,3817.91,70.1718,5156.29,4127.15,388.724,2580.79,2971.55,4367.71,2715.72,6.57331,615.142,3255.31,17.0588,5360.54,4717.14,1584.05,5056.94,1647.99,1353.91,1470.09,1473.72,3627.26,715,1315.5,2920.66,795.194,431.472,923.933,1241.95,1460.51,1324.49,25.7635,6.00811,10.9769,1319.97,261.684,969.762,1073.86,697.982,205.532,977,9.88972,942.442,13.9634,17,120.209,15.9145,3999.78,57.3612,5.26649,7,965.309,2694.58,53.8307,70.7929,3659.16,1101.68,28.5425,2243.99,3614.21,3711.03,3173.79,37.1834,1379.7,1305.28,25.0288,163.271,95.9407,16.8434,22.1672,3098.62,1836.85,67.0423,2425.1,2116.33,66.0038,2700.92,25.0473,2565.2,2647.06,71.7016,123.933,2044.92,32.3559,2502.07,571.182,6.95432,1756.45,9.89995,2432.79,83.9085,3344.18,2022.19,57.6042,3778.84,19.9312,19.8959,13.2799,1945.58,350.88,12.0001,144.739,13.0275,906.753,190.256,123.153,77.5114,35.9137,0],
[6.41074,10.9985,9.00725,0,0,0,0,24.7214,0,13,0,0,0,0,219.001,430.276,694,1108.78,16.5045,99.8947,3623.72,2555.81,93.622,2047.79,306.604,24.4521,2100.13,49.1065,1882.14,2478.22,53.0276,66.3427,27.2721,2981.57,152.578,2268.53,3293.2,523.208,2067.06,3330.72,1855.39,4736.21,3788.09,3193.66,78.2757,3406.76,17.689,56.6663,2762.02,3072.55,2515.4,2908.91,463.528,2330.74,3222.45,44.4817,2433.59,3565.84,2344.69,3074.57,2708.78,2335.13,334.971,86.9418,2735.04,139.546,3647,2309.49,4437.32,6369.46,198.594,1152.24,4814.6,12095,4994.8,4776.02,9152.61,8377.14,2131.99,0,5232.07,6011.14,4565.46,2475.83,3585.56,7247.27,1616.99,4013.2,1893.82,2058.69,2223.93,70.3503,1022.45,0,0,2082.92,936.237,117.204,2340.7,2324.31,2381.9,2903.83,2123.08,1319.81,1941.67,4790.49,2135.48,945.246,88.1725,2168.22,5335.65,2518.75,4487.32,729.458,30.0225,13.3065,5729.27,17.6652,2774.42,38.025,4202.89,7092.58,7828.5,3588.47,4377.54,72.0877,4112.72,4117.25,5038.12,3992,6859.43,2319.76,2956.91,25.5431,9.81079,2561.73,2673.26,0,0,0,66.3083,1911.43,1260.28,543.738,1493.49,2670.61,2783.32,599.648,2263.97,409.476,11.2454,40.0002,15.7531,945.792,0,3297.2,1002.46,3274.76,5.48776,23.1938,495.885,2024.15,28.6581,19.6803,47.0062,1646.83,16.4678,24.3739,2559.41,3493.37,2383.1,4106.59,6.47519,4784.83,5089.01,3625.98,11.0025,2360.92,9.05115,1876.04,1510.61,14.5616,24.8316,3497.67,5.66271,5215.26,2810.84,2424.22,4908.93,2022.18,4960,975.595,32.2126,12.2096,1006,1458.24,7.82769,5.00006,1403.92,1306.58,1895.2,3627.06,3993.9,35.7852,7.92815,607.942,40.667,13.6434,8.01133,467,8.00012,177.935,1003.39,815.999,2785.73,50.9075,1035.35,1312.62,872.935,35.3459,1873.27,943.609,3613.29,160.807,1500.4,91.3973,1790.41,2255.78,1094.2,57.6781,1209.6,5294.6,5455.8,5713.02,3693.54,3344.91,4319.89,30.5675,14.8836,1232.73,2739.36,24.1309,3113.52,943.656,45.3633,1866.33,68.5395,2876.14,15.5945,16.0236,778.59,2953.8,10.9439,8.62651,16.3288,93.4266,33.0293,3305.08,3691.54,418.7,223.551,2368.16,13.9651,130.944,54.5162,38.548,2847.05,34.1696,40.4567,784.232,91.6223,27.0379,7.60191,8.90166,19.0619,241,287.981,753.826,245.123,257.296,146.898,0],
[9,0,0,0,0,0,0,7.96702,0,0,0,0,0,0,179.073,458.999,122.47,1021.41,22.7708,186.895,0,302.008,1131.7,1188.57,47.7443,2119.03,21.3386,25.2606,21.7787,23.0576,2083.38,4106.68,2916.76,3147.7,2873.77,3127.93,4323.22,2808.34,3114.84,19.207,128.719,0,1668.37,0,2183.82,2628.26,2535.43,250.98,2667.96,2152.06,3119.43,2553.28,2274.42,20.6471,61.7797,126.23,3304.64,542.838,503.495,3336.04,1945.69,470.591,7.99534,2763.87,43.9483,3039.91,0,306.905,0,4366.21,3972.32,3102.72,3503.24,0,1958.52,0,5127.05,5433.7,4922.9,0,6698.95,4633.81,4257.28,5203.94,1276.51,919.436,0,0,0,5411.63,0,942.035,52.809,0,0,57.946,5559.47,2701.97,5436.68,5524.06,999.925,2302.72,1578.67,3100.18,3446.12,1735.8,2784.1,39.9099,2683.11,2063.86,759.671,1865.84,42.1909,86.3187,85.8209,184.27,2558.33,34.399,955.225,2208.68,2441.31,77.6022,0,7268.6,0,3608.99,3121.39,7911.41,7776.45,4407.12,3839.5,3677.65,953.159,48.2679,692.995,20.5119,0,0,0,0,916.384,933.8,525.266,1448.78,734.325,0,1646.39,51.1723,134.733,1478.73,29,2976.82,24.4813,3072.44,0,1919.94,84.5371,12.5716,1819.86,79.7626,799.968,9.08682,752.846,24.5743,61.7317,3024.8,2542.86,1647.06,1666.4,795.347,34.6835,2987.74,1224.37,1603.15,76.6492,1677.33,26.2061,3849.01,2215.55,3489.09,10.0147,13.0339,16.0081,14.5554,8.88434,3284.33,1821.1,1517.53,2173.87,1978.48,41.0071,8.91407,5.30723,4246.52,1391.41,3638,934.001,1455.43,452,779.348,0,16.6261,10.0428,1418.02,27.1191,36.1052,1684.08,1505.88,546.999,9,716.466,6.02703,463.085,621.998,561,179.663,971.023,984,3290.59,3602.61,17.2562,297.895,960,3192.27,1876.18,154.99,33.7491,53.0118,65.1962,27.018,54.8202,1544.87,3047.26,1724.01,5534,121.218,120.646,11,2456.22,11.0217,37.1558,2057.93,1163.39,2654.9,62.5787,11.9417,37.0737,52.15,37.3024,42.7466,2836.14,39.5478,22.0757,682.729,98.0549,226.743,1848.64,36.1241,41.6543,37.0034,16.2433,18.6229,47.897,1843.11,737.239,770.766,910.616,918.767,2915.45,61.1235,12.307,2138.4,9.05087,1270.71,17.7366,15.5984,951.206,305.155,58.2167,23.6193,0,0],
[52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70.6932,1265.78,0,0,1783.5,23.0237,66.2424,46.0769,20.3732,12.365,6.96,1657.5,3332.78,2046.92,69.4259,1709.86,42.0308,17.3256,0,109.223,3400.74,2539.59,85.603,0,0,0,0,2148.1,1303.42,2384.64,43.0702,9.96486,184.984,389.703,106.506,50.6697,62.4167,148.865,28.0283,3465.84,237.451,112.189,42.4673,81.4889,78.9323,2473.89,51.15,91.1402,0,3992.85,0,211.947,1250.59,1778.31,0,0,4442.94,0,0,5511.69,0,0,0,0,83.4057,196.275,3039.77,0,0,0,0,131.294,0,2679.33,68.6606,0,0,2507.38,27.3974,947.235,99.5143,2203.64,2520.34,1858.34,2909.07,55.7475,0,2463.18,91.0213,2671.56,2270.32,5413.09,43.8363,32.6457,19.1114,2253.79,1678.37,97.8089,33.7961,5387.08,1998.53,3620.92,1232.91,4285.6,0,91.483,0,3531.74,0,0,0,0,57.3662,1025.57,3366.87,4984.91,34.6947,1218.01,0,0,0,0,16.8638,73.2225,2530.94,375.439,47.6761,0,188.922,1571.35,1322.26,2305.68,11.6963,36.9257,10.0196,690.211,0,0,29.968,932.578,2907.16,2903.15,74.5356,40.7157,2008.22,547.848,3270.68,11.0446,64.4816,20.6482,19.4788,2444.48,3340.78,0,3290.73,57.3058,62.1235,41.5427,2616.47,2432.64,1161.43,0,18.9224,4789.04,5461.5,5983.68,1896.8,11.0431,0,0,0,0,21.805,4636.13,782.38,1033.54,730,15.7283,5.23616,20.269,171,2976.1,0,760.284,16.015,4143.81,9.30536,1711.2,12.9013,7,19.0006,1280.18,2876.15,409.444,867,0,5.1135,3212.82,6.05134,3603.59,16.1446,26.0005,998.383,1369.62,338.995,934,2942.15,44.1498,2181.17,9.70119,16.5615,3560.3,4101.96,3307.87,41.9997,20.6198,56.2346,105.147,2346.18,2551.82,2193.63,26.699,1369.67,3237.21,1819.67,29.284,1878.63,24.334,39.204,45.4401,2520.05,13.0594,69.9438,34.8816,2481.59,15.9888,2505.93,7,46.4611,38.5871,2740.53,35.6516,13.7953,85.3682,2183.98,2849.9,24.1925,40.9426,69.0166,2882.5,972.54,82.9484,32.5493,9.82479,12.6392,201.388,1101.84,258.85,125.426,0,0,0,0,0],
[6.29588,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1112.88,1714.38,0,0,29.7145,278.386,2095.66,22.6755,1742.61,73.7516,32.7175,355.696,1681.76,2649.8,4107.36,128.826,1888.48,555.623,0,2075.53,88.8465,0,3381.33,0,0,0,0,103.386,7.03651,2198.09,2243.36,0,189.12,0,2845.08,2075.96,1907.44,2762.08,53.4532,2409.93,0,0,99.0001,1965.08,77.1739,323.153,92.1113,200.82,0,0,0,4368.7,2161.7,0,0,0,1974.84,0,0,0,0,0,0,0,69.3304,0,0,0,0,0,0,52.4949,0,41.1221,3213.08,0,0,0,2052.5,2281.86,21.8693,72.2016,60.9247,59.6583,28.7421,42.1829,0,57.43,117.897,2366.45,2488.45,22.7764,2010.62,2043.13,176.755,1774.07,23.8114,94.0012,40.3863,3012.22,5140.36,1060.01,168.619,3173.85,0,68.5008,0,0,0,0,0,0,117,58.4975,37.2091,26.892,2151.99,614.027,0,0,0,0,0,0,13.7391,101.549,0,0,0,146.981,354.666,8.12486,23.8132,33.8256,1817.95,0,0,0,3264.36,1932.03,5.00626,2576.23,2724.64,817.36,534.826,2836.9,17.0562,8.96398,2861.31,2568.75,54.3639,20.388,28.797,0,3586.06,687.826,4499.74,0,15.999,6.78959,18.9614,0,3641.13,16.9995,19.9092,39.921,5615.35,2909.72,0,0,0,0,26.9978,0,46.077,0,0,10.0183,3157.67,450,7.00698,35.9427,0,1463.47,1331.98,21.0036,1630.19,246.384,8.02208,493.063,4400.04,3519.94,602.611,32.2057,0,0,771.551,800.453,25.5169,14.0133,9.85671,36.8829,1424.81,17.0009,1529.77,1500,14.9753,1676.29,0,2928.4,52.0218,29.6146,31.2973,63.558,0,0,39.7918,4980.26,431.996,4385.16,21.4919,2685.37,3529.29,35.9246,18.2957,90.0314,16.9416,529.724,567.117,2495.47,16.7488,48.8994,60.9631,39.584,742.684,33.0036,63.4398,504.701,2099.49,115.896,2546.99,50.0485,563.076,54.8912,652.945,27.7685,117.862,3743.43,76.392,1531.53,1060.02,2568.69,36.1351,526.009,1588.29,9.07939,20.3374,21.5993,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1451.22,0,0,0,289,133.795,1198.48,47.6637,20.9755,14.0445,1664.11,19.2392,127.226,27.4501,34.2185,39.7508,124.453,8.3556,0,86.821,303.382,0,43.4524,0,0,0,0,83.917,15.2716,29.6452,17.9595,0,0,0,1583.39,73.4274,54.9627,53.426,3138.42,82.5634,0,0,447.935,220.83,2643.8,35.1562,69.7347,519.382,0,0,0,44.5568,132.978,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1226.89,0,15.8652,0,0,0,0,272.805,103.699,850.836,29.4163,129.487,1014.03,34.4155,0,0,73.4583,415.203,61.3479,5770.17,57.2602,193.863,29.2127,2244.99,4717.18,4943.49,53.956,44.676,81.9005,42.5844,2588.39,80.2706,41.6583,0,65.7611,0,0,0,0,0,0,312.5,0,1888.5,20.7827,1362.08,311.967,0,0,0,0,0,0,100.476,55.5839,0,0,0,0,0,11.5969,23.3784,73.0002,11.9975,0,0,0,57.0648,12.4284,2943.87,217.376,3323.71,12.2991,14.5073,823.519,19.5887,5.00091,9.62609,23.2268,3620.92,0,0,0,10.9118,11.5033,1755.93,0,1283.62,0,35.9968,0,2483.25,1683.63,46.9646,9.0157,3233.55,1748.83,0,0,0,0,1767.72,0,1101.17,0,0,6.92436,10.4595,158,0,28.7196,0,0,0,14.5797,539.338,1749.54,1518.46,28.3408,6.4085,6,12.132,17.1031,0,0,0,44.1436,729,861.441,10,18.0013,8.74399,3492.44,0,309.002,17.4561,0,0,0,2225.25,30.042,32.3684,19.1035,0,0,0,28.4989,7.00634,26.5364,377.892,27,24.3336,1071.92,40.3052,62.2709,22.288,32.1313,79.5421,662.524,11.655,1911.66,74.7137,800.191,14.222,2351.55,2156.27,24.18,6.01396,47.1896,0,13.6786,36.981,53.7158,150.531,45.3299,2479.1,58.1106,1990.61,0,50.9257,568.319,692.573,15.432,43.4929,1272,265.328,1251.09,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68.3024,0,0,0,56.4417,24.643,23.7817,1901.15,18.0813,1900.62,10.3019,14.1721,516.458,12.9209,133.771,55.9359,116.723,65.0602,0,0,0,0,197.628,0,0,0,0,1596.56,51.6209,100.721,106.845,0,0,0,42.4654,78.0987,62.906,21.5442,2034.47,0,0,0,81.7775,0,2952.7,0,2482.53,1843.68,0,0,0,57.3828,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,85.7179,0,3001.38,0,0,0,0,0,75.0305,24.0918,81.6054,45.9345,99.447,0,0,0,29.3648,0,56.9156,208.938,0,46.0539,0,93.1132,74.3583,28.8731,2138.96,13.4142,104.086,11.1132,126.168,0,0,0,3976.37,0,0,0,0,0,0,1158.14,0,32.8551,1527.44,10.0087,0,0,0,0,0,0,0,88.3909,0,0,0,0,0,0,30.4316,547.121,13.032,32.1174,0,0,0,1990.32,13.006,6.43124,1872.9,98.353,2796.72,2768.59,48.7171,2811.59,2740.25,1569.93,37.8196,884.837,0,0,0,700.016,26.0653,0,0,522.005,0,29.9986,0,8.82704,24.6799,3259.47,3417.4,566.274,23.6739,0,0,0,0,1511.67,0,54.7829,0,0,0,146.2,859.24,0,0,0,0,0,0,135.797,9.96085,17.8354,226.937,1256.68,0,43.9178,2435.01,0,0,0,41.8497,0,0,9.82402,5.00267,18.7704,40.4672,0,0,28.0001,0,0,0,64.5664,2097.14,63.9853,0,0,0,0,1503.71,3203.01,39.04,1108.43,26.0059,21.5074,0,12.8029,49.4261,31.7222,1829.81,1936.97,36.2437,27.0316,680.004,25.0903,31.503,508.135,16.9557,68.2192,6.66792,7,2325.24,0,2229.22,2353.03,1601.89,21.2318,2391.68,0,146.121,0,0,138.811,24.254,2443.91,11.9997,32.0923,5.00371,10.1151,7.3231,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17.672,0,0,0,2233.78,36.8908,12.6867,99.044,68.5177,70.1026,317.329,23.7234,31.3164,20.2406,1726.51,69.6921,91.1497,131.462,0,0,0,0,72.7136,0,0,0,0,32.2201,12.0407,9.15022,228.368,0,0,0,81.2263,502.101,2482.57,129.04,86.3395,0,0,0,0,0,77.0159,0,49.5044,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25.4118,201.39,0,0,0,22.8813,0,65.2995,0,0,49.7134,0,1628.6,138.178,25.8519,963.263,0,0,54.8063,88.3584,0,0,0,151.191,0,0,0,0,0,0,46.0896,0,9.56971,24.6957,97.0763,0,0,0,0,0,0,0,71.34,0,0,0,0,0,0,32.7759,383.879,33.9487,37.4138,0,0,0,53.0529,7.01574,0,428.1,11.7412,28.6001,89.1337,29.5276,12.009,446.042,418.845,925.182,52.4678,0,0,0,10.4419,0,0,0,2849.61,0,3646.69,0,5.02035,49.3647,16.8716,6.97818,38.3242,9.50606,0,0,0,0,37.834,0,16.5921,0,0,0,446.49,7.75531,0,0,0,0,0,0,1791.39,9.86396,227.999,27.0534,12.9058,0,0,877.875,0,0,0,0,0,0,1320.87,1447.99,10.5964,19.2613,0,0,27.0553,0,0,0,0,31.2111,17.0927,0,0,0,0,75.4801,11.8097,25.4699,0,9,10.1181,0,0,0,614.441,23.5548,17,6.97104,177.161,22.9102,72.3051,31.0976,5.70736,47.592,633.077,370.999,432,487.748,0,29.239,89.4681,93.83,1557.74,389.903,0,0,0,0,32.1841,53.602,27.7142,16.1532,9.50059,288.345,180.725,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33.9799,13.3176,13.1574,1650.89,0,26.5756,30.8258,77.5918,10.5391,0,48.1184,4130.92,63.0961,166.373,0,0,0,0,506.059,0,0,0,0,38.13,260.404,9.82992,0,0,0,0,31.4137,22.54,19.5659,2176.11,44.6923,0,0,0,0,0,117.59,0,29.4033,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,131.88,0,0,0,0,0,332.021,0,0,0,0,115.534,1859.57,8.33462,30.137,0,0,145.015,339.489,0,0,0,47.9596,0,0,0,0,0,0,0,0,0,28.0785,0,0,0,0,0,0,0,0,100.771,0,0,0,0,0,0,40.9089,16.389,1743.83,584.078,0,0,0,0,3010.3,0,16.9075,0,43.2243,43.8631,0,20.1985,7.46487,849.986,467.153,13.6661,0,0,0,14.7343,0,0,0,38.9521,0,73.6386,0,7.71494,5.26446,654.076,16.5198,6.75978,21.144,0,0,0,0,10.9156,0,0,0,0,0,9.40714,0,0,0,0,0,0,0,5.54132,0,540.969,15.0032,13.9877,0,0,39.8531,0,0,0,0,0,0,10.9384,19.0317,11.1934,8.92312,0,0,22.8434,0,0,0,0,313.211,25.3719,0,0,0,0,3109.46,81.9706,46.7061,0,17.6125,0,0,0,0,53.2623,311.664,77.7431,0,1828.15,15.5185,48.0084,74.559,0,2267.42,437.122,2687.57,11,43.9615,0,2608.3,389.42,166.547,17.0518,789.319,0,0,0,0,18.118,6.78984,67.0735,99.3039,16.2732,25.9999,11.3658,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,77.3397,14.6168,7.26842,33.4815,0,1677.14,30.3973,0,0,0,18.2536,46.8178,57.3354,0,0,0,0,0,128.029,0,0,0,0,102.622,0,54.4988,0,0,0,0,0,0,39.9881,3236.28,29.2423,0,0,0,0,0,18.608,0,293.282,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,104.164,0,0,0,0,0,20.2466,0,0,0,0,27.5952,40.0583,121.153,29.1275,0,0,49.1967,37.7042,0,0,0,412.095,0,0,0,0,0,0,0,0,0,747.55,0,0,0,0,0,0,0,0,63.4265,0,0,0,0,0,0,24.1352,1675.54,6.00008,3160.16,0,0,0,0,14.029,0,18.9131,0,5.98596,0,0,10.253,772,0,28.4988,0,0,0,0,0,0,0,0,6.78561,0,16.5207,0,0,58.4391,18.2818,20.826,0,14.0278,0,0,0,0,0,0,0,0,0,0,186.305,0,0,0,0,0,0,0,53.1925,0,36.024,9.9545,0,0,0,0,0,0,0,0,0,0,7.85749,1111.61,0,9.21853,0,0,258.985,0,0,0,0,0,2358.74,0,0,0,0,14.3162,0,33.2706,0,170,0,0,0,0,31.8317,31.4293,2192.12,0,651.139,69.5375,63.5742,0,0,28.4647,36.1954,13.0339,345.228,53.8798,0,43.9472,31.1694,25.2236,12.5981,40.0989,0,0,0,0,59.4325,332.636,19.9636,48.8995,35.4555,6.99333,15.8896,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50.0796,13.0657,0,289.766,0,9.83909,19.5234,0,0,0,0,98.0867,98.623,0,0,0,0,0,69.2051,0,0,0,0,53.9482,0,8.86028,0,0,0,0,0,0,5.98706,22.5695,0,0,0,0,0,0,6.72064,0,20.6633,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30.9082,0,0,0,0,51.208,34.0784,38.2737,68.4268,0,0,21.6309,41.7934,0,0,0,0,0,0,0,0,0,0,0,0,0,9.73962,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9.63595,5.91746,45.9552,18.0042,0,0,0,0,10.6073,0,13.5094,0,0,0,0,25.2014,19.7049,0,6.94778,0,0,0,0,0,0,0,0,44.4174,0,16.6403,0,0,0,3666.65,0,0,8.99068,0,0,0,0,0,0,0,0,0,0,12.2506,0,0,0,0,0,0,0,33.7716,0,0,0,0,0,0,0,0,0,0,0,0,0,12.7103,21.3918,0,0,0,0,0,0,0,0,0,0,6.92507,0,0,0,0,34.9147,0,2999.99,0,4761.99,0,0,0,0,46.6315,0,20.7926,0,18.8722,55.8484,33.9504,0,0,33.4476,1993.02,43.0722,53.0007,45.8031,0,509.105,2997.34,703.148,12.9254,24.2307,0,0,0,0,0,6.01333,41.5716,8.22108,27.7103,0,7.36156,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42.6883,12.6514,0,9.94525,0,299.609,65.6268,0,0,0,0,62.3036,51.3145,0,0,0,0,0,0,0,0,0,0,103.513,0,17.6982,0,0,0,0,0,0,194.165,395.983,0,0,0,0,0,0,12.3087,0,40.7813,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14.4876,25.1693,100.927,2280.16,0,0,0,40.6347,0,0,0,0,0,0,0,0,0,0,0,0,0,55.168,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29.2873,2578.89,24.7768,0,0,0,0,0,0,39.2023,0,0,0,0,774.912,6.0101,0,28.2762,0,0,0,0,0,0,0,0,0,0,0,0,0,0,38.6934,0,0,15.9253,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10.0001,0,0,0,0,0,0,0,0,0,0,314.755,0,0,0,0,0,0,6.00723,0,19.4164,0,0,0,0,72.1491,0,44.1632,0,0,0,38.6073,0,0,21.0919,51.7871,6.85865,2544.41,20.114,0,24.9915,9.2717,13.7064,19.427,22.0045,0,0,0,0,0,0,2287.81,9.05458,5.01608,0,22.2347,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25.8234,0,0,57.9426,0,23.192,0,0,0,0,0,36.4878,49.4102,0,0,0,0,0,0,0,0,0,0,40.2646,0,0,0,0,0,0,0,0,68.307,46.4478,0,0,0,0,0,0,52.8714,0,30.2241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,233.775,23.6463,46.0484,75.9589,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63.0715,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65.8776,27.9873,0,0,0,0,0,0,53.9366,0,0,0,0,8.1099,14.7833,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,243.703,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5.75802,0,0,0,0,0,0,179.758,0,0,0,0,0,1976.27,0,0,369.285,31.9568,5.66671,34.2433,20.8491,0,18.7971,0,355.082,0,45.4847,0,0,0,0,0,0,30.4157,21.9764,55.0128,0,17.7688,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42.8797,0,0,21.1523,0,12.9468,0,0,0,0,0,15.6631,583.402,0,0,0,0,0,0,0,0,0,0,106.944,0,0,0,0,0,0,0,0,102.937,0,0,0,0,0,0,0,162.655,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43.9674,20.1636,25.4287,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10.7342,61.7469,0,0,0,0,0,0,0,0,0,0,0,54.7781,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,845.85,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23.3563,0,0,0,0,0,0,46.3884,0,0,0,0,0,40.3069,0,0,148.171,17.8338,0,69.6571,8.9532,0,18.9857,0,63.0749,0,0,0,0,0,0,0,0,6.9904,6.95821,1426.02,0,5.40093,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5.38746,0,33.8641,0,0,0,0,0,0,97.6698,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,69.458,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1864.1,29.4035,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14.1499,834.859,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33.1505,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12.8465,0,0,0,0,0,7.73896,0,0,0,13.8691,0,0,18.9822,0,16.9932,0,51.0001,0,0,0,0,0,0,0,0,24.9561,6.80544,14,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8.68959,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,799.957,59.7382,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21.9971,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10.7546,0,0,0,0,0,0,0,0,0,58.053,0,0,12.8373,0,6.71864,0,2624.33,0,0,0,0,0,0,0,0,72.643,0,226.173,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63.8939,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37.7846,7.91045,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13.0584,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,282.002,0,0,0,0,0,0,0,0,0,0,0,0,28.2066,0,5.87055,0,42.131,0,0,0,0,0,0,0,0,50.6474,0,22.0788,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25.846,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2135.74,1861.06,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6.00015,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,196.886,0,74.5733,0,0,0,0,0,0,0,0,30.5589,0,12.1927,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,77.6493,28.4226,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,418.602,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6.0364,0,0,0,0,0,0,0,0,12.4223,0,8.68309,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21.2537,72.5225,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,603.536,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32.8022,0,0,0,0,0,0,0,0,25.0327,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6.65057,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12.4522,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16.2201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];
const xz = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281];
// for inspiration, go here: https://github.com/d3/d3-scale-chromatic#schemeAccent
const z = {
"blue": d3.scaleSequential(d3.interpolateBlues)
.domain([-0.5 * n, 1.5 * n]),
"ryb": d3.scaleSequential(d3.interpolateRdYlBu)
.domain([0, n]),
"spectral": d3.scaleSequential(d3.interpolateSpectral)
.domain([0, n]),
"rainbow": d3.scaleSequential(d3.interpolateRainbow)
.domain([0, 12]),
"set3": d3.scaleOrdinal(d3.schemeSet3)
.domain([0, n]),
"paired": d3.scaleOrdinal(d3.schemePaired)
.domain([0, n])
};
const y01z = d3.stack()
.keys(d3.range(n))
(d3.transpose(yz)) // stacked yz
.map((data, i) => data.map(([y0, y1]) => [y0, y1, i]));
const y1Max = d3.max(y01z, y => d3.max(y, d => d[1]));
const yMax = d3.max(yz, y => d3.max(y));
const y = d3.scaleLinear()
.domain([0, y1Max])
.range([height - margin.bottom, margin.top]);
const x = d3.scaleBand()
.domain(xz)
.rangeRound([margin.left, width - margin.right])
.padding(0.08);
const xAxis = svg => svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).tickSizeOuter(0).tickFormat(() => ""));
function chart() {
const svg = d3.select('#stackedSVG')
.style("width", "100%")
.style("height", "auto");
const gs = svg.selectAll("g")
.data(y01z)
.enter().append("g")
.attr("fill", (d, i) => z["blue"](i))
const rect = gs.selectAll("rect")
.data(d => d)
.join("rect")
.attr("x", (d, i) => x(i))
.attr("y", height - margin.bottom)
.attr("width", x.bandwidth())
.attr("height", 0);
svg.append("g")
.call(xAxis);
function transitionGrouped() {
y.domain([0, yMax]);
rect.transition()
.duration(500)
.delay((d, i) => i * 20)
.attr("x", (d, i) => x(i) + x.bandwidth() / n * d[2])
.attr("width", x.bandwidth() / n)
.transition()
.attr("y", d => y(d[1] - d[0]))
.attr("height", d => y(0) - y(d[1] - d[0]));
}
function transitionStacked() {
y.domain([0, y1Max]);
rect.transition()
.duration(500)
.delay((d, i) => i * 20)
.attr("y", d => y(d[1]))
.attr("height", d => y(d[0]) - y(d[1]))
.transition()
.attr("x", (d, i) => x(i))
.attr("width", x.bandwidth());
}
function update(layout) {
if (layout === "stacked") transitionStacked();
else transitionGrouped();
}
function recolor(palette) {
if (palette in z)
gs.transition()
.duration(500)
.delay((d, i) => i * 20)
.attr("fill", (d, i) => z[palette](i));
else
alert("Wrong color " + palette);
}
return Object.assign(svg.node(), {update, recolor});
}
var chrt = chart();
chrt.update('stacked');
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment