AxisX.svelte component
Generates an SVG x-axis. This component is also configured to detect if your x-scale is an ordinal scale. If so, it will place the markers in the middle of the bandwidth.
Param | Default | Required | Description |
---|---|---|---|
tickMarks Boolean |
false |
Show a vertical mark for each tick. | |
gridlines Boolean |
true |
Show gridlines extending into the chart area. | |
tickMarkLength Number |
6 |
The length of the tick mark. | |
baseline Boolean |
false |
Show a solid line at the bottom. | |
snapLabels Boolean |
false |
Instead of centering the text labels on the first and the last items, align them to the edges of the chart. | |
format Function |
d=>d |
A function that passes the current tick value and expects a nicely formatted value in return. | |
ticks (Number | Array | Function ) |
None | If this is a number, it passes that along to the d3Scale.ticks function. If this is an array, hardcodes the ticks to those values. If it's a function, passes along the default tick values and expects an array of tick values in return. If nothing, it uses the default ticks supplied by the D3 function. | |
tickGutter Number |
0 |
The amount of whitespace between the start of the tick and the chart drawing area (the yRange min). | |
dx Number |
0 |
Any optional value passed to the dx attribute on the text label. |
|
dy Number |
12 |
Any optional value passed to the dy attribute on the text label. |
Used in these examples:
<!--
@component
Generates an SVG x-axis. This component is also configured to detect if your x-scale is an ordinal scale. If so, it will place the markers in the middle of the bandwidth.
-->
<script>
import { getContext } from 'svelte';
const { width, height, xScale, yRange } = getContext('LayerCake');
/** @type {Boolean} [tickMarks=false] - Show a vertical mark for each tick. */
export let tickMarks = false;
/** @type {Boolean} [gridlines=true] - Show gridlines extending into the chart area. */
export let gridlines = true;
/** @type {Number} [tickMarkLength=6] - The length of the tick mark. */
export let tickMarkLength = 6;
/** @type {Boolean} [baseline=false] – Show a solid line at the bottom. */
export let baseline = false;
/** @type {Boolean} [snapLabels=false] - Instead of centering the text labels on the first and the last items, align them to the edges of the chart. */
export let snapLabels = false;
/** @type {Function} [format=d => d] - A function that passes the current tick value and expects a nicely formatted value in return. */
export let format = d => d;
/** @type {Number|Array|Function} [ticks] - If this is a number, it passes that along to the [d3Scale.ticks](https://github.com/d3/d3-scale) function. If this is an array, hardcodes the ticks to those values. If it's a function, passes along the default tick values and expects an array of tick values in return. If nothing, it uses the default ticks supplied by the D3 function. */
export let ticks = undefined;
/** @type {Number} [tickGutter=0] - The amount of whitespace between the start of the tick and the chart drawing area (the yRange min). */
export let tickGutter = 0;
/** @type {Number} [dx=0] - Any optional value passed to the `dx` attribute on the text label. */
export let dx = 0;
/** @type {Number} [dy=12] - Any optional value passed to the `dy` attribute on the text label. */
export let dy = 12;
function textAnchor(i, sl) {
if (sl === true) {
if (i === 0) {
return 'start';
}
if (i === tickVals.length - 1) {
return 'end';
}
}
return 'middle';
}
$: tickLen = tickMarks === true
? tickMarkLength ?? 6
: 0;
$: isBandwidth = typeof $xScale.bandwidth === 'function';
$: tickVals = Array.isArray(ticks) ? ticks :
isBandwidth ?
$xScale.domain() :
typeof ticks === 'function' ?
ticks($xScale.ticks()) :
$xScale.ticks(ticks);
$: halfBand = isBandwidth ? $xScale.bandwidth() / 2 : 0
</script>
<g class="axis x-axis" class:snapLabels>
{#each tickVals as tick, i (tick)}
{#if baseline === true}
<line
class="baseline"
y1={$height}
y2={$height}
x1="0"
x2={$width}
/>
{/if}
<g class="tick tick-{i}" transform="translate({$xScale(tick)},{Math.max(...$yRange)})">
{#if gridlines === true}
<line
class="gridline"
x1={halfBand}
x2={halfBand}
y1={-$height}
y2="0"
/>
{/if}
{#if tickMarks === true}
<line
class="tick-mark"
x1={halfBand}
x2={halfBand}
y1={tickGutter}
y2={tickGutter + tickLen}
/>
{/if}
<text
x={halfBand}
y={tickGutter + tickLen}
{dx}
{dy}
text-anchor={textAnchor(i, snapLabels)}>{format(tick)}</text
>
</g>
{/each}
</g>
<style>
.tick {
font-size: 11px;
}
line,
.tick line {
stroke: #aaa;
stroke-dasharray: 2;
}
.tick text {
fill: #666;
}
.tick .tick-mark,
.baseline {
stroke-dasharray: 0;
}
/* This looks slightly better */
.axis.snapLabels .tick:last-child text {
transform: translateX(3px);
}
.axis.snapLabels .tick.tick-0 text {
transform: translateX(-3px);
}
</style>