From 76433909bed694663660517440ebc4e1d5d494a2 Mon Sep 17 00:00:00 2001 From: mhkeller Date: Fri, 30 Jun 2023 21:00:08 -0400 Subject: [PATCH 01/51] axisXTop --- src/_components/AxisXTop.svelte | 111 +++++++++++++++++++++++++ src/routes/_components.js | 2 + src/routes/_components/AxisXTop.svelte | 44 ++++++++++ 3 files changed, 157 insertions(+) create mode 100644 src/_components/AxisXTop.svelte create mode 100644 src/routes/_components/AxisXTop.svelte diff --git a/src/_components/AxisXTop.svelte b/src/_components/AxisXTop.svelte new file mode 100644 index 00000000..c0bbf449 --- /dev/null +++ b/src/_components/AxisXTop.svelte @@ -0,0 +1,111 @@ + + + + + {#each tickVals as tick, i (tick)} + + {#if gridlines !== false} + + {/if} + {#if tickMarks === true} + + {/if} + {formatTick(tick)} + + {/each} + {#if baseline === true} + + {/if} + + + diff --git a/src/routes/_components.js b/src/routes/_components.js index 26be9403..c6aab78d 100644 --- a/src/routes/_components.js +++ b/src/routes/_components.js @@ -6,6 +6,7 @@ import AreaD3 from './_components/Area-D3.svelte'; import AreaStacked from './_components/AreaStacked.svelte'; import AxisRadial from './_components/AxisRadial.svelte'; import AxisX from './_components/AxisX.svelte'; +import AxisXTop from './_components/AxisXTop.svelte'; import AxisY from './_components/AxisY.svelte'; import Bar from './_components/Bar.svelte'; import BarStacked from './_components/BarStacked.svelte'; @@ -54,6 +55,7 @@ export default [ components: [ { slug: 'AxisX.svelte', component: AxisX }, { slug: 'AxisY.svelte', component: AxisY }, + { slug: 'AxisXTop.svelte', component: AxisXTop }, { slug: 'AxisX.html.svelte', component: AxisXHtml }, { slug: 'AxisY.html.svelte', component: AxisYHtml }, { slug: 'AxisRadial.svelte', component: AxisRadial }, diff --git a/src/routes/_components/AxisXTop.svelte b/src/routes/_components/AxisXTop.svelte new file mode 100644 index 00000000..d4f682d0 --- /dev/null +++ b/src/routes/_components/AxisXTop.svelte @@ -0,0 +1,44 @@ + + + + +
+ + + + + +
From 743184cbe20a224186a420a1b8447d6155b1f7aa Mon Sep 17 00:00:00 2001 From: mhkeller Date: Fri, 30 Jun 2023 21:13:29 -0400 Subject: [PATCH 02/51] axisXTop.html --- src/_components/AxisXTop.html.svelte | 103 ++++++++++++++++++ src/routes/_components.js | 42 ++++--- .../_components_ssr/AxisXTop.html.svelte | 47 ++++++++ 3 files changed, 177 insertions(+), 15 deletions(-) create mode 100644 src/_components/AxisXTop.html.svelte create mode 100644 src/routes/_components_ssr/AxisXTop.html.svelte diff --git a/src/_components/AxisXTop.html.svelte b/src/_components/AxisXTop.html.svelte new file mode 100644 index 00000000..475e5458 --- /dev/null +++ b/src/_components/AxisXTop.html.svelte @@ -0,0 +1,103 @@ + + + +
+ {#each tickVals as tick, i (tick)} + {#if gridlines !== false} +
+ {/if} + {#if tickMarks === true} +
+ {/if} +
+
{formatTick(tick)}
+
+ {/each} + {#if baseline === true} +
+ {/if} +
+ + diff --git a/src/routes/_components.js b/src/routes/_components.js index c6aab78d..0fdbca07 100644 --- a/src/routes/_components.js +++ b/src/routes/_components.js @@ -44,6 +44,7 @@ import Tooltip from './_components/Tooltip.html.svelte'; import SharedTooltip from './_components/SharedTooltip.html.svelte'; import SharedTooltipPercentRange from './_components_ssr/SharedTooltip.percent-range.html.svelte'; import AxisXHtml from './_components_ssr/AxisX.html.svelte'; +import AxisXTopHtml from './_components_ssr/AxisXTop.html.svelte'; import AxisYHtml from './_components_ssr/AxisY.html.svelte'; import ScatterHtml from './_components_ssr/Scatter.html.svelte'; import Key from './_components_ssr/Key.html.svelte'; @@ -51,16 +52,20 @@ import QuadTree from './_components/QuadTree.html.svelte'; import QuadTreePercentRange from './_components_ssr/QuadTree.percent-range.html.svelte'; export default [ - { name: 'axis', + { + name: 'axis', components: [ { slug: 'AxisX.svelte', component: AxisX }, { slug: 'AxisY.svelte', component: AxisY }, { slug: 'AxisXTop.svelte', component: AxisXTop }, { slug: 'AxisX.html.svelte', component: AxisXHtml }, + { slug: 'AxisXTop.html.svelte', component: AxisXTopHtml }, { slug: 'AxisY.html.svelte', component: AxisYHtml }, - { slug: 'AxisRadial.svelte', component: AxisRadial }, - ] }, - { name: 'chart', + { slug: 'AxisRadial.svelte', component: AxisRadial } + ] + }, + { + name: 'chart', components: [ { slug: 'Area.svelte', component: Area }, { slug: 'Area-D3.svelte', component: AreaD3 }, @@ -87,9 +92,11 @@ export default [ { slug: 'Scatter.canvas.svelte', component: ScatterCanvas }, { slug: 'Scatter.svg.svelte', component: ScatterSvg }, { slug: 'Scatter.webgl.svelte', component: ScatterWebgl }, - { slug: 'Scatter.html.svelte', component: ScatterHtml }, - ] }, - { name: 'map', + { slug: 'Scatter.html.svelte', component: ScatterHtml } + ] + }, + { + name: 'map', components: [ { slug: 'Map.svg.svelte', component: MapSvg }, { slug: 'Map.canvas.svelte', component: MapCanvas }, @@ -97,9 +104,11 @@ export default [ { slug: 'MapPoints.html.svelte', component: MapPointsHtml }, { slug: 'MapPoints.canvas.svelte', component: MapPointsCanvas }, { slug: 'MapLabels.html.svelte', component: MapLabelsHtml }, - { slug: 'MapLabels.svg.svelte', component: MapLabels }, - ] }, - { name: 'interaction', + { slug: 'MapLabels.svg.svelte', component: MapLabels } + ] + }, + { + name: 'interaction', components: [ { slug: 'Voronoi.svelte', component: Voronoi }, { slug: 'Brush.html.svelte', component: Brush }, @@ -107,15 +116,18 @@ export default [ { slug: 'QuadTree.percent-range.html.svelte', component: QuadTreePercentRange }, { slug: 'Tooltip.html.svelte', component: Tooltip }, { slug: 'SharedTooltip.html.svelte', component: SharedTooltip }, - { slug: 'SharedTooltip.percent-range.html.svelte', component: SharedTooltipPercentRange }, - ] }, - { name: 'annotation', + { slug: 'SharedTooltip.percent-range.html.svelte', component: SharedTooltipPercentRange } + ] + }, + { + name: 'annotation', components: [ { slug: 'Annotations.html.svelte', component: Annotations }, { slug: 'AnnotationsData.html.svelte', component: AnnotationsData }, { slug: 'Arrows.svelte', component: Arrows }, { slug: 'Key.html.svelte', component: Key }, { slug: 'Labels.html.svelte', component: Labels }, - { slug: 'GroupLabels.html.svelte', component: GroupLabels }, - ] } + { slug: 'GroupLabels.html.svelte', component: GroupLabels } + ] + } ]; diff --git a/src/routes/_components_ssr/AxisXTop.html.svelte b/src/routes/_components_ssr/AxisXTop.html.svelte new file mode 100644 index 00000000..237f7707 --- /dev/null +++ b/src/routes/_components_ssr/AxisXTop.html.svelte @@ -0,0 +1,47 @@ + + + + +
+ d[yKey]} + yDomain={[0, null]} + data={data} + > + + + + +
From f4957a9cdb32ead01261b63f2feea07bba6f79d1 Mon Sep 17 00:00:00 2001 From: mhkeller Date: Fri, 30 Jun 2023 22:43:36 -0400 Subject: [PATCH 03/51] WIP AxisRight --- src/_components/AxisYRight.svelte | 98 ++++++++++++++++++++++++ src/routes/_components.js | 2 + src/routes/_components/AxisYRight.svelte | 43 +++++++++++ 3 files changed, 143 insertions(+) create mode 100644 src/_components/AxisYRight.svelte create mode 100644 src/routes/_components/AxisYRight.svelte diff --git a/src/_components/AxisYRight.svelte b/src/_components/AxisYRight.svelte new file mode 100644 index 00000000..9183039b --- /dev/null +++ b/src/_components/AxisYRight.svelte @@ -0,0 +1,98 @@ + + + + + {#each tickVals as tick (tick)} + + {#if gridlines !== false} + + {/if} + {#if tickMarks === true} + + {/if} + {formatTick(tick)} + + {/each} + + + diff --git a/src/routes/_components.js b/src/routes/_components.js index 0fdbca07..2c9ac374 100644 --- a/src/routes/_components.js +++ b/src/routes/_components.js @@ -8,6 +8,7 @@ import AxisRadial from './_components/AxisRadial.svelte'; import AxisX from './_components/AxisX.svelte'; import AxisXTop from './_components/AxisXTop.svelte'; import AxisY from './_components/AxisY.svelte'; +import AxisYRight from './_components/AxisYRight.svelte'; import Bar from './_components/Bar.svelte'; import BarStacked from './_components/BarStacked.svelte'; import Beeswarm from './_components/Beeswarm.svelte'; @@ -57,6 +58,7 @@ export default [ components: [ { slug: 'AxisX.svelte', component: AxisX }, { slug: 'AxisY.svelte', component: AxisY }, + { slug: 'AxisYRight.svelte', component: AxisYRight }, { slug: 'AxisXTop.svelte', component: AxisXTop }, { slug: 'AxisX.html.svelte', component: AxisXHtml }, { slug: 'AxisXTop.html.svelte', component: AxisXTopHtml }, diff --git a/src/routes/_components/AxisYRight.svelte b/src/routes/_components/AxisYRight.svelte new file mode 100644 index 00000000..8c52508a --- /dev/null +++ b/src/routes/_components/AxisYRight.svelte @@ -0,0 +1,43 @@ + + + + +
+ + + + + +
From 782db3930cf6feac7b7b6aaa02188368f1f643ca Mon Sep 17 00:00:00 2001 From: mhkeller Date: Wed, 26 Jul 2023 21:03:45 -0400 Subject: [PATCH 04/51] update axis y --- src/_components/AxisY.svelte | 59 ++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/src/_components/AxisY.svelte b/src/_components/AxisY.svelte index 38439862..8ab9ab43 100644 --- a/src/_components/AxisY.svelte +++ b/src/_components/AxisY.svelte @@ -10,29 +10,35 @@ /** @type {Boolean} [gridlines=true] - Extend lines from the ticks into the chart space */ export let gridlines = true; - /** @type {Boolean} [tickMarks=false] - Show a vertical mark for each tick. */ + /** @type {Boolean} [labelPosition='above'] - Whether the label sits even with its value ('even') or sits on top ('above'). Default is 'above'. */ + export let labelPosition = 'above'; + + /** @type {Boolean} [tickMarks=false] - Show a horiontal mark for each tick. */ export let tickMarks = 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; + /** @type {Boolean} [tickMarks=undefined] - How many pixels wide should the tickMark be. By default, this is calculated dynamically and the tick mark extends from the end of the tickOffsetX to the tickGutter position. Set a value here to override that calculation. */ + export let tickMarkWidth = undefined; + + /** @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=4] - 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. */ export let ticks = 4; - /** @type {Number} [xTick=0] - How far over to position the text marker. */ - export let xTick = 0; + /** @type {Number} [tickGutter=2] - The amount of whitespace between the min of the xRange and the start of the tick. */ + export let tickGutter = 2; - /** @type {Number} [yTick=0] - How far up and down to position the text marker. */ + /** @type {Number} [tickOffsetX=0] - How far over to position the tick mark and label. */ + export let tickOffsetX = 0 + + /** @type {Number} [yTick=0] - How far up and down to nudge the text label. */ export let yTick = 0; - /** @type {Number} [dxTick=0] - Any optional value passed to the `dx` attribute on the text marker and tick mark (if visible). This is ignored on the text marker if your scale is ordinal. */ + /** @type {Number} [dxTick=0] - Any optional value passed to the `dx` attribute on the text label. */ export let dxTick = 0; - /** @type {Number} [dyTick=-4] - Any optional value passed to the `dy` attribute on the text marker and tick mark (if visible). This is ignored on the text marker if your scale is ordinal. */ - export let dyTick = -4; - - /** @type {String} [textAnchor='start'] The CSS `text-anchor` passed to the label. This is automatically set to "end" if the scale has a bandwidth method, like in ordinal scales. */ - export let textAnchor = 'start'; + /** @type {Number} [dyTick=-4] - Any optional value passed to the `dy` attribute on the text label. */ + export let dyTick = -3; $: isBandwidth = typeof $yScale.bandwidth === 'function'; @@ -42,14 +48,24 @@ typeof ticks === 'function' ? ticks($yScale.ticks()) : $yScale.ticks(ticks); + + const tickWidthEven = 3; + const charPixelWidth = 7.25; + $: tickOffsetXVal = tickOffsetX + Math.min(-10, -1 * Math.max(...tickVals.map(d => format(d).toString().split('').reduce(calcStringLength, 0)))); + + function calcStringLength(sum, val) { + if (val === ',') return sum + charPixelWidth * 0.75; + return sum + charPixelWidth; + } - + {#each tickVals as tick (tick)} - + {#if gridlines !== false} {/if} {formatTick(tick)} + dx='{dxTick}' + dy='{isBandwidth || labelPosition === 'even' ? dyTick + 6 : dyTick}' + >{format(tick)} {/each} +
+ + + + + + +
+
From cabd17d500112ad318fe0edeefcc5df722c6fa91 Mon Sep 17 00:00:00 2001 From: mhkeller Date: Sat, 10 Feb 2024 00:14:42 -0500 Subject: [PATCH 11/51] update controls --- src/routes/_components/AxisY.svelte | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/routes/_components/AxisY.svelte b/src/routes/_components/AxisY.svelte index 98857d39..94c11898 100644 --- a/src/routes/_components/AxisY.svelte +++ b/src/routes/_components/AxisY.svelte @@ -27,16 +27,21 @@ expand to fill it. */ .chart-container { - width: calc(100% - 20px); + width: calc(100% - 40px); height: 200px; } .props { + margin-top: 5px; + height: 25px; display: flex; flex-direction: row; user-select: none; - cursor: pointer; gap: 20px; } + label { + display: flex; + cursor: pointer; + }
@@ -47,15 +52,13 @@ - -
From 5dd994cf66b417bf5b76a79a8c2f6fc23e1e6178 Mon Sep 17 00:00:00 2001 From: mhkeller Date: Sat, 10 Feb 2024 16:44:31 -0500 Subject: [PATCH 12/51] axisX --- src/_components/AxisX.svelte | 89 +++++++++++++++++------------ src/_components/AxisY.svelte | 19 +++--- src/routes/_components/AxisX.svelte | 50 +++++++++++++++- src/routes/_components/AxisY.svelte | 13 ++--- src/routes/components/+page.svelte | 9 ++- 5 files changed, 124 insertions(+), 56 deletions(-) diff --git a/src/_components/AxisX.svelte b/src/_components/AxisX.svelte index e45c34d0..d216ff34 100644 --- a/src/_components/AxisX.svelte +++ b/src/_components/AxisX.svelte @@ -6,12 +6,12 @@ import { getContext } from 'svelte'; const { width, height, xScale, yRange } = getContext('LayerCake'); - /** @type {Boolean} [gridlines=true] - Extend lines from the ticks into the chart space */ - export let gridlines = true; - /** @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; @@ -19,28 +19,25 @@ export let snapTicks = 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} [xTick=0] - How far over to position the text marker. */ - export let xTick = 0; + /** @type {Number} [tickGutter=0] - The amount of whitespace between the start of the tick and the chart drawing area (the xRange min). */ + export let tickGutter = 0; - /** @type {Number} [yTick=16] - The distance from the baseline to place each tick value. */ - export let yTick = 16; + /** @type {Number} [labelOffset=12] - The amount of whitespace between the start of the tick and the chart drawing area (the xRange min). */ + export let labelOffset = 12; - $: isBandwidth = typeof $xScale.bandwidth === 'function'; + /** @type {Number} [dx=0] - Any optional value passed to the `dx` attribute on the text label. */ + export let dx = 0; - $: tickVals = Array.isArray(ticks) ? ticks : - isBandwidth ? - $xScale.domain() : - typeof ticks === 'function' ? - ticks($xScale.ticks()) : - $xScale.ticks(ticks); + /** @type {Number} [dy=0] - Any optional value passed to the `dy` attribute on the text label. */ + export let dy = 0; - function textAnchor(i) { - if (snapTicks === true) { + function textAnchor(i, st) { + if (st === true) { if (i === 0) { return 'start'; } @@ -50,41 +47,63 @@ } return 'middle'; } + + $: tickLen = typeof tickMarkLength === 'number' + ? tickMarkLength + : tickMarkLength === 'short' + ? 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 {#each tickVals as tick, i (tick)} + {#if baseline === true} + + {/if} + - {#if gridlines !== false} - - {/if} - {#if tickMarks === true} + {#if tickMarks === true && tickMarkLength === 'long'} + + {:else if tickMarks === true && (tickMarkLength === 'short' || typeof tickMarkLength === 'number')} {/if} {formatTick(tick)}{format(tick)} {/each} - {#if baseline === true} - - {/if} +
+ + + + + + + + +
+
diff --git a/src/routes/_components/AxisY.svelte b/src/routes/_components/AxisY.svelte index 94c11898..a2074964 100644 --- a/src/routes/_components/AxisY.svelte +++ b/src/routes/_components/AxisY.svelte @@ -2,7 +2,6 @@ import { LayerCake, Svg } from 'layercake'; import AxisY from '../../_components/AxisY.svelte'; - import Bar from '../../_components/Bar.svelte'; // This example loads csv data as json using @rollup/plugin-dsv import data from '../../_data/points.csv'; @@ -16,7 +15,7 @@ let tickMarks = true; let labelPosition = 'above'; - let tickMarkWidth = 'long'; + let tickMarkLength = 'long'; +
+ + + + + + + + +
+
diff --git a/src/routes/components/+page.svelte b/src/routes/components/+page.svelte index 6bd29c78..0ca330d9 100644 --- a/src/routes/components/+page.svelte +++ b/src/routes/components/+page.svelte @@ -218,7 +218,6 @@ display: flex; flex-direction: column; gap: 5px; - overflow: hidden; } .block-container :global(.chart-container) { From 4720a34b6ac869bd23c7e15e428b071b1f930e7c Mon Sep 17 00:00:00 2001 From: mhkeller Date: Sat, 10 Feb 2024 18:35:31 -0500 Subject: [PATCH 14/51] axiYRight plus other improvements --- src/_components/AxisX.svelte | 11 ++- src/_components/AxisXTop.svelte | 13 ++-- src/_components/AxisY.svelte | 10 +-- src/_components/AxisYRight.svelte | 90 ++++++++++++++---------- src/routes/_components/AxisY.svelte | 2 +- src/routes/_components/AxisYRight.svelte | 44 +++++++++++- 6 files changed, 109 insertions(+), 61 deletions(-) diff --git a/src/_components/AxisX.svelte b/src/_components/AxisX.svelte index d216ff34..2137df1a 100644 --- a/src/_components/AxisX.svelte +++ b/src/_components/AxisX.svelte @@ -24,17 +24,14 @@ /** @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 xRange min). */ + /** @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} [labelOffset=12] - The amount of whitespace between the start of the tick and the chart drawing area (the xRange min). */ - export let labelOffset = 12; - /** @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; + /** @type {Number} [dy=12] - Any optional value passed to the `dy` attribute on the text label. */ + export let dy = 12; function textAnchor(i, st) { if (st === true) { @@ -92,7 +89,7 @@ {/if} {format(tick)} {/if} {format(tick)} format(d).toString().split('').reduce(calcStringLength, 0)))); + $: widestTickLen = Math.max(10, Math.max(...tickVals.map(d => format(d).toString().split('').reduce(calcStringLength, 0)))); - $: x1 = (widestTickLen - tickGutter) - (labelPosition === 'even' ? widestTickLen : 0); + $: x1 = (-widestTickLen - tickGutter) + (labelPosition === 'even' ? widestTickLen : 0); $: y = isBandwidth ? $yScale.bandwidth() / 2 : 0; {#each tickVals as tick (tick)} - + {#if tickMarks === true && tickMarkLength === 'long'} {/if} - - + {#each tickVals as tick (tick)} - - {#if gridlines !== false} + + {#if tickMarks === true && tickMarkLength === 'long'} - {/if} - {#if tickMarks === true} + {:else if tickMarks === true && (tickMarkLength === 'short' || typeof tickMarkLength === 'number')} {/if} {formatTick(tick)} + x='{$width + tickGutter + (labelPosition === 'even' ? tickLen : 0)}' + {y} + {dx} + dy='{dy + (labelPosition === 'even' ? 4 : -3)}' + >{format(tick)} {/each} +
+ + + + + + +
+
+
From c535475eca7392f2ad9f88fde651d0d674d8bbd8 Mon Sep 17 00:00:00 2001 From: mhkeller Date: Sat, 10 Feb 2024 18:53:22 -0500 Subject: [PATCH 15/51] make axisY similar to others --- src/_components/AxisY.svelte | 13 +++++++++---- src/_components/AxisYRight.svelte | 2 +- src/routes/_components/AxisY.svelte | 2 ++ src/routes/_components/AxisYRight.svelte | 2 -- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/_components/AxisY.svelte b/src/_components/AxisY.svelte index b03163d5..aba9655d 100644 --- a/src/_components/AxisY.svelte +++ b/src/_components/AxisY.svelte @@ -48,10 +48,15 @@ return sum + charPixelWidth; } - const tickLenBase = 3; + $: tickLen = typeof tickMarkLength === 'number' + ? tickMarkLength + : tickMarkLength === 'short' + ? labelPosition === 'above' ? widestTickLen : 5 + : 0; + $: widestTickLen = Math.max(10, Math.max(...tickVals.map(d => format(d).toString().split('').reduce(calcStringLength, 0)))); - $: x1 = (-widestTickLen - tickGutter) + (labelPosition === 'even' ? widestTickLen : 0); + $: x1 = -tickGutter - (labelPosition === 'above' ? widestTickLen : tickLen); $: y = isBandwidth ? $yScale.bandwidth() / 2 : 0; @@ -70,13 +75,13 @@ {/if} format(d).toString().split('').reduce(calcStringLength, 0)))); - $: x2 = $width + tickGutter + (labelPosition === 'above' ? widestTickLen : 0); + $: x2 = $width + tickGutter + (labelPosition === 'above' ? widestTickLen : tickLen); $: y = isBandwidth ? $yScale.bandwidth() / 2 : 0; diff --git a/src/routes/_components/AxisY.svelte b/src/routes/_components/AxisY.svelte index fc0ceeba..be50fae8 100644 --- a/src/routes/_components/AxisY.svelte +++ b/src/routes/_components/AxisY.svelte @@ -2,6 +2,7 @@ import { LayerCake, Svg } from 'layercake'; import AxisY from '../../_components/AxisY.svelte'; + import Line from '../../_components/Line.svelte'; // This example loads csv data as json using @rollup/plugin-dsv import data from '../../_data/points.csv'; @@ -76,6 +77,7 @@ tickMarkLength={Number.isNaN(+tickMarkLength) ? tickMarkLength : +tickMarkLength} ticks={4} /> +
diff --git a/src/routes/_components/AxisYRight.svelte b/src/routes/_components/AxisYRight.svelte index 7bd296a1..bd086024 100644 --- a/src/routes/_components/AxisYRight.svelte +++ b/src/routes/_components/AxisYRight.svelte @@ -2,7 +2,6 @@ import { LayerCake, Svg } from 'layercake'; import AxisYRight from '../../_components/AxisYRight.svelte'; - import Line from '../../_components/Line.svelte'; // This example loads csv data as json using @rollup/plugin-dsv import data from '../../_data/points.csv'; @@ -77,7 +76,6 @@ tickMarkLength={Number.isNaN(+tickMarkLength) ? tickMarkLength : +tickMarkLength} ticks={4} /> -
From b085f943b64c73db7ad795154cdec403ce564fd1 Mon Sep 17 00:00:00 2001 From: mhkeller Date: Sun, 11 Feb 2024 13:29:33 -0500 Subject: [PATCH 16/51] adjust character calculation --- src/_components/AxisY.svelte | 2 +- src/_components/AxisYRight.svelte | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/_components/AxisY.svelte b/src/_components/AxisY.svelte index aba9655d..f37a22f3 100644 --- a/src/_components/AxisY.svelte +++ b/src/_components/AxisY.svelte @@ -44,7 +44,7 @@ $yScale.ticks(ticks); function calcStringLength(sum, val) { - if (val === ',') return sum + charPixelWidth * 0.75; + if (val === ',' || val === '.') return sum + charPixelWidth * 0.5; return sum + charPixelWidth; } diff --git a/src/_components/AxisYRight.svelte b/src/_components/AxisYRight.svelte index 003895bd..3ed284ca 100644 --- a/src/_components/AxisYRight.svelte +++ b/src/_components/AxisYRight.svelte @@ -44,7 +44,7 @@ $yScale.ticks(ticks); function calcStringLength(sum, val) { - if (val === ',') return sum + charPixelWidth * 0.75; + if (val === ',' || val === '.') return sum + charPixelWidth * 0.5; return sum + charPixelWidth; } From 015d58b31add93b01efd146de35715986768c57d Mon Sep 17 00:00:00 2001 From: mhkeller Date: Sun, 11 Feb 2024 13:44:56 -0500 Subject: [PATCH 17/51] update default axis y label position --- src/_components/AxisXTop.svelte | 3 ++- src/_components/AxisY.svelte | 8 ++++---- src/_components/AxisYRight.svelte | 6 +++--- src/routes/_components/AxisY.svelte | 2 -- src/routes/_examples/Bar.svelte | 7 ++++--- src/routes/_examples/Column.svelte | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/_components/AxisXTop.svelte b/src/_components/AxisXTop.svelte index 7262820c..2ac1279c 100644 --- a/src/_components/AxisXTop.svelte +++ b/src/_components/AxisXTop.svelte @@ -1,9 +1,10 @@ - + {#each tickVals as tick, i (tick)} {#if baseline === true} @@ -92,7 +92,7 @@ y={tickGutter + tickLen} {dx} {dy} - text-anchor={textAnchor(i, snapTicks)}>{format(tick)}{format(tick)} {/each} @@ -118,10 +118,10 @@ stroke-dasharray: 0; } /* This looks slightly better */ - .axis.snapTicks .tick:last-child text { + .axis.snapLabels .tick:last-child text { transform: translateX(3px); } - .axis.snapTicks .tick.tick-0 text { + .axis.snapLabels .tick.tick-0 text { transform: translateX(-3px); } diff --git a/src/_components/AxisXTop.svelte b/src/_components/AxisXTop.svelte index 2ac1279c..e808cc4c 100644 --- a/src/_components/AxisXTop.svelte +++ b/src/_components/AxisXTop.svelte @@ -16,8 +16,8 @@ /** @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 format = d => d; @@ -34,8 +34,8 @@ /** @type {Number} [dy=-4] - Any optional value passed to the `dy` attribute on the text label. */ export let dy = -4; - function textAnchor(i, st) { - if (st === true) { + function textAnchor(i, sl) { + if (sl === true) { if (i === 0) { return 'start'; } @@ -64,7 +64,7 @@ $: halfBand = isBandwidth ? $xScale.bandwidth() / 2 : 0 - + {#each tickVals as tick, i (tick)} {#if baseline === true} @@ -93,7 +93,7 @@ y={tickGutter - tickLen} {dx} {dy} - text-anchor={textAnchor(i, snapTicks)}>{format(tick)}{format(tick)} {/each} @@ -119,10 +119,10 @@ stroke-dasharray: 0; } /* This looks slightly better */ - .axis.snapTicks .tick:last-child text { + .axis.snapLabels .tick:last-child text { transform: translateX(3px); } - .axis.snapTicks .tick.tick-0 text { + .axis.snapLabels .tick.tick-0 text { transform: translateX(-3px); } diff --git a/src/_components/AxisY.svelte b/src/_components/AxisY.svelte index f52a2801..9458ebf2 100644 --- a/src/_components/AxisY.svelte +++ b/src/_components/AxisY.svelte @@ -10,6 +10,9 @@ /** @type {Boolean} [tickMarks=true] - Show marks next to the tick label. */ export let tickMarks = true; + /** @type {Boolean} [snapBaselineLabel=true] - Adjust the lowest label so that it sits above the tick mark and not even with it. */ + export let snapBaselineLabel = true; + /** @type {String} [labelPosition='even'] - Whether the label sits even with its value ('even') or sits on top ('above') the tick mark. Default is 'even'. */ export let labelPosition = 'even'; @@ -58,11 +61,14 @@ $: x1 = -tickGutter - (labelPosition === 'above' ? widestTickLen : tickLen); $: y = isBandwidth ? $yScale.bandwidth() / 2 : 0; + + $: maxTickValPx = Math.max(...tickVals.map($yScale)); {#each tickVals as tick (tick)} - + {@const tickValPx = $yScale(tick)} + {#if tickMarks === true && tickMarkLength === 'long'} {format(tick)} {/each} diff --git a/src/_components/AxisYRight.svelte b/src/_components/AxisYRight.svelte index 42c44b48..f814c059 100644 --- a/src/_components/AxisYRight.svelte +++ b/src/_components/AxisYRight.svelte @@ -10,6 +10,9 @@ /** @type {Boolean} [tickMarks=true] - Show marks next to the tick label. */ export let tickMarks = true; + /** @type {Boolean} [snapBaselineLabel=true] - Adjust the lowest label so that it sits above the tick mark and not even with it. */ + export let snapBaselineLabel = true; + /** @type {String} [labelPosition='even'] - Whether the label sits even with its value ('even') or sits on top ('above') the tick mark. Default is 'even'. */ export let labelPosition = 'even'; @@ -58,6 +61,8 @@ $: x2 = $width + tickGutter + (labelPosition === 'above' ? widestTickLen : tickLen); $: y = isBandwidth ? $yScale.bandwidth() / 2 : 0; + + $: maxTickValPx = Math.max(...tickVals.map($yScale)); @@ -84,7 +89,7 @@ x='{$width + tickGutter + (labelPosition === 'even' ? tickLen : 0)}' {y} {dx} - dy='{dy + (labelPosition === 'even' ? 4 : -3)}' + dy='{dy + (labelPosition === 'above' || (snapBaselineLabel === true && tickValPx === maxTickValPx) ? -3 : 4)}' >{format(tick)} {/each} From dd242449201347758a0a879fb3f2d6e2ab93bcc4 Mon Sep 17 00:00:00 2001 From: mhkeller Date: Sun, 11 Feb 2024 14:21:06 -0500 Subject: [PATCH 19/51] add missing var --- src/_components/AxisY.svelte | 6 +++--- src/_components/AxisYRight.svelte | 9 +++++---- src/routes/_components/AxisY.svelte | 7 +++++++ src/routes/_components/AxisYRight.svelte | 7 +++++++ 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/_components/AxisY.svelte b/src/_components/AxisY.svelte index 9458ebf2..5e6a82f9 100644 --- a/src/_components/AxisY.svelte +++ b/src/_components/AxisY.svelte @@ -10,12 +10,12 @@ /** @type {Boolean} [tickMarks=true] - Show marks next to the tick label. */ export let tickMarks = true; - /** @type {Boolean} [snapBaselineLabel=true] - Adjust the lowest label so that it sits above the tick mark and not even with it. */ - export let snapBaselineLabel = true; - /** @type {String} [labelPosition='even'] - Whether the label sits even with its value ('even') or sits on top ('above') the tick mark. Default is 'even'. */ export let labelPosition = 'even'; + /** @type {Boolean} [snapBaselineLabel=false] - When labelPosition='even', adjust the lowest label so that it sits above the tick mark. */ + export let snapBaselineLabel = 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'; diff --git a/src/_components/AxisYRight.svelte b/src/_components/AxisYRight.svelte index f814c059..24b0107d 100644 --- a/src/_components/AxisYRight.svelte +++ b/src/_components/AxisYRight.svelte @@ -10,12 +10,12 @@ /** @type {Boolean} [tickMarks=true] - Show marks next to the tick label. */ export let tickMarks = true; - /** @type {Boolean} [snapBaselineLabel=true] - Adjust the lowest label so that it sits above the tick mark and not even with it. */ - export let snapBaselineLabel = true; - /** @type {String} [labelPosition='even'] - Whether the label sits even with its value ('even') or sits on top ('above') the tick mark. Default is 'even'. */ export let labelPosition = 'even'; + /** @type {Boolean} [snapBaselineLabel=false] - When labelPosition='even', adjust the lowest label so that it sits above the tick mark. */ + export let snapBaselineLabel = 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'; @@ -67,7 +67,8 @@ {#each tickVals as tick (tick)} - + {@const tickValPx = $yScale(tick)} + {#if tickMarks === true && tickMarkLength === 'long'} @@ -31,11 +32,13 @@ } .props { margin-top: 5px; + margin-bottom: 25px; height: 25px; display: flex; flex-direction: row; user-select: none; gap: 10px; + flex-wrap: wrap; } label { display: flex; @@ -60,6 +63,9 @@ +
@@ -72,6 +78,7 @@ @@ -36,6 +37,8 @@ flex-direction: row; user-select: none; gap: 10px; + margin-bottom: 25px; + flex-wrap: wrap; } label { display: flex; @@ -60,6 +63,9 @@ +
@@ -73,6 +79,7 @@ From e5a57221a5b1fa3754f87738b62f8072c039c308 Mon Sep 17 00:00:00 2001 From: mhkeller Date: Sun, 11 Feb 2024 14:23:36 -0500 Subject: [PATCH 20/51] update ux controls --- src/routes/_components/AxisY.svelte | 4 +++- src/routes/_components/AxisYRight.svelte | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/routes/_components/AxisY.svelte b/src/routes/_components/AxisY.svelte index 9de8a555..ec2c7f77 100644 --- a/src/routes/_components/AxisY.svelte +++ b/src/routes/_components/AxisY.svelte @@ -42,6 +42,8 @@ } label { display: flex; + } + label:not(.disabled) { cursor: pointer; } @@ -63,7 +65,7 @@ -
diff --git a/src/routes/_components/AxisYRight.svelte b/src/routes/_components/AxisYRight.svelte index f7725547..2e07757f 100644 --- a/src/routes/_components/AxisYRight.svelte +++ b/src/routes/_components/AxisYRight.svelte @@ -42,6 +42,8 @@ } label { display: flex; + } + label:not(.disabled) { cursor: pointer; } @@ -63,7 +65,7 @@ -