Radial Gauges with Needle Pointers

By default, Wijmo's radial gauges use a colored sector and a text element to indicate the gauge's current value. This results in a clean and easy-to read look.

If you prefer a more traditional needle-style pointer, use the needleShape and needleLength properties to select a needle pointer which can be styled with CSS.

You can also use the needleElement property to use custom SVG elements as needles, and createNeedleElement method to create custom needle shapes.

import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; import { ComboBox } from '@grapecity/wijmo.input'; import { RadialGauge, ShowText, NeedleShape, NeedleLength } from '@grapecity/wijmo.gauge'; document.readyState === 'complete' ? init() : window.onload = init; function init() { // create the gauge let theRadialGauge = new RadialGauge('#theRadialGauge', { showText: ShowText.None, min: 0, max: 500, value: 100, startAngle: -45, sweepAngle: 270, showTicks: true, showTickText: true, tickSpacing: 50, thickness: 0.2, needleShape: NeedleShape.Pointer, isReadOnly: false }); // configure the gauge new ComboBox('#start', { itemsSource: [-90, -45, 0, 45, 90], selectedItem: theRadialGauge.startAngle, selectedIndexChanged: (s) => { theRadialGauge.startAngle = s.selectedItem; } }); new ComboBox('#sweep', { itemsSource: [-360, -270, -180, -90, 90, 180, 270, 360], selectedItem: theRadialGauge.sweepAngle, selectedIndexChanged: (s) => { theRadialGauge.sweepAngle = s.selectedItem; } }); new ComboBox('#spacing', { itemsSource: [20, 50, 100, 200, 250], selectedItem: 100, selectedIndexChanged: (s) => { theRadialGauge.tickSpacing = s.selectedItem; } }); new ComboBox('#needle-shape', { itemsSource: 'None,Triangle,Diamond,Hexagon,Rectangle,Arrow,WideArrow,Pointer,WidePointer,Outer'.split(','), text: NeedleShape[theRadialGauge.needleShape], textChanged: (s) => { theRadialGauge.needleShape = s.text; theRadialGauge.showText = s.text.match(/Outer|None/) ? ShowText.Value : ShowText.None; } }); new ComboBox('#needle-length', { itemsSource: 'Outer,Middle,Inner'.split(','), text: 'Middle', textChanged: (s) => { theRadialGauge.needleLength = s.text; } }); // gauges with custom needles new RadialGauge('#customGauge1', { thickness: .2, showText: ShowText.None, min: 0, max: 500, value: 100, startAngle: -45, sweepAngle: 270, showTicks: true, showTickText: true, tickSpacing: 50, isReadOnly: false, needleLength: NeedleLength.Inner, needleElement: RadialGauge.createNeedleElement([ { x: -35, y: 0 }, { x: -35, y: 35 }, { x: -30, y: 35 }, { x: -20, y: 5 }, { x: 60, y: 5 }, { x: 100, y: 0 } ], 15) }); new RadialGauge('#customGauge2', { thickness: .2, showText: ShowText.None, min: 0, max: 500, value: 100, startAngle: -45, sweepAngle: 270, showTicks: true, showTickText: true, tickSpacing: 50, isReadOnly: false, needleLength: NeedleLength.Inner, needleElement: RadialGauge.createNeedleElement([ { x: -10, y: 0 }, { x: -10, y: 12 }, { x: 0, y: 20 }, { x: 35, y: 20 }, { x: 50, y: 12 }, { x: 10, y: 12 }, { x: 10, y: 5 }, { x: 80, y: 5 }, { x: 100, y: 0 } ]) }); new RadialGauge('#customGauge3', { thickness: .2, showText: ShowText.Value, min: 0, max: 500, value: 100, startAngle: -45, sweepAngle: 270, showTicks: true, showTickText: true, tickSpacing: 50, isReadOnly: false, needleLength: NeedleLength.Inner, needleElement: RadialGauge.createNeedleElement([ { x: 40, y: 15 }, { x: 90, y: 0 } ]) }); } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Radial Gauges with Needle Pointers</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <div class="container-fluid"> <p> Select one of the built-in needle shapes using the <b>needleShape</b> property: </p> <div class="row"> <div class="col-xs-4"> <label for="needle-shape"> needleShape </label> <input id="needle-shape" /><br /> <label for="needle-length"> needleLength </label> <input id="needle-length" /><br /> <br /> <label for="start"> startAngle </label> <input id="start" /><br /> <label for="sweep"> sweepAngle </label> <input id="sweep" /><br /> <label for="spacing"> tickSpacing </label> <input id="spacing" /><br /> </div> <div class="col-xs-4"> <div id="theRadialGauge"></div> </div> </div> <p> Or create custom needle shapes with the <b>createNeedleElement</b> method: </p> <div class="row"> <div class="col-xs-4"> <div id="customGauge1"></div> </div> <div class="col-xs-4"> <div id="customGauge2"></div> </div> <div class="col-xs-4"> <div id="customGauge3"></div> </div> </div> </div> </body> </html> .wj-gauge { margin: 2em auto; width: 200px; height: 200px; } .wj-gauge .wj-needle { fill: orangered; stroke: orangered; } .wj-gauge .wj-needle .wj-inner-needle-cap { fill: white; } label { min-width: 100px; text-align: right; margin-right: 12px; } .wj-combobox { width: 150px; } import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; import { RadialGauge } from '@grapecity/wijmo.gauge'; import { Component, enableProdMode, NgModule } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { BrowserModule } from '@angular/platform-browser'; import { WjInputModule } from '@grapecity/wijmo.angular2.input'; import { WjGaugeModule } from '@grapecity/wijmo.angular2.gauge'; @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { // state showText = 'None'; startAngles = [-90, -45, 0, 45, 90]; startAngle = -45; sweepAngles = [-360, -270, -180, -90, 90, 180, 270, 360]; sweepAngle = 270; tickSpacings = [20, 50, 100, 200, 250]; tickSpacing = 50; needleShapes = 'None,Triangle,Diamond,Hexagon,Rectangle,Arrow,WideArrow,Pointer,WidePointer,Outer'.split(','); needleShape = 'Pointer'; needleLengths = 'Outer,Middle,Inner'.split(','); needleLength = 'Middle'; // create custom needles with the createNeedleElement utility _customNeedles = new Map(); createNeedleElement(points: any[], innerRadius?: number, outerRadius?: number): Element { let needle = this._customNeedles.get(points); if (!needle) { needle = RadialGauge.createNeedleElement(points, innerRadius, outerRadius); this._customNeedles.set(points, needle); } return needle; } } @NgModule({ imports: [WjGaugeModule, WjInputModule, BrowserModule], declarations: [AppComponent], bootstrap: [AppComponent] }) export class AppModule { } enableProdMode(); // Bootstrap application with hash style navigation and global services. platformBrowserDynamic().bootstrapModule(AppModule); <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Radial Gauges with Needle Pointers</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Polyfills --> <script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/zone.js/dist/zone.min.js"></script> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.js"></script> <script src="systemjs.config.js"></script> <script> // workaround to load 'rxjs/operators' from the rxjs bundle System.import('rxjs').then(function (m) { System.set(SystemJS.resolveSync('rxjs/operators'), System.newModule(m.operators)); System.import('./src/app.component'); }); </script> </head> <body> <app-component></app-component> </body> </html> <div class="container-fluid"> <p> Select one of the built-in needle shapes using the <b>needleShape</b> property: </p> <div class="row"> <div class="col-xs-4"> <label for="needle-shape">needleShape</label> <wj-combo-box #cmbNeedleShape id="needle-shape" [itemsSource]="needleShapes" [text]="needleShape" (textChanged)="needleShape = cmbNeedleShape.selectedValue"> </wj-combo-box> <br/> <label for="needle-length">needleLength</label> <wj-combo-box #cmbNeedleLength id="needle-length" [itemsSource]="needleLengths" [text]="needleLength" (textChanged)="needleLength = cmbNeedleLength.selectedValue"> </wj-combo-box> <br/> <label for="start-angle">startAngle</label> <wj-combo-box #cmbStartAngle id="start-angle" [itemsSource]="startAngles" [selectedItem]="startAngle" (textChanged)="startAngle = cmbStartAngle.selectedValue"> </wj-combo-box> <br/> <label for="sweep-angle">sweepAngle</label> <wj-combo-box #cmbSweepAngle id="sweep-angle" [itemsSource]="sweepAngles" [selectedItem]="sweepAngle" (textChanged)="sweepAngle = cmbSweepAngle.selectedValue"> </wj-combo-box> <br/> <label for="tick-spacing">tickSpacing</label> <wj-combo-box #cmbTickSpacing id="tick-spacing" [itemsSource]="tickSpacings" [selectedItem]="tickSpacing" (textChanged)="tickSpacing = cmbTickSpacing.selectedValue"> </wj-combo-box> </div> <div class="col-xs-4"> <wj-radial-gauge [min]="0" [max]="500" [value]="100" [showText]="showText" [startAngle]="startAngle" [sweepAngle]="sweepAngle" [tickSpacing]="tickSpacing" [needleShape]="needleShape" [needleLength]="needleLength" [thickness]=".2" [showTicks]="true" [showTickText]="true" [isReadOnly]="false"> </wj-radial-gauge> </div> </div> <p> Or create custom needle shapes with the <b>createNeedleElement</b> method: </p> <div class="row"> <div class="col-xs-4"> <wj-radial-gauge [thickness]=".2" [showText]="'None'" [min]="0" [max]="500" [value]="100" [startAngle]="-45" [sweepAngle]="270" [showTicks]="true" [showTickText]="true" [tickSpacing]="50" [isReadOnly]="false" [needleLength]="'Inner'" [needleElement]="createNeedleElement([{ x: -35, y: 0 }, { x: -35, y: 35 }, { x: -30, y: 35 }, { x: -20, y: 5 }, { x: 60, y: 5 }, { x: 100, y: 0 } ], 15)"> </wj-radial-gauge> </div> <div class="col-xs-4"> <wj-radial-gauge [thickness]=".2" [showText]="'None'" [min]="0" [max]="500" [value]="100" [startAngle]="-45" [sweepAngle]="270" [showTicks]="true" [showTickText]="true" [tickSpacing]="50" [isReadOnly]="false" [needleLength]="'Inner'" [needleElement]="createNeedleElement([ { x: -10, y: 0 }, { x: -10, y: 12 }, { x: 0, y: 20 }, { x: 35, y: 20 }, { x: 50, y: 12 }, { x: 10, y: 12 }, { x: 10, y: 5 }, { x: 80, y: 5 }, { x: 100, y: 0 } ])"> </wj-radial-gauge> </div> <div class="col-xs-4"> <wj-radial-gauge [thickness]=".2" [showText]="'Value'" [min]="0" [max]="500" [value]="100" [startAngle]="-45" [sweepAngle]="270" [showTicks]="true" [showTickText]="true" [tickSpacing]="50" [isReadOnly]="false" [needleLength]="'Inner'" [needleElement]="createNeedleElement([ { x: 40, y: 15 }, { x: 90, y: 0 } ])"> </wj-radial-gauge> </div> </div> </div> .wj-gauge { margin: 2em auto; width: 200px; height: 200px; } .wj-gauge .wj-needle { fill: orangered; stroke: orangered; } .wj-gauge .wj-needle .wj-inner-needle-cap { fill: white; } label { min-width: 100px; text-align: right; margin-right: 12px; } .wj-combobox { width: 150px; } <template> <div class="container-fluid app"> <p> Select one of the built-in needle shapes using the <b>needleShape</b> property: </p> <div class="row"> <div class="col-xs-4"> <label for="needle-shape">needleShape</label> <wj-combo-box :itemsSource=this.needleShapes :text=this.needleShape :textChanged="optionChanged.bind(this, 'needleShape', 'text')" /> <br/> <label for="needle-length">needleLength</label> <wj-combo-box :itemsSource=this.needleLengths :text=this.needleLength :textChanged="optionChanged.bind(this, 'needleLength', 'text')" /> <br/> <label for="start">startAngle</label> <wj-combo-box :itemsSource=this.startAngles :selectedItem=this.startAngle :textChanged="optionChanged.bind(this, 'startAngle', 'selectedValue')" /> <br/> <label for="sweep">sweepAngle</label> <wj-combo-box :itemsSource=this.sweepAngles :selectedItem=this.sweepAngle :textChanged="optionChanged.bind(this, 'sweepAngle', 'selectedValue')" /> <br/> <label for="spacing">tickSpacing</label> <wj-combo-box :itemsSource=this.tickSpacings :selectedItem=this.tickSpacing :textChanged="optionChanged.bind(this, 'tickSpacing', 'selectedValue')" /> </div> <div class="col-xs-4"> <wj-radial-gauge :min=0 :max=500 :value=100 :showText=this.showText :startAngle=this.startAngle :sweepAngle=this.sweepAngle :tickSpacing=this.tickSpacing :needleShape=this.needleShape :needleLength=this.needleLength :showTicks=true :showTickText=true :thickness=.2 :isReadOnly=false /> </div> </div> <p> Or create custom needle shapes with the <b>createNeedleElement</b> method: </p> <div class="row"> <div class="col-xs-4"> <wj-radial-gauge :thickness=.2 showText="None" :min=0 :max=500 :value=100 :startAngle=-45 :sweepAngle=270 :showTicks=true :showTickText=true :tickSpacing=50 :isReadOnly=false needleLength="Inner" :needleElement="createNeedleElement([{ x: -35, y: 0 }, { x: -35, y: 35 }, { x: -30, y: 35 }, { x: -20, y: 5 }, { x: 60, y: 5 }, { x: 100, y: 0 } ], 15)" /> </div> <div class="col-xs-4"> <wj-radial-gauge :thickness=.2 showText="None" :min=0 :max=500 :value=100 :startAngle=-45 :sweepAngle=270 :showTicks=true :showTickText=true :tickSpacing=50 :isReadOnly=false needleLength="Inner" :needleElement="createNeedleElement([ { x: -10, y: 0 }, { x: -10, y: 12 }, { x: 0, y: 20 }, { x: 35, y: 20 }, { x: 50, y: 12 }, { x: 10, y: 12 }, { x: 10, y: 5 }, { x: 80, y: 5 }, { x: 100, y: 0 } ])" /> </div> <div class="col-xs-4"> <wj-radial-gauge :thickness=.2 showText="Value" :min=0 :max=500 :value=100 :startAngle=-45 :sweepAngle=270 :showTicks=true :showTickText=true :tickSpacing=50 :isReadOnly=false needleLength="Inner" :needleElement="createNeedleElement([ { x: 40, y: 15 }, { x: 90, y: 0 } ])" /> </div> </div> </div> </template> <script> import "bootstrap.css"; import "@grapecity/wijmo.styles/wijmo.css"; import 'src/app.css'; import Vue from "vue"; import "@grapecity/wijmo.vue2.input"; import "@grapecity/wijmo.vue2.gauge"; import { RadialGauge } from "@grapecity/wijmo.gauge"; let App = Vue.extend({ name: "app", data: function() { return { showText: 'None', startAngles: [-90, -45, 0, 45, 90], startAngle: -45, sweepAngles: [-360, -270, -180, -90, 90, 180, 270, 360], sweepAngle: 270, tickSpacings: [20, 50, 100, 200, 250], tickSpacing: 50, needleShapes: 'None,Triangle,Diamond,Hexagon,Rectangle,Arrow,WideArrow,Pointer,WidePointer,Outer'.split(','), needleShape: 'Pointer', needleLengths: 'Outer,Middle,Inner'.split(','), needleLength: 'Middle' }; }, methods: { optionChanged: function(option, comboProp, s) { this[option] = s[comboProp]; }, createNeedleElement: function(arr, innerRadius, outerRadius) { return RadialGauge.createNeedleElement(arr, innerRadius, outerRadius); } } }); new Vue({ render: h => h(App) }).$mount("#app"); </script> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Radial Gauges with Needle Pointers</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app.vue'); </script> </head> <body> <div id="app"> </div> </body> </html> import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './app.css'; import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { ComboBox } from '@grapecity/wijmo.react.input'; import { RadialGauge } from '@grapecity/wijmo.react.gauge'; import { ShowText, NeedleLength, RadialGauge as rg } from '@grapecity/wijmo.gauge'; class App extends React.Component { constructor(props) { super(props); this.state = { showText: 'None', startAngles: [-90, -45, 0, 45, 90], startAngle: -45, sweepAngles: [-360, -270, -180, -90, 90, 180, 270, 360], sweepAngle: 270, tickSpacings: [20, 50, 100, 200, 250], tickSpacing: 50, needleShapes: 'None,Triangle,Diamond,Hexagon,Rectangle,Arrow,WideArrow,Pointer,WidePointer,Outer'.split(','), needleShape: 'Pointer', needleLengths: 'Outer,Middle,Inner'.split(','), needleLength: 'Middle' }; } render() { return (<div className="container-fluid"> <p> Select one of the built-in needle shapes using the <b>needleShape</b> property: </p> <div className="row"> <div className="col-xs-4"> <label htmlFor="needle-shape"> needleShape </label> <ComboBox itemsSource={this.state.needleShapes} text={this.state.needleShape} textChanged={s => this.setState({ needleShape: s.text, showText: s.text.match(/Outer|None/) ? ShowText.Value : ShowText.None })}/> <br /> <label htmlFor="needle-length"> needleLength </label> <ComboBox itemsSource={this.state.needleLengths} text={this.state.needleLength} textChanged={s => this.setState({ needleLength: s.text })}/> <br /> <label htmlFor="start"> startAngle </label> <ComboBox itemsSource={this.state.startAngles} selectedItem={this.state.startAngle} selectedIndexChanged={s => this.setState({ startAngle: s.selectedItem })}/> <br /> <label htmlFor="sweep"> sweepAngle </label> <ComboBox itemsSource={this.state.sweepAngles} selectedItem={this.state.sweepAngle} selectedIndexChanged={s => this.setState({ sweepAngle: s.selectedItem })}/> <br /> <label htmlFor="spacing"> tickSpacing </label> <ComboBox itemsSource={this.state.tickSpacings} selectedItem={this.state.tickSpacing} selectedIndexChanged={s => this.setState({ tickSpacing: s.selectedItem })}/> </div> <div className="col-xs-4"> <RadialGauge min={0} max={500} value={100} showText={this.state.showText} startAngle={this.state.startAngle} sweepAngle={this.state.sweepAngle} tickSpacing={this.state.tickSpacing} needleShape={this.state.needleShape} needleLength={this.state.needleLength} thickness={.2} showTicks={true} showTickText={true} isReadOnly={false}/> </div> </div> <p> Or create custom needle shapes with the <b>createNeedleElement</b> method: </p> <div className="row"> <div className="col-xs-4"> <RadialGauge thickness={.2} showText={ShowText.None} min={0} max={500} value={100} startAngle={-45} sweepAngle={270} showTicks={true} showTickText={true} tickSpacing={50} isReadOnly={false} needleLength={NeedleLength.Inner} needleElement={rg.createNeedleElement([ { x: -35, y: 0 }, { x: -35, y: 35 }, { x: -30, y: 35 }, { x: -20, y: 5 }, { x: 60, y: 5 }, { x: 100, y: 0 } ], 15)}/> </div> <div className="col-xs-4"> <RadialGauge thickness={.2} showText={ShowText.None} min={0} max={500} value={100} startAngle={-45} sweepAngle={270} showTicks={true} showTickText={true} tickSpacing={50} isReadOnly={false} needleLength={NeedleLength.Inner} needleElement={rg.createNeedleElement([ { x: -10, y: 0 }, { x: -10, y: 12 }, { x: 0, y: 20 }, { x: 35, y: 20 }, { x: 50, y: 12 }, { x: 10, y: 12 }, { x: 10, y: 5 }, { x: 80, y: 5 }, { x: 100, y: 0 } ])}/> </div> <div className="col-xs-4"> <RadialGauge thickness={.2} showText={ShowText.Value} min={0} max={500} value={100} startAngle={-45} sweepAngle={270} showTicks={true} showTickText={true} tickSpacing={50} isReadOnly={false} needleLength={NeedleLength.Inner} needleElement={rg.createNeedleElement([ { x: 40, y: 15 }, { x: 90, y: 0 } ])}/> </div> </div> </div>); } } ReactDOM.render(<App />, document.getElementById('app')); <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Radial Gauges with Needle Pointers</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <div id="app"></div> </body> </html> .wj-gauge { margin: 2em auto; width: 200px; height: 200px; } .wj-gauge .wj-needle { fill: orangered; stroke: orangered; } .wj-gauge .wj-needle .wj-inner-needle-cap { fill: white; } label { min-width: 100px; text-align: right; margin-right: 12px; } .wj-combobox { width: 150px; }