mirror of https://github.com/sveltejs/svelte
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
2.2 KiB
112 lines
2.2 KiB
6 years ago
|
<script>
|
||
|
import { onMount } from 'svelte';
|
||
|
import { scaleLinear } from 'd3-scale';
|
||
|
|
||
|
export let points;
|
||
|
|
||
|
const xTicks = [1990, 1995, 2000, 2005, 2010, 2015];
|
||
|
const yTicks = [0, 5, 10, 15, 20];
|
||
|
const padding = { top: 20, right: 15, bottom: 20, left: 25 };
|
||
|
|
||
|
let width = 500;
|
||
|
let height = 200;
|
||
|
let barWidth;
|
||
|
let xScale;
|
||
|
let yScale;
|
||
|
|
||
|
function formatMobile(tick) {
|
||
|
return "'" + tick % 100;
|
||
|
}
|
||
|
|
||
|
$: xScale = scaleLinear()
|
||
|
.domain([0, xTicks.length])
|
||
|
.range([padding.left, width - padding.right]);
|
||
|
|
||
|
$: yScale = scaleLinear()
|
||
|
.domain([0, Math.max.apply(null, yTicks)])
|
||
|
.range([height - padding.bottom, padding.top]);
|
||
|
|
||
|
$: {
|
||
|
const innerWidth = width - (padding.left + padding.right);
|
||
|
barWidth = innerWidth / xTicks.length;
|
||
|
}
|
||
|
</script>
|
||
|
|
||
|
<style>
|
||
|
.chart {
|
||
|
width: 100%;
|
||
|
max-width: 500px;
|
||
|
margin: 0 auto;
|
||
|
}
|
||
|
|
||
|
svg {
|
||
|
position: relative;
|
||
|
width: 100%;
|
||
|
height: 200px;
|
||
|
}
|
||
|
|
||
|
.tick {
|
||
|
font-family: Helvetica, Arial;
|
||
|
font-size: .725em;
|
||
|
font-weight: 200;
|
||
|
}
|
||
|
|
||
|
.tick line {
|
||
|
stroke: #e2e2e2;
|
||
|
stroke-dasharray: 2;
|
||
|
}
|
||
|
|
||
|
.tick text {
|
||
|
fill: #ccc;
|
||
|
text-anchor: start;
|
||
|
}
|
||
|
|
||
|
.tick.tick-0 line {
|
||
|
stroke-dasharray: 0;
|
||
|
}
|
||
|
|
||
|
.x-axis .tick text {
|
||
|
text-anchor: middle;
|
||
|
}
|
||
|
|
||
|
.bars rect {
|
||
|
fill: #a11;
|
||
|
stroke: none;
|
||
|
opacity: 0.65;
|
||
|
}
|
||
|
</style>
|
||
|
|
||
|
<div class="chart">
|
||
|
<h2>US birthrate by year {width}/{height}</h2>
|
||
|
<svg bind:clientWidth={width} bind:clientHeight={height}>
|
||
|
<!-- y axis -->
|
||
|
<g class="axis y-axis" transform="translate(0,{padding.top})">
|
||
|
{#each yTicks as tick}
|
||
|
<g class="tick tick-{tick}" transform="translate(0, {yScale(tick) - padding.bottom})">
|
||
|
<line x2="100%"></line>
|
||
|
<text y="-4">{tick} {tick === 20 ? ' per 1,000 population' : ''}</text>
|
||
|
</g>
|
||
|
{/each}
|
||
|
</g>
|
||
|
|
||
|
<!-- x axis -->
|
||
|
<g class="axis x-axis">
|
||
|
{#each points as point, i}
|
||
|
<g class="tick" transform="translate({xScale(i)},{height})">
|
||
|
<text x="{barWidth/2}" y="-4">{width > 380 ? point.year : formatMobile(point.year)}</text>
|
||
|
</g>
|
||
|
{/each}
|
||
|
</g>
|
||
|
|
||
|
<g class='bars'>
|
||
|
{#each points as point, i}
|
||
|
<rect
|
||
|
x="{xScale(i) + 2}"
|
||
|
y="{yScale(point.birthrate)}"
|
||
|
width="{barWidth - 4}"
|
||
|
height="{height - padding.bottom - yScale(point.birthrate)}"
|
||
|
></rect>
|
||
|
{/each}
|
||
|
</g>
|
||
|
</svg>
|
||
|
</div>
|