import { default as LayerCake, flatten, uniques } from 'layercake';
import { stack } from 'd3-shape';
import { scaleBand } from 'd3-scale';
import fruit from './data/fruitOrdinal.js';
import ColumnStacked from './components/ColumnStacked.html';
import AxisX from './components/AxisXScaleBand.html';
import AxisY from './components/AxisY.html';
const seriesNames = Object.keys(fruit[0]).filter(d => d !== 'year');
const stackData = stack()
.keys(seriesNames);
const series = stackData(fruit);
function formatYTick (d) {
if (d > 999) {
return Math.round(d / 1000) + 'k';
}
return d;
}
const colors = ['#00e047', '#7ceb68', '#b7f486', '#ecfda5'];
const myCake = new LayerCake({
padding: { top: 0, right: 0, bottom: 20, left: 20 },
x: d => d.data.year,
y: [0, 1],
xScale: scaleBand().paddingInner([0.02]).round(true),
xDomain: uniques(fruit, 'year'),
flatData: flatten(series),
data: series,
target: document.getElementById('my-chart'),
seriesNames_: seriesNames
})
.svgLayers([
{ component: AxisX, opts: { gridlines: false } },
{ component: AxisY, opts: { gridlines: false, formatTick: formatYTick } },
{ component: ColumnStacked, opts: { colors } }
]);
myCake.render();
{#each $data as series, i}
{#each series as d}
<rect class='group-rect' data-id="{i}" x="{$xGet(d)}" y="{$yGet(d)[1]}" {width} height="{height(d)}"fill={fill(series.key)}></rect>
{/each}
}
{/each}
<script>
import { scaleOrdinal } from 'd3-scale';
export default {
namespace: 'svg',
computed: {
colorScale: ({ $xScale, $seriesNames_, $data, opts }) => {
return scaleOrdinal()
.domain($seriesNames_)
.range(opts.colors);
},
fill: ({ colorScale }) => {
return seriesName => colorScale(seriesName);
},
width: ({ $xScale }) => {
return $xScale.bandwidth();
},
height: ({ $height, $xScale, $yGet }) => {
return (d) => {
const vals = $yGet(d);
return vals[0] - vals[1];
};
}
}
};
</script>
<g class='axis x-axis'>
{#each $xScale.domain() as tick}
<g class='tick tick-{ tick }' transform='translate({$xScale(tick)},{$yScale.range()[0]})'>
{#if opts.gridlines !== false}
<line y1='{$height * -1}' y2='0' x1='0' x2='0'></line>
{/if}
<text y='16' x="{$xScale.bandwidth() / 2}">{opts.formatTick ? opts.formatTick(tick) : tick}</text>
</g>
{/each}
</g>
<style>
.tick {
font-size: .725em;
font-weight: 200;
}
.tick line {
stroke: #aaa;
stroke-dasharray: 2;
}
.tick text {
fill: #666;
text-anchor: start;
}
.tick.tick-0 line {
stroke-dasharray: 0;
}
.x-axis .tick text {
text-anchor: middle;
}
</style>
<script>
export default {
namespace: 'svg'
};
</script>
<g class='axis y-axis' transform='translate(-{$padding.left}, 0)'>
{#each $yScale.ticks(opts.ticks || opts.tickNumber || 5) as tick, i}
<g class='tick tick-{tick}' transform='translate(0, {$yScale(tick)})'>
{#if opts.gridlines !== false}
<line x2='100%'></line>
{/if}
<text y='-4'>{opts.formatTick ? opts.formatTick(tick) : tick}</text>
</g>
{/each}
</g>
<style>
.tick {
font-size: .725em;
font-weight: 200;
}
.tick line {
stroke: #aaa;
stroke-dasharray: 2;
}
.tick text {
fill: #666;
text-anchor: start;
}
.tick.tick-0 line {
stroke-dasharray: 0;
}
</style>
<script>
export default {
namespace: 'svg'
};
</script>
export default [
{year: '2019', apples: 3840, bananas: 1920, cherries: 960, dates: 400},
{year: '2018', apples: 1600, bananas: 1440, cherries: 960, dates: 400},
{year: '2017', apples: 820, bananas: 1000, cherries: 640, dates: 400},
{year: '2016', apples: 820, bananas: 560, cherries: 720, dates: 400}
];