1.2.0 ā€¢ Published 1 year ago

react-native-cool-speedometer v1.2.0

Weekly downloads
5
License
ISC
Repository
github
Last release
1 year ago

Cool Speedometer šŸ˜Ž

If you are tired of all those boring speedometers for react native, have a look at this one. This is different. This is cool.

Cool speedometer

Cool speedometer

āœ… Flexible

āœ… Performant

āœ… Support for negative numbers

āœ… Made out of SVG

āœ… Animated

āœ… More customization than you'll use

āœ… Cool šŸ˜Ž

Install it for free:

npm i react-native-cool-speedometer

Usage

Default speedometer

import Speedometer, {
  Background,
  Arc,
  Needle,
  Progress,
  Marks,
  Indicator,
} from 'react-native-cool-speedometer';

// a few lines later ...

<Speedometer
  value={128}
  fontFamily='squada-one'
>
  <Background />
  <Arc/>
  <Needle/>
  <Progress/>
  <Marks/>
  <Indicator/>
</Speedometer>

That's it, you can play around changing some of the components inside <Speedometer>. Take in mind the order of them matters: <Background> is first because it is meant to be behind all other components.

sizing

By default, the size of the component is 250. You can resize it by passing a different width. You can also change the height, if you need a proportion other than 1:1.


Examples

Playing with angle

Half speedometer

<Speedometer
  value={54}
  max={80}
  angle={160}
  fontFamily='squada-one'
>
  <Background angle={180} />
  <Arc/>
  <Needle/>
  <Progress/>
  <Marks/>
  <Indicator>
    {(value, textProps) => (
      <Text
        {...textProps}
        fontSize={60}
        fill="#555"
        x={250 / 2}
        y={210}
        textAnchor="middle"
        fontFamily='squada-one'
      >
        {value}k/m
      </Text>
    )}
  </Indicator>
</Speedometer>

Rotated

Changing rotation, step, the looking of <Needle/>, and adding <DangerPath/>:

Rotated speedometer

<Speedometer
  value={5}
  max={11}
  rotation={-90}
  fontFamily='squada-one'
>
  <Background />
  <Arc arcWidth={4} />
  <Needle
    baseOffset={40}
    circleRadius={30}
  />
  <DangerPath/>
  <Progress arcWidth={10} />
  <Marks step={1} />
</Speedometer>

If speed is not your thing

Circular progress

See code

Thermostat

See code


God mode

When I said "more customization than you'll use", I meant it.

Custom marks

Pass a function as children to render your own marks. This function receives:

  • coordinates
    Coordinates of the current line: { x1, y1, x2, y2 }. Either pass them to a <Line> component, or use them to create whatever you like, as long as it is made of SVG.

  • textProps
    Coordinates and rotation for the text: { x, y, transform }. It is recommended you apply this object to a <Text> element.

  • value
    The value of this mark.
import { G, Line } from 'react-native-svg'

// later ...
<Marks step={5}>
  {(mark, i) => (
    <G key={i}>
      <Line
        {...mark.coordinates}
        // any other prop here, except x1, y1, x2, and y2
      />
      {(i % 2 == 0) && (
        // only show the number if the mark is even
        <Text
          {...mark.textProps}
          // any other prop here, except x, y, and transform
        >
          {mark.value}
        </Text>
      )}
    </G>
  )}
</Marks>

Custom needle

Pass a function as children to make a custom needle. It will rotate automatically.

<Speedometer width={width}>
  <Needle>
    {() => {
      // you might need the center of the circle
      // to place the needle correctly
      const center = width / 2

      return (
        // some magic SVG here
      )
    }}
  </Needle>
</Speedometer>

Custom indicator

Pass a function as children to make a custom indicator. You can use this to place the indicator in the center of the circle:

<Speedometer width={width}>
  <Indicator>
    {(value, textProps) => (
      <Text
        {...textProps} // textProps has the "transform" property only
        fontSize={40}
        x={width / 2}
        y={width / 2 + 10}
        textAnchor="middle"
        alignmentBaseline="middle"
      >
        {value}
      </Text>
    )}
  </Indicator>
