Skip to content

Commit

Permalink
axisX.html
Browse files Browse the repository at this point in the history
  • Loading branch information
mhkeller committed Feb 11, 2024
1 parent e5a5722 commit 4043a6d
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 31 deletions.
83 changes: 61 additions & 22 deletions src/_components/AxisX.html.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,52 @@
<script>
import { getContext } from 'svelte';
const { xScale } = getContext('LayerCake');
/** @type {Boolean} [gridlines=true] - Extend lines from the ticks into the chart space. */
export let gridlines = true;
const { width, height, xScale, yRange } = getContext('LayerCake');
/** @type {Boolean} [tickMarks=false] - Show a vertical mark for each tick. */
export let tickMarks = false;
/** @type {String|Number} [tickMarkLength='long'] - Tick mark style. Options: 'long', 'short' or a number in pixels. If 'long', the line extends the full width. If 'short', it will generally be the length of the longest tick label. */
export let tickMarkLength = 'long';
/** @type {Boolean} [baseline=false] – Show a solid line at the bottom. */
export let baseline = false;
/** @type {Boolean} [snapTicks=false] - Instead of centering the text on the first and the last items, align them to the edges of the chart. */
export let snapTicks = 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} [formatTick=d => d] - A function that passes the current tick value and expects a nicely formatted value in return. */
export let formatTick = d => d;
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} [yTick=7] - The distance from the baseline to place each tick value, in pixels. */
export let yTick = 7;
/** @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=0] - Any optional value passed to the `dy` attribute on the text label. */
export let dy = 0;
function textAnchor(i, sl) {
if (sl === true) {
if (i === 0) {
return 'start';
}
if (i === tickVals.length - 1) {
return 'end';
}
}
return 'middle';
}
$: tickLen = typeof tickMarkLength === 'number'
? tickMarkLength
: tickMarkLength === 'short'
? 6
: 0;
$: isBandwidth = typeof $xScale.bandwidth === 'function';
Expand All @@ -36,27 +60,42 @@
typeof ticks === 'function' ?
ticks($xScale.ticks()) :
$xScale.ticks(ticks);
$: halfBand = isBandwidth ? halfBand : 0
</script>

