[BarChart] Group series label position
Hi, Thanks for the great library. I have a question, How to set the label position for the BarChart group? Right now I have the result like below, the labels is in between. I'm using the BarChart component, not the primitive.
Thanks
Hi @ariefsn, thanks for the kind words. Sadly, you've encountered an outstanding issue I need to address, and hope to as part of the Svelte 5 migration (the short is we need to update Points/Labels to account for x1Scale (i.e. a derived x scale used for group layouts) similar to Bar)
With that said, you can roll your own by overriding one of the slots within BarChart (like aboveMarks) and iterate the series and data to render Text instances.
For example:
<BarChart
data={wideData}
x="year"
series={[
{ key: 'apples', color: 'hsl(var(--color-danger))' },
{
key: 'bananas',
color: 'hsl(var(--color-warning))',
},
{
key: 'cherries',
color: 'hsl(var(--color-success))',
},
{
key: 'grapes',
color: 'hsl(var(--color-info))',
},
]}
seriesLayout="group"
>
<svelte:fragment slot="aboveMarks" let:xScale let:x1Scale let:yScale let:visibleSeries>
{#each visibleSeries as s}
{#each wideData as d}
{@const value = d[s.key]}
<Text
x={xScale(d.year) + x1Scale(s.key) + x1Scale.bandwidth() / 2}
y={yScale(value) - 2}
{value}
textAnchor="middle"
class="text-xs"
/>
{/each}
{/each}
</svelte:fragment>
</BarChart>
You will need the freshly released 1.0.10 which passes the x1Scale as a slot prop (btw, this is even cleaner with the upcoming LayerChart 2.0.0 / Svelte 5 migration using snippets).
Hi @ariefsn, thanks for the kind words. Sadly, you've encountered an outstanding issue I need to address, and hope to as part of the Svelte 5 migration (the short is we need to update Points/Labels to account for
x1Scale(i.e. a derived x scale used for group layouts) similar toBar)With that said, you can roll your own by overriding one of the slots within
BarChart(likeaboveMarks) and iterate the series and data to renderTextinstances.For example:
<BarChart data={wideData} x="year" series={[ { key: 'apples', color: 'hsl(var(--color-danger))' }, { key: 'bananas', color: 'hsl(var(--color-warning))', }, { key: 'cherries', color: 'hsl(var(--color-success))', }, { key: 'grapes', color: 'hsl(var(--color-info))', }, ]} seriesLayout="group"
<svelte:fragment slot="aboveMarks" let:xScale let:x1Scale let:yScale let:visibleSeries> {#each visibleSeries as s} {#each wideData as d} {@const value = d[s.key]} <Text x={xScale(d.year) + x1Scale(s.key) + x1Scale.bandwidth() / 2} y={yScale(value) - 2} {value} textAnchor="middle" class="text-xs" /> {/each} {/each} </svelte:fragment> </BarChart> You will need the freshly released 1.0.10 which passes the
x1Scaleas a slot prop (btw, this is even cleaner with the upcoming LayerChart 2.0.0 / Svelte 5 migration using snippets).
Hi, thank you for the detailed response! I am trying to figure out your solution with LayerChart next version but looks like those props are no longer being passed to the snippets. How could this be achieve in the next version?
Hey @zacharya19 👋
In LayerChart next we consolidated most of these slots props into a single context snippet argument.
This is equivalent to the above:
{#snippet aboveMarks({ context, visibleSeries })}
{#each visibleSeries as s}
{#each wideData as d}
{@const value = d[s.key]}
<Text
x={context.xScale(d.year) + context.x1Scale(s.key) + context.x1Scale.bandwidth() / 2}
y={context.yScale(value)}
{value}
textAnchor="middle"
class="text-xs"
/>
{/each}
{/each}
{/snippet}