Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kubk committed Sep 16, 2019
0 parents commit 90e502d
Show file tree
Hide file tree
Showing 31 changed files with 18,293 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules
lib
.idea
dist
.cache
examples/node_modules
examples/.cache
examples/dist
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"printWidth": 90
}
18 changes: 18 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
language: node_js

node_js:
- '10'

before_script:
- npm install
- cd examples && npm install

script:
- npm run lint
- npm run typecheck
- npm run test
- npm run build && npm run bundlesize
- cd examples && npm run typecheck

notifications:
email: false
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
## gauge-chart-js [![NPM version](https://badge.fury.io/js/simple-slider.svg)](https://npmjs.org/package/gauge-chart-js) [![Build Status](https://travis-ci.org/kubk/gauge-chart-js.svg?branch=master)](https://travis-ci.org/kubk/gauge-chart-js) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)

A tiny (<2kb gzipped) library for rendering gauge charts. Supports conical/polar gradients, animation timing functions, custom labels/tooltips. No external dependencies required.

### Examples:
| [Conical / Polar gradient](./examples/conical-gradient) | [Multiple gauges](./examples/multiple-gauge) | [Countdown circle](./examples/countdown-gauge) |
| ------------- | -------------| -------------|
| <img src="/assets/conical-polar.gif" width="249.2" height="256.2"> | <img src="/assets/multiple-gauges.gif" width="261" height="256.2"> | <img src="/assets/countdown-circle.gif" width="249.2" height="256.2"> |

### Installation
`npm install gauge-chart-js`

### Basic usage
```typescript
import { cubicBezier, Gauge } from 'gauge-chart-js';

const gauge = new Gauge({
container: document.querySelector('.root'),
value: 50,
color: '#0f0'
});

gauge.draw();

```

### Customise easing
```typescript
import { cubicBezier, Gauge } from 'gauge-chart-js';

const easeIn = cubicBezier(0, 0, 0.2, 1);
const gauge = new Gauge({
...
easing: easeIn
})
```

Easing functions cheat sheet: https://matthewlein.com/tools/ceaser

### Options
| Name | Description | Required | Default value | Type |
| --- | --- | --- | --- | --- |
| `value` | Gauge value | Yes | - | `number` |
| `container` | The HTML element that act as a container for the gauge | Yes | - | `HTMLElement` |
| `fromAngle` | Gauge start angle in degrees | No | 220 | `number` |
| `toAngle` | Gauge end angle in degrees | No | 500 | `number` |
| `animationDuration` | Animation duration in milliseconds | No | 600 | `number` |
| `animationDelay`| Animation delay in milliseconds. Pass 0 for no animation. | No | 0 | `number` |
| `lineWidth`| Thickness of the gauge | No | 3.5 | `number` |
| `easing`| The easing function that will be used when animating | No | linear | `(timeFraction: number) => number` |
| `gaugeRadius`| Gauge radius | No | 35 | `number` |
| `color`| Gauge color supported by SVG's [fill](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Fills_and_Strokes) attribute | No | - | `string` |
| `colors`| Gauge colors supported by SVG's [fill](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Fills_and_Strokes) attribute | No | - | `string[]` |

### How to integrate it with framework X?
The library is framework-agnostic and do not require any framework-specific integration. If you are using Angular make sure chart is rendered outside zone.js:
```typescript
class ExampleComponent implements OnInit {
constructor(private ngZone: NgZone) {}

ngOnInit() {
const gauge = new Gauge({ ... });
this.ngZone.runOutsideAngular(() => {
gauge.draw();
});
}
}
```
Binary file added assets/conical-polar.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/countdown-circle.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/multiple-gauges.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
### Examples
- `npm run example conical-gradient/conical-gradient.html`
- `npm run example countdown-gauge/countdown-gauge.html`
- `npm run example multiple-gauges/multiple-gauges.html`
17 changes: 17 additions & 0 deletions examples/conical-gradient/conical-gradient.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<html lang="en">
<head>
<title>Conical gradient</title>
<script src="conical-gradient.ts"></script>
<link rel="stylesheet" href="conical-gradient.scss" />
</head>
<body>
<div class="conical-gauge-wrapper">
<div class="conical-gauge"></div>
<span class="label"></span>
<div class="controls">
<button class="control decrease">Decrease</button>
<button class="control increase">Increase</button>
</div>
</div>
</body>
</html>
78 changes: 78 additions & 0 deletions examples/conical-gradient/conical-gradient.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
.conical-gauge-wrapper {
$chart-size: 400px;
$chart-padding: 100px;
$label-width: 160px;
$font-family: 'Open Sans', sans-serif;
$color-accent: #7199e3;
$color-white: #fff;
$color-text: #0f3e48;

background-color: $color-white;
width: $chart-size + $chart-padding;
height: $chart-size + $chart-padding;
font-family: $font-family;
position: relative;

.conical-gauge {
position: relative;
width: $chart-size;
height: $chart-size;
left: $chart-padding / 2;
top: $chart-padding / 2;
}

.label {
color: $color-text;
font-size: 66px;
letter-spacing: -1.5px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -60%);
}

.controls {
position: absolute;
display: flex;
left: 50%;
transform: translateX(-50%);
bottom: 65px;

.control {
font-size: 16px;
padding: 3px 20px;
text-decoration: none;
border: 1px solid $color-accent;
color: $color-accent;
font-family: $font-family;
text-align: center;
cursor: pointer;
background-color: $color-white;
transition: 0.2s all;

&:first-child {
border-radius: 7px 0 0 7px;
}

&:not(:first-child) {
margin-left: -2px;
}

&:last-child {
border-radius: 0 7px 7px 0;
}

&:focus {
box-shadow: none;
outline: none;
background-color: $color-accent;
border-color: $color-accent;
color: $color-white;
}

&:active {
background-color: darken($color-accent, 10%);
}
}
}
}
78 changes: 78 additions & 0 deletions examples/conical-gradient/conical-gradient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { cubicBezier, Gauge } from '../../src';
// @ts-ignore
const gradstop = require('gradstop');

function clamp(from: number, to: number, value: number) {
if (value < from) {
return from;
}
if (value > to) {
return to;
}
return value;
}

function updatePercentNode(value: number) {
const element = document.querySelector('.label') as HTMLElement;
element.innerHTML = parseInt(value.toString()) + '%';
}

function setControlDisabled(disabled: boolean) {
Array.from(document.querySelectorAll('.control')).forEach(node => {
if (disabled) {
node.setAttribute('disabled', '');
} else {
node.removeAttribute('disabled');
}
});
}

document.addEventListener('DOMContentLoaded', () => {
const step = 70;
const fromAngle = 220;
const toAngle = 500;
const maxValue = toAngle - fromAngle;
let value = maxValue * 0.2;
updatePercentNode((value / maxValue) * 100);
const container = document.querySelector('.conical-gauge') as HTMLElement;
const sharedConfig = {
lineWidth: 4,
container,
fromAngle,
toAngle,
easing: cubicBezier(0.165, 0.84, 0.44, 1)
};

const gaugeBackground = new Gauge({
...sharedConfig,
color: '#f5f5f5',
value: maxValue
});
gaugeBackground.draw();

const gaugeMain = new Gauge({
...sharedConfig,
colors: gradstop({
stops: maxValue,
colorArray: ['#D16BA5', '#86A8E7', '#5FFBF1']
}),
value
});
gaugeMain.draw();

const controls = document.querySelector('.controls') as HTMLElement;
controls.addEventListener('click', event => {
setControlDisabled(true);
const target = event.target as HTMLElement;
if (target.classList.contains('increase')) {
value = clamp(0, maxValue, value + step);
}
if (target.classList.contains('decrease')) {
value = clamp(0, maxValue, value - step);
}
gaugeMain.setValue(value).then(() => {
setControlDisabled(false);
});
updatePercentNode((value / maxValue) * 100);
});
});
14 changes: 14 additions & 0 deletions examples/countdown-gauge/countdown-gauge.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<html lang="en">
<head>
<title>Timeout gauge</title>
<script src="countdown-gauge.ts"></script>
<link rel="stylesheet" href="countdown-gauge.scss" />
</head>
<body>
<div class="countdown-gauge-background">
<div class="countdown-gauge">
<span class="timer"></span>
</div>
</div>
</body>
</html>
27 changes: 27 additions & 0 deletions examples/countdown-gauge/countdown-gauge.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.countdown-gauge-background {
$chart-size: 400px;
$chart-padding: 100px;
$label-width: 160px;

background-color: white;
width: $chart-size + $chart-padding;
height: $chart-size + $chart-padding;
font-family: 'Open Sans', sans-serif;

.timer {
position: absolute;
font-size: 6em;
top: 50%;
left: 50%;
transform: translate(-50%, -55%);
color: #fd9eaa;
}

.countdown-gauge {
position: relative;
width: $chart-size;
height: $chart-size;
left: $chart-padding / 2;
top: $chart-padding / 2;
}
}
66 changes: 66 additions & 0 deletions examples/countdown-gauge/countdown-gauge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { cubicBezier, Gauge } from '../../src';

const linear = cubicBezier(0, 0, 1, 1);
const easeIn = cubicBezier(0, 0, 0.2, 1);

function updateTimerNode(value: number) {
const timer = document.querySelector('.timer') as HTMLElement;
timer.innerHTML = value.toString();
}

document.addEventListener('DOMContentLoaded', () => {
let timer = 5;
updateTimerNode(timer);
const container = document.querySelector('.countdown-gauge') as HTMLElement;
const sharedConfig = {
container,
gaugeRadius: 45,
lineWidth: 1,
fromAngle: 0,
toAngle: 360,
animationDuration: 5000,
easing: linear
};
const maxValue = sharedConfig.toAngle - sharedConfig.fromAngle;
const gaugeBackground = new Gauge({
...sharedConfig,
value: maxValue,
color: '#ebebeb',
animationDuration: 0
});

gaugeBackground.draw();

const mainGauge = new Gauge({
...sharedConfig,
value: maxValue,
color: '#fd9eaa'
});

mainGauge.draw({ animationDuration: 0 }).then(() => {
setTimeout(() => {
const interval = setInterval(() => {
timer--;
updateTimerNode(timer);
}, 1000);
mainGauge
.setValue(0, { easing: linear, })
.then(() => {
clearInterval(interval);
timer = 0;
updateTimerNode(timer);
return mainGauge.setValue(maxValue, {
easing: easeIn,
animationDelay: 600,
animationDuration: 600
});
})
.then(() => {
setTimeout(() => {
timer = 5;
updateTimerNode(timer);
}, 500);
});
}, 2000);
});
});
Loading

0 comments on commit 90e502d

Please sign in to comment.