<div class='axis x-axis' class:snapTicks>
<div class='axis x-axis' class:snapLabels>
{#each tickVals as tick, i (tick)}
{#if gridlines !== false}
<div class="gridline" style='left:{$xScale(tick)}%;top: 0px;bottom: 0;'></div>
{@const tickValPx = $xScale(tick)}

{#if baseline === true}
<div class="baseline" style='top:100%; width:100%;'></div>
{/if}
{#if tickMarks === true}
<div class="tick-mark" style='left:{$xScale(tick) + (isBandwidth ? $xScale.bandwidth() / 2 : 0)}%;height:6px;bottom: -6px;'></div>

{#if tickMarks === true && tickMarkLength === 'long'}
<div
class="gridline"
style:left={tickValPx + '%'}
style='top:0; bottom:0;'></div>
{:else if tickMarks === true && (tickMarkLength === 'short' || typeof tickMarkLength === 'number')}
<div
class="tick-mark"
style:left={(tickValPx + halfBand) + '%'}
style:height={tickLen + 'px'}
style:bottom={-tickLen + 'px'}
></div>
{/if}
<div
class='tick tick-{ i }'
style='left:{$xScale(tick) + (isBandwidth ? $xScale.bandwidth() / 2 : 0)}%;top:100%;'>
class='tick tick-{i}'
style:left={(tickValPx + halfBand) + '%'}
style='top:100%;'>
<div
class="text"
style='top:{(yTick)}px;'>{formatTick(tick)}</div>
style:top={(tickGutter + tickLen) + 'px'}
style:transform={`translate(calc(-50% + ${dx}px), ${dy}px)`}
>{format(tick)}</div>
</div>
{/each}
{#if baseline === true}
<div class="baseline" style='top: 100%;width: 100%;'></div>
{/if}
</div>

<style>
Expand Down Expand Up @@ -94,10 +133,10 @@
transform: translateX(-50%);
}
/* This looks a little better at 40 percent than 50 */
.axis.snapTicks .tick:last-child {
.axis.snapLabels .tick:last-child {
transform: translateX(-40%);
}
.axis.snapTicks .tick.tick-0 {
.axis.snapLabels .tick.tick-0 {
transform: translateX(40%);
}
</style>
1 change: 1 addition & 0 deletions src/_components/AxisX.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
-->
<script>
import { getContext } from 'svelte';
const { width, height, xScale, yRange } = getContext('LayerCake');
/** @type {Boolean} [tickMarks=false] - Show a vertical mark for each tick. */
Expand Down
7 changes: 3 additions & 4 deletions src/routes/_components/AxisX.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
});
let tickMarks = true;
let snapTicks = true;
let snapLabels = true;
let baseline = true;
let tickMarkLength = 'long';
</script>
Expand Down Expand Up @@ -53,7 +53,7 @@
</label>

<label>
<input type="checkbox" bind:checked={snapTicks}/> snapTicks
<input type="checkbox" bind:checked={snapLabels}/> snapLabels
</label>

<label>
Expand All @@ -65,7 +65,6 @@
<option value="long">long</option>
<option value="short">short</option>
</select>

</div>

<div class="chart-container">
Expand All @@ -79,7 +78,7 @@
<AxisX
{baseline}
{tickMarks}
{snapTicks}
{snapLabels}
tickMarkLength={Number.isNaN(+tickMarkLength) ? tickMarkLength : +tickMarkLength}
/>
</Svg>
Expand Down
6 changes: 3 additions & 3 deletions src/routes/_components/AxisXTop.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
});
let tickMarks = true;
let snapTicks = true;
let snapLabels = true;
let baseline = true;
let tickMarkLength = 'long';
</script>
Expand Down Expand Up @@ -53,7 +53,7 @@
</label>

<label>
<input type="checkbox" bind:checked={snapTicks}/> snapTicks
<input type="checkbox" bind:checked={snapLabels}/> snapLabels
</label>

<label>
Expand All @@ -79,7 +79,7 @@
<AxisXTop
{baseline}
{tickMarks}
{snapTicks}
{snapLabels}
tickMarkLength={Number.isNaN(+tickMarkLength) ? tickMarkLength : +tickMarkLength}
/>
</Svg>
Expand Down
47 changes: 45 additions & 2 deletions src/routes/_components_ssr/AxisX.html.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
data.forEach(d => {
d[yKey] = +d[yKey];
});
let tickMarks = true;
let snapLabels = true;
let baseline = true;
let tickMarkLength = 'long';
</script>

<style>
Expand All @@ -23,10 +28,45 @@
*/
.chart-container {
width: 100%;
height: 250px;
height: 200px;
}
.props {
height: 25px;
display: flex;
flex-direction: row;
user-select: none;
gap: 10px;
}
label {
display: flex;
cursor: pointer;
align-items: center;
}
select {
width: 60px;
}
</style>

<div class="props">
<label>
<input type="checkbox" bind:checked={baseline}/> baseline
</label>

<label>
<input type="checkbox" bind:checked={snapLabels}/> snapLabels
</label>

<label>
<input type="checkbox" bind:checked={tickMarks}/> tickMarks
</label>

<select bind:value={tickMarkLength} disabled={!tickMarks}>
<option disabled>tickMarkLength</option>
<option value="long">long</option>
<option value="short">short</option>
</select>
</div>

<div class="chart-container">
<LayerCake
ssr={true}
Expand All @@ -39,7 +79,10 @@
>
<Html>
<AxisX
baseline={true}
{baseline}
{tickMarks}
{snapLabels}
tickMarkLength={Number.isNaN(+tickMarkLength) ? tickMarkLength : +tickMarkLength}
/>
</Html>
</LayerCake>
Expand Down
1 change: 1 addition & 0 deletions src/routes/_examples/Column.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
/>
<AxisY
tickMarks={false}
snapBaselineLabel
/>
</Svg>

Expand Down

0 comments on commit 4043a6d

Please sign in to comment.