A headless React hook for building beautiful gauge charts.

Overview

use-gauge

npm version bundlesize

A headless React hook for building gauge charts. You bring the styles, we bring the math that powers your chart!

Screen Shot 2022-02-08 at 11 05 36 PM

Code for the examples above πŸ‘† https://i19w7.csb.app/

Installation

yarn add use-gauge

Usage

🚨 Beware that this API is very much in flux! Breaking changes will occur, but I'll update these docs and the Codesandbox accordingly 🚨

In your React project, import the useGauge hook and invoke it with the following parameters.

const {
  ticks,
  valueToAngle,
  angleToValue,
  getTickProps,
  getLabelProps,
  getArcProps,
  getNeedleProps,
  getSVGProps,
} = useGauge({
  startAngle: 90, // The bottom of the gauge is considered 90 degrees, so this means 90 degrees FROM 90, so 180.
  endAngle: 270, // And this means 270 degrees FROM 90, so 360.
  numTicks, // the number of ticks to display between the min and max values
  diameter, // diameter of the gauge itself
  domain: [minValue, maxValue], // Min and max values for your gauge. *Please* use a min that's smaller than the max :)
});

If you want to skip ahead and see a fully baked implementation of this hook, check out the example playground.

Otherwise, here's a brief explanation of how these returned values work.

getSVGProps

Please be sure to apply these props to your SVG element, as it's responsible for programatically updating the height, width, and viewBox of the element as a function of the diameter you provide.

<svg {...getSVGProps()}></svg>

ticks, getTickProps, getLabelProps, and angleToValue

ticks is an array of evenly spaced angles (represented as numbers) that's calculated from the numTicks, startAngle, and endAngle argument.

You can create visual tick marks on the SVG by mapping over this array and passing each angle (along with a length argument) to the getTickProps function accordingly.

Additionally, you can render text labels for tick mark by invoking the getLabelProps on the given angle (along wiht an offset argument that determines how far the label sits from the tick).

Note that you'll need to convert the given angle to its "value" counterpart (as minValue and maxValue are the domain of our dataset) by invoking the angleToValue function with the given angle as an argument.

{
  ticks.map((angle) => {
    return (
      <React.Fragment key={`tick-group-${angle}`}>
        <line
          stroke={tickColor}
          {...getTickProps({ angle, length: tickLength })}
        />
        <text
          className="text-sm fill-gray-500 font-medium"
          {...getLabelProps({ angle, offset: 20 })}
        >
          {angleToValue(angle)}
        </text>
      </React.Fragment>
    );
  });
}

getArcProps

This function allows you to render arcs of arbitrary length, as expressed by a start angle and end angle. A common use-case might be to have two arcs: one as a "background", and another that represents the progress of the gauge.

You can calculate progress in this scenario by converting your numerical value to its angle counterpart with the valueToAngle function.

// Background
<path
  {...getArcProps({ offset, startAngle: 90, endAngle: 270 })}
  className="stroke-gray-100"
  strokeLinecap="round"
  strokeWidth={24}
/>

// Progress
<path
{...getArcProps({
  offset,
  startAngle,
  endAngle: valueToAngle(value),
})}
className="stroke-blue-600"
strokeLinecap="round"
strokeWidth={24}
/>

getNeedleProps

Last but not least, this function helps you draw a needle shape on your gauge. Specifically, it returns the bits you need to draw: A) the "tip" of the needle (i.e., the small circle at the top), B) the "base" of the needle (i.e., the bigger circle at the bottom), and C) the "body" of the needle (i.e., the polyline that connects these two circles).

Warning: this API is janky. There's got to be a better way of handling this, but again, this is what worked for my initial use case πŸ€·πŸ»β€β™‚οΈ

const { tip, base, points } = getNeedleProps({
  value,
  baseRadius: 12,
  tipRadius: 8,
});

<g id="needle">
  <circle className="fill-gray-300" {...base} r={24} />
  <circle fill={needleColor} {...base} />
  <circle fill={needleColor} {...tip} />
  <polyline fill={needleColor} points={points} />
  <circle className="fill-white" {...base} r={4} />
</g>;

Local Development

From the project root, run yarn start. This will run tsdx in watch mode, and will re-compile the code every time you save.

In a different terminal window, cd into the /example directory and run yarn start. This will boot up Parcel and open a web server at http://localhost:1234. All of your changes to the hook source code will (eventually) propagate to Parcel's hot-reloading server.

You might also like...
Reactochart is a library of React components for creating data visualization charts and graphs.
Reactochart is a library of React components for creating data visualization charts and graphs.

Reactochart is a library of React components for creating data visualization charts and graphs. Components include line chart, bar chart, area chart, heat maps, scatterplot, histogram, pie chart, sankey diagram, and tree map.

βš›οΈ Simple, immersive & interactive charts for React

βš›οΈ Simple, immersive & interactive charts for React

A React library for creating animated charts visualizations based on dynamic data.
A React library for creating animated charts visualizations based on dynamic data.

react-dynamic-charts (demo) A React library for creating animated charts visualizations based on dynamic data. Install npm install --save react-dynami

React wrapper for Smoothie Charts

react-smoothie React wrapper for Smoothie Charts. Install With Yarn: yarn add react-smoothie With NPM: npm install react-smoothie --save Install from