</Speedometer>

SpeedometerContext

You can achieve virtually anything you need by using the context:

import {
  SpeedometerContext
} from './react-native-cool-speedometer'
import { G, Line } from 'react-native-svg'
import { useContext } from 'react'

const MyCustomSVG = () => {

  const {
    currentFillAngle,
    radius,
    rotation,
    min,
    max,
    angle,
    lineCap,
    accentColor,
    fontFamily,
    value,
  } = useContext(SpeedometerContext);

  return (
    <Line
      rotation={rotation}
      // more magic here
    />
  )
}

const App = () => {

  return (
    <Speedometer>
      <Background />
      <Needle />
      <MyCustomSVG />
    </Speedometer>
  )
}

Just SVG

It is possible to wrap any component inside a <G> tag and add more vectors:

<Speedometer>
  <G opacity={0.4}>
    <Needle/>
  </G>
  <Line />
  <Polygon />
</Speedometer>

Properties

PropDefaultTypeDescription
width250numberWidth of the component
heightsame as widthnumberHeight of the component
angle250numberAngle of the speedometer in degrees
rotationnumberBy default, the rotation is computed with the given angle to keep the marks symmetrical. If you want to change the rotation (like this example) take in mind that "0" is at the top of the circle.
value0numberCurrent value of the speedometer, this is what you typically change dynamically
min0numberMinimum value, can be a negative number
max180numberMax value
lineCap'butt'stringLine terminations, can be butt, line, or square
accentColor'#00e0ff'stringAccent color. Used by default for the progress bar, and the circle of the needle.
fontFamily'helvetica'stringFont to use in the indicator and the marks. You need to configure in your project the font you want to use.

Background

PropDefaultTypeDescription
angle360numberA lower angle will result in a shorter circle
color'black'stringColor of background
opacity0.5numberOpacity of background

And any other Path prop

Arc

PropDefaultTypeDescription
color'blackColor of the arc behind the progress
opacity0.3Opacity of the arc behind the progress
arcWidth4numberWidth of the arc behind the progress
lineCaplineCap defined in <Speedometer>, or buttstringLine terminations, can be butt, line, or square

And any other Path prop

Needle

PropDefaultTypeDescription
offset25numberDistance from the border of the circle. A higher number will make the needle shorter.
baseWidth6numberWidth of the base of the needle
baseOffset18numberDistance of the base from the center of the circle
color'white'stringColor of the needle
circleRadius15numberRadius of the circle at the base of the needle
circleColorSame as global accentColorstringColor of the circle at the base of the needle

DangerPath

PropDefaultTypeDescription
color'#FF3333'stringColor of the danger path
angle50numberAngle of the danger path, from the right
arcWidth4stringWidth of the danger path
lineCapsame as global lineCapstringLine terminations, can be butt, line, or square
offset6numberDistance from the border of the circle

And any other Path prop

Progress

PropDefaultTypeDescription
colorSame as global accentColorstringColor of the progress bar
arcWidth5numberWidth of the progress bar
lineCapSame as global lineCapstringLine terminations, can be butt, line, or square

And any other Path prop

Marks

PropDefaultTypeDescription
step10numberTimes max will be divided in, to show the line marks
lineCap'butt'stringLine terminations, can be butt, line, or square
lineColor'white'stringColor of lines
lineOpacity1numberOpacity of lines
numbersRadius17numberDistance from the border of the circle
fontSize18numberFont size of the numbers
lineSize12numberLarge of the lines

Indicator

PropDefaultTypeDescription
suffixstringText after the value
fontSize45numberFont size of the indicator
color'white'stringText color of the indicator
fontFamilySame as global fontFamilynumberFont family of the indicator
textAnchor'middle'stringAlignment of the indicator, can be end, middle, or start

Any other Text property (Text is from 'react-native-svg', not 'react-native')