npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

svelte-bar-chart-race

v0.1.2

Published

Bar chart race visualization for Svelte

Downloads

67

Readme

svelte-bar-chart-race

NPM

Bar chart race visualization for Svelte

A bar chart race is a horizontal bar chart that animates bars over an interval (usually time). The x-axis represents the bar chart values. The bars are sorted based on their value from highest to lowest as the interval changes.

This library exports the following components:

  • BarChartRace: Parent component that accepts data, options and manages internal state
  • Chart: Child component that displays the chart with the ability to customize the chart display and animation
  • Slider: Child component that shows the range input to control the interval (current value)

Demo · Svelte REPL

Installation

# Yarn
yarn add -D svelte-bar-chart-race

# NPM
npm i -D svelte-bar-chart-race

# pnpm
pnpm i -D svelte-bar-chart-race

Usage

The examples use data sampled from StackOverflow's annual developer survey for "Most Loved Languages."

// demo/data.ts
export const data = [
  {
    title: "Rust",
    color: "#dea584",
    values: [
      { year: 2021, value: 86.98 },
      { year: 2020, value: 86.1 },
      { year: 2019, value: 83.5 },
      { year: 2018, value: 78.9 },
      { year: 2017, value: 73.1 },
    ],
  },
  {
    title: "TypeScript",
    color: "#2b7489",
    values: [
      { year: 2021, value: 72.73 },
      { year: 2020, value: 67.1 },
      { year: 2019, value: 73.1 },
      { year: 2018, value: 67.0 },
      { year: 2017, value: 64.1 },
    ],
  },
  {
    title: "Python",
    color: "#3572A5",
    values: [
      { year: 2021, value: 67.83 },
      { year: 2020, value: 66.7 },
      { year: 2019, value: 73.1 },
      { year: 2018, value: 68.0 },
      { year: 2017, value: 62.7 },
    ],
  },
  {
    title: "Go",
    color: "#00ADD8",
    values: [
      { year: 2021, value: 62.74 },
      { year: 2020, value: 62.3 },
      { year: 2019, value: 67.9 },
      { year: 2018, value: 65.6 },
      { year: 2017, value: 63.3 },
    ],
  },
  {
    title: "Swift",
    color: "#F05138",
    values: [
      { year: 2021, value: 63.56 },
      { year: 2020, value: 59.5 },
      { year: 2019, value: 69.2 },
      { year: 2018, value: 65.1 },
      { year: 2017, value: 63.7 },
    ],
  },
];

Simple

In the simplest example, all you need is to pass data to BarChartRace.

Then, pass Chart and Slider through its default slot.

<script>
  import { BarChartRace, Slider, Chart } from "svelte-bar-chart-race";
  import { data } from "./data";
</script>

<BarChartRace {data}>
  <Chart />
  <Slider />
</BarChartRace>

Source: demo/Simple.svelte

Two-way Binding

The currentValue prop supports two-way binding.

In this example, the initial value is 2018. Any change to the currentValue via Slider will be reflected to the bound value.

currentValue can also be programmatically updated.

Finally, setting currentValue to null resets the value to the lowest value (in this case, 2017).

<script>
  import { BarChartRace, Slider, Chart } from "svelte-bar-chart-race";
  import { data } from "./data";

  let currentValue = 2018;
</script>

<BarChartRace {data} bind:currentValue>
  <Slider />
  <Chart />
</BarChartRace>

<button on:click={() => (currentValue = 2020)}> Set value to 2020 </button>
<button on:click={() => (currentValue = null)}> Set value to null </button>

Current value:
<strong>{currentValue}</strong>

Source: demo/TwoWayBinding.svelte

Kitchen Sink

The kitchen sink showcases all available features.

An alternative to accessing the currentValue is to destructure it from the BarChartRace slot using the let: directive.

Other slot props include:

  • setMax (() => void): sets the current value to the maximum value defined in data
  • setMin (() => void): sets the current value to the minimum value defined in data
  • setValue ((value: number) => void): sets the current value to the provided value
  • play (() => void): function to animate the bar chart
  • pause (() => void): function to pause the animation
  • isPlaying (boolean): true if the chart is currently animating
<script>
  import { BarChartRace, Slider, Chart } from "svelte-bar-chart-race";
  import { quadOut } from "svelte/easing";
  import { data } from "./data";
</script>

<BarChartRace
  {data}
  interval={1_500}
  options={{ key: "year" }}
  let:currentValue={value}
  let:setMax
  let:setMin
  let:setValue
  let:play
  let:pause
  let:isPlaying
>
  <Slider labelText="Year: {value}" />
  <Chart
    --bar-height="10px"
    --bar-margin-bottom="12px"
    animate={{
      easing: quadOut,
      duration: 400,
      delay: 50,
    }}
    let:datum
  >
    <strong>{datum.title}</strong>
    {datum.value.toFixed(1)}%
  </Chart>
  <button on:click={isPlaying ? pause : play}>
    {isPlaying ? "Pause" : "Play"}
  </button>
  <button on:click={setMax}>Set max</button>
  <button on:click={setMin}>Set min</button>
  <button on:click={() => setValue(2019)}> Set value to 2019 </button>
</BarChartRace>

Source: demo/KitchenSink.svelte

API

BarChartRace

Props

| Prop | Type | Default value | | :------- | :-------------------- | :--------------------------------- | | data | BarChartRaceDatum[] | [] | | options | BarChartRaceOptions | { key: "", unit: "%", max: 100 } | | interval | number | 2_000 |

If no key is explicitly provided to options, BarChartRace will infer the key by finding the first key that is not "value" in data[0].values.

interface BarChartRaceDatum {
  /**
   * Title must be unique because it's
   * used as a key in `Chart.svelte`.
   */
  title: string;

  /**
   * Specify the chart bar color.
   * @default "#333"
   * @example "red"
   * @example "#f00"
   */
  color?: string;

  /**
   * Tabular data used as values for each bar.
   * @example
   * [
      { key: 2021, value: 63.56 },
      { key: 2020, value: 59.5 },
      // ...
     ]
   */
  values: BarChartRaceValue[];
}

interface BarChartRaceOptions {
  /**
   * Specify the key used to normalize values in the `data.values` array.
   * If no key is specified, it will be inferred.
   * @example
   * For a value object { year: 2021, value: 62.74 },
   * the inferred key would be "year".
   */
  key?: any;

  /**
   * Specify the unit.
   * @default "%"
   */
  unit?: string;

  /**
   * Specify the maximum value the
   * chart value should be divided by.
   * @default 100
   */
  max?: number;
}

Slots

Use the default slot to pass through the Chart and Slider components or any other element.

<BarChartRace
  {data}
  let:currentValue
  let:isPlaying
  let:setMax
  let:setMin
  let:setValue
  let:play
  let:pause
>
  <!-- Default slot -->
</BarChartRace>

Chart

Props

| Prop | Type | Default value | | :------ | :----------- | :------------------------------------------------------------------ | | animate | FlipParams | { delay: 0, duration: d => Math.sqrt(d) * 120, easing: cubicOut } |

The Chart component uses the flip function to animate the bar chart.

Svelte provides numerous easing functions you can use to customize the animation.

<script>
  import { quadOut } from "svelte/easing";
</script>

<Chart
  animate={{
    easing: quadOut,
    duration: 400,
    delay: 50,
  }}
/>

Style Props

Customize the chart styles using --style-props.

| Style prop | Description | Default value | | :------------------ | :---------------------- | :------------ | | --bar-height | Chart bar height | 6px | | --bar-margin-top | Chart bar margin top | 4px | | --bar-margin-bottom | Chart bar margin bottom | 10px | | --chart-padding | ol element padding | 0 |

<Chart
  --bar-height="10px"
  --margin-top="20px"
  --margin-bottom="20px"
  --chart-padding="40px"
/>

Slots

Use the default slot to customize the bar chart display value.

Access arbitrary values from data values.

<Chart let:datum>
  <strong>{datum.title}</strong>
  {datum.value}%
  {datum.additionalValue ?? ""}
</Chart>

Slider

Props

| Name | Type | Default value | | :-------- | :------- | :--------------------------------------- | | id | string | "slider-" + Math.random().toString(36) | | labelText | any | "" |

The current value from BarChartRace will be used as the labelText.

Customize labelText to override this behavior.

<Slider labelText="Year: {value}" />

Changelog

CHANGELOG.md

License

MIT