React-based drag'n'drop pivot table with Plotly.js charts
React-based drag'n'drop pivot table with Plotly.js charts

react-pivottable react-pivottable is a React-based pivot table library with drag'n'drop functionality. It is a React port of the jQuery-based PivotTab

βš›οΈ Simple, immersive & interactive charts for React

Simple, immersive and interactive charts for React Enjoy this library? Try the entire TanStack! React Table, React Query, React Form Visit react-chart

A collection of easy to use charts created in D3 for your React applications.

react-charts-d3 A collection of easy to use charts created in D3 for your React applications. Area Chart Bar Chart Bubble Chart Line Chart Pie Chart S

Plug and play React charts

Orama [DEPRECATED] This package has been deprecated as it is no longer used by Kensho internally and we do not plan to continue maintaining it. We hop

Bar, Line, Area, Pie, and Donut charts in React Native
Bar, Line, Area, Pie, and Donut charts in React Native

react-native-gifted-charts The most complete library for Bar, Line, Area, Pie, and Donut charts in React Native. Allows 2D, 3D, gradient, animations a

Comments
  • I want to add 4 dynamic values as ticks, low, high and medium value, but based on angle, and function angleToValue its not showing values How do I resolve this

    I want to add 4 dynamic values as ticks, low, high and medium value, but based on angle, and function angleToValue its not showing values How do I resolve this

    {gauge.ticks.map((angle) => { console.log(angle); const asValue = gauge.angleToValue(angle); console.log(asValue); const showText = asValue === 0 || asValue === props.low|| asValue === props.medium|| asValue === props.high; return ( {showText && ( <> {asValue} )} ); })}
    opened by kashkumar12 5
  • bug: Arc strokeWidth can cause overflow

    bug: Arc strokeWidth can cause overflow

    For whatever reason, the arc's stroke-width isn't being taken into account when we redraw the SVG's bounding box. I even tried using this API for including stroke in the calculation but it doesn't seem to be working in Chrome.

    getBBox({stroke: true})
    

    https://developer.mozilla.org/en-US/docs/Web/API/SVGGraphicsElement/getBBox#parameters

    Screen Shot 2022-02-09 at 8 11 36 AM

    As a workaround, you can increase the gauge's padding to account for this, or allow overflow.

    bug 
    opened by mattrothenberg 1
  • feat: dynamic SVG size

    feat: dynamic SVG size

    We need to recalculate the width, height, and viewBox of the SVG anytime a user changes an inner property (such as tick length, arc strokeWidth, etc.)

    This PR adds a private, imperative API for doing so. Unclear whether it impacts perf too badly 🀷

    opened by mattrothenberg 1
  • enhancement: different needle shapes

    enhancement: different needle shapes

    Currently, there's only one needle shape – this weird thing where we connect a smaller circle ("tip") to a larger circle ("base") and fill in the rest with a polyline. It'd be cool if users could provide their own needle shape, be it an arrow, a straight line, etc.

    Screen Shot 2022-02-09 at 8 41 23 AM enhancement 
    opened by mattrothenberg 0
Owner
Matt Rothenberg
Matt Rothenberg
Create beautiful JavaScript charts with one line of React

React Chartkick Create beautiful JavaScript charts with one line of React See it in action Supports Chart.js, Google Charts, and Highcharts Quick Star

Andrew Kane 1.2k Dec 28, 2022
πŸ“Š πŸ“ˆ πŸ“‰ React.js plugin for building charts using CSS

Chartify React.js plugin for building charts using CSS. Demo The source for this module is in the main repo. Example app is here. Backend service for

Kirill Stepkin 685 Jan 1, 2023
πŸ“Š πŸ“ˆ πŸ“‰ React.js plugin for building charts using CSS

Chartify React.js plugin for building charts using CSS. Demo The source for this module is in the main repo. Example app is here. Backend service for

Kirill Stepkin 685 Jan 1, 2023
React components for building composable and flexible charts

rumble-charts React components for building composable and flexible charts to visualize your data. It's based on D3.js under the hood, but most of the

null 338 Dec 26, 2022
Highly customizable library for building interactive node-based UIs, editors, flow charts and diagrams

React Flow is a library for building node-based graphs. You can easily implement custom node types and it comes with components like a mini-map and graph controls.

webkid 13.2k Jan 4, 2023
A declarative, efficient, and simple JavaScript library for building responsive charts

A declarative, efficient, and simple JavaScript library for building responsive charts

ZingChart 254 Dec 8, 2022
React minimal pie chart🍰 Lightweight but versatile SVG pie/donut charts for React. < 2kB gzipped.

React minimal pie chart Lightweight React SVG pie charts, with versatile options and CSS animation included. < 2kB gzipped. ?? Demo ?? . Why? Because

Andrea Carraro 341 Dec 14, 2022
Modular React charts made with d3.js

Update Important update: The actively maintained fork of this project is now at the Github of react-d3 co-creator yang-wei, who has recently taken the

Eric S. Bullington 1.8k Oct 27, 2022
Customizable React-based editor panel for Plotly charts

Customizable React-based editor panel for Plotly charts

Plotly 443 Jan 1, 2023
react d3 charts

CRA-MHL A Professional Starter Create React App (CRA) with Must-Have Libraries (MHL) Template A very opinionated starter Create React App (CRA) templa

Oscar Cardoso Garcia 6 Oct 19, 2022