Archived

Documentation for Layer Cake v10, before Svelte 5 runes. Current docs at layercake.graphics

Menu

Key.html.svelte component

Generates an HTML key for an ordinal c scale, with one chip and label per domain value.

Param Default Required Description
shape ('circle' | 'line' | 'square') 'square'
no
The shape of each chip.
align ('start' | 'center' | 'end') 'start'
no
Where the key sits in its box, as flexbox justify-content.
lookup (((d: any) => string) | Record<string, string>) None
no
Either a function that formats a value, or an object mapping values to labels. A value missing from the object is shown as is.
capitalize boolean true
no
Capitalize the first character of each label.

Used in these examples:

<!--
  @component
  Generates an HTML key for an ordinal `c` scale, with one chip and label per domain value.
 -->
<script>
  import { getLayerCakeContext } from 'layercake';

  const k = getLayerCakeContext();

  /**
   * @typedef {Object} Props
   * @property {'circle'|'line'|'square'} [shape='square'] - The shape of each chip.
   * @property {'start'|'center'|'end'} [align='start'] - Where the key sits in its box, as flexbox `justify-content`.
   * @property {((d: any) => string)|Record<string, string>} [lookup] - Either a function that formats a value, or an object mapping values to labels. A value missing from the object is shown as is.
   * @property {boolean} [capitalize=true] - Capitalize the first character of each label.
   */

  /** @type {Props} */
  let { shape = 'square', align = 'start', lookup, capitalize = true } = $props();

  /** @param {any} val */
  function capitalizeFirst(val) {
    return String(val).replace(/^\w/, d => d.toUpperCase());
  }

  /** @param {any} val */
  function displayName(val) {
    if (lookup) {
      return typeof lookup === 'function' ? lookup(val) : lookup[val] || val;
    }
    return capitalize === true ? capitalizeFirst(val) : val;
  }
</script>

<div class="key" style="justify-content: {align === 'end' ? 'flex-end' : align};">
  {#each k.cDomain as item}
    <div class="key-item">
      <div
        class="chip chip__{shape}"
        style="background: {shape === `line`
          ? `linear-gradient(-45deg, #ffffff 40%, ${k.cScale?.(item) ?? '#ccc'} 41%, ${k.cScale?.(item) ?? '#ccc'} 59%, #ffffff 60%)`
          : (k.cScale?.(item) ?? '#ccc')};"
      ></div>
      <div class="name">{displayName(item)}</div>
    </div>
  {/each}
</div>

<style>
  .key {
    display: flex;
  }
  .key-item {
    margin-right: 14px;
  }
  .chip {
    display: inline-block;
    position: relative;
    width: 12px;
    height: 12px;
  }
  .chip__circle {
    border-radius: 50%;
  }
  .chip__line:after {
    content: '';
    position: absolute;
    border-width: 3px;
    width: 14px;
    transform: rotate(-45deg);
    transform-origin: 14px 5px;
  }
  .name {
    display: inline;
    font-size: 14px;
    text-shadow:
      -1px -1px 0 #fff,
      1px -1px 0 #fff,
      -1px 1px 0 #fff,
      1px 1px 0 #fff;
  }
</style>