Alarm Zones

You can use the FlexChart's rendering and rendered events to add arbitrary elements behind or above the regular chart elements.

For example,the chart below has 'buy' and 'sell' zones created in the chart's rendering event handler:

import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; // import * as chart from '@grapecity/wijmo.chart'; import { getData } from './data'; // document.readyState === 'complete' ? init() : window.onload = init; // function init() { let linechart = new chart.FlexChart('#chart', { header: 'Device Temperature Monitor', legend: { position: chart.Position.None }, chartType: chart.ChartType.Line, bindingX: 'x', series: [{ binding: 'y', name: 'Temperature' }], axisY: { min: 0, max: 100, majorGrid: false, title: 'Temperature(°C)' }, rendering: function (s, e) { var xMin = s.axisX.actualMin.valueOf(), xMax = s.axisX.actualMax.valueOf(), yMin = s.axisY.actualMin, yMax = s.axisY.actualMax; if (isNaN(xMin) && isNaN(xMax)) { return; } drawAlarmZone(s, e.engine, xMin, 80, xMax, yMax, 'alarm-zone'); drawAlarmZone(s, e.engine, xMin, 50, xMax, 80, 'warning-zone'); drawAlarmZone(s, e.engine, xMin, yMin, xMax, 50, 'safe-zone'); } }); // setInterval(() => { let data = getData(); linechart.itemsSource = data; }, 1000); } // draw an alarm zone into the chart function drawAlarmZone(chart, engine, xMin, yMin, xMax, yMax, className) { var pt1 = chart.dataToPoint(xMin, yMin); var pt2 = chart.dataToPoint(xMax, yMax); engine.drawRect(Math.min(pt1.x, pt2.x), Math.min(pt1.y, pt2.y), Math.abs(pt2.x - pt1.x), Math.abs(pt2.y - pt1.y), className); } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo FlexChart Alarm Zones</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"> <div id="chart"></div> </div> </body> </html> // get temperature(random data) of device. let data = []; export function getData() { let date = new Date(); if (data.length === 0) { date.setSeconds(date.getSeconds() - 99); for (let i = 1; i < 100; i++) { data.push({ x: new Date(date.valueOf()), y: getRandomTemp() }); date.setSeconds(date.getSeconds() + 1); } } if (data.length === 100) { data.splice(0, 1); } data.push({ x: date, y: getRandomTemp() }); return data.slice(); } function getRandomTemp() { let seed = Math.random(); if (seed > 0.9) { return (Math.round(Math.random() * 800) / 10) + 20; } else if (seed > 0.6) { return (Math.round(Math.random() * 600) / 10) + 20; } else { return (Math.round(Math.random() * 300) / 10) + 20; } } body { margin-bottom: 24px; } label { margin-right: 3px; } .alarm-zone { fill: red; opacity: .15; stroke-width: 0; } .warning-zone { fill: orange; opacity: .15; stroke-width: 0; } .safe-zone { fill: green; opacity: .15; stroke-width: 0; } import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; // import { Component, Inject, enableProdMode, NgModule } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { BrowserModule } from '@angular/platform-browser'; import { WjChartModule } from '@grapecity/wijmo.angular2.chart'; import { DataService } from './app.data'; import * as wjChart from '@grapecity/wijmo.chart'; // @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { data: any[]; // constructor(@Inject(DataService) private dataService: DataService) { this.data = dataService.getData(); setInterval(()=>{ this.data = dataService.getData(); }, 1000); } chartRendering(s: wjChart.FlexChart, e: any) { // behind the regular chart elements var xMin = s.axisX.actualMin.valueOf(), xMax = s.axisX.actualMax.valueOf(), yMin = s.axisY.actualMin, yMax = s.axisY.actualMax; if(isNaN(xMin) && isNaN(xMax)) { return; } this.drawAlarmZone(s, e.engine, xMin, 80, xMax, yMax, 'alarm-zone'); this.drawAlarmZone(s, e.engine, xMin, 50, xMax, 80, 'warning-zone'); this.drawAlarmZone(s, e.engine, xMin, yMin, xMax, 50, 'safe-zone'); } // draw an alarm zone into the chart drawAlarmZone(chart: wjChart.FlexChart, engine: wjChart.IRenderEngine, xMin: number, yMin: number, xMax: number, yMax: number, className: string) { var pt1 = chart.dataToPoint(xMin, yMin); var pt2 = chart.dataToPoint(xMax, yMax); engine.drawRect( Math.min(pt1.x, pt2.x), Math.min(pt1.y, pt2.y), Math.abs(pt2.x - pt1.x), Math.abs(pt2.y - pt1.y), className); } } // @NgModule({ imports: [WjChartModule, BrowserModule], declarations: [AppComponent], providers: [DataService], 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>GrapeCity Wijmo FlexChart Alarm Zones</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"> <wj-flex-chart #theChart [itemsSource]="data" header="Device Temperature Monitor" chartType="Line" bindingX="x" (rendering)="chartRendering(theChart, $event)"> <wj-flex-chart-legend position="None"></wj-flex-chart-legend> <wj-flex-chart-series binding="y" name="Temperature"></wj-flex-chart-series> <wj-flex-chart-axis wjProperty="axisY" [min]="0" [max]="100" [majorGrid]="false" title="Temperature(°C)"></wj-flex-chart-axis> </wj-flex-chart> </div> import { Injectable } from '@angular/core'; //// get temperature(random data) of device. let data: any[] = []; @Injectable() export class DataService { getData() { let date = new Date(); if(data.length === 0) { date.setSeconds(date.getSeconds() - 99); for(let i = 1; i < 100; i++) { data.push({ x: new Date(date.valueOf()), y: this.getRandomTemp() }); date.setSeconds(date.getSeconds() + 1); } } if(data.length === 100) { data.splice(0, 1); } data.push({ x: date, y: this.getRandomTemp() }); return data.slice(); } // getRandomTemp() { let seed = Math.random(); if(seed > 0.9) { return (Math.round(Math.random() * 800) / 10) + 20 ; } else if (seed > 0.6) { return (Math.round(Math.random() * 600) / 10) + 20 ; } else { return (Math.round(Math.random() * 300) / 10) + 20 ; } } } body { margin-bottom: 24px; } label { margin-right: 3px; } .alarm-zone { fill: red; opacity: .15; stroke-width: 0; } .warning-zone { fill: orange; opacity: .15; stroke-width: 0; } .safe-zone { fill: green; opacity: .15; stroke-width: 0; } <template> <div class="container-fluid"> <wj-flex-chart :itemsSource="data" header="Device Temperature Monitor" chartType="Line" bindingX="x" :rendering="chartRendering"> <wj-flex-chart-legend position="None"></wj-flex-chart-legend> <wj-flex-chart-series binding="y" name="Temperature"></wj-flex-chart-series> <wj-flex-chart-axis wjProperty="axisY" :min="0" :max="100" :majorGrid="false" title="Temperature(°C)"></wj-flex-chart-axis> </wj-flex-chart> </div> </template> <script> import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import Vue from 'vue'; import '@grapecity/wijmo.vue2.core'; import '@grapecity/wijmo.vue2.chart'; import { getData } from './data'; let App = Vue.extend({ name: 'app', data: function () { return { data: getData() } }, mounted: function () { setInterval(()=>{ this.data = getData(); }, 1000); }, methods: { chartRendering: function(s, e) { var xMin = s.axisX.actualMin.valueOf(), xMax = s.axisX.actualMax.valueOf(), yMin = s.axisY.actualMin, yMax = s.axisY.actualMax; if(isNaN(xMin) && isNaN(xMax)) { return; } this.drawAlarmZone(s, e.engine, xMin, 80, xMax, yMax, 'alarm-zone'); this.drawAlarmZone(s, e.engine, xMin, 50, xMax, 80, 'warning-zone'); this.drawAlarmZone(s, e.engine, xMin, yMin, xMax, 50, 'safe-zone'); }, drawAlarmZone: function(chart, engine, xMin, yMin, xMax, yMax, className) { var pt1 = chart.dataToPoint(xMin, yMin); var pt2 = chart.dataToPoint(xMax, yMax); engine.drawRect( Math.min(pt1.x, pt2.x), Math.min(pt1.y, pt2.y), Math.abs(pt2.x - pt1.x), Math.abs(pt2.y - pt1.y), className); } } }) new Vue({ render: h => h(App) }).$mount('#app'); </script> <style> body { margin-bottom: 24px; } label { margin-right: 3px; } .alarm-zone { fill: red; opacity: .15; stroke-width: 0; } .warning-zone { fill: orange; opacity: .15; stroke-width: 0; } .safe-zone { fill: green; opacity: .15; stroke-width: 0; } </style> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo FlexChart Alarm Zones</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> // get temperature(random data) of device. let data = []; export function getData() { let date = new Date(); if(data.length === 0) { date.setSeconds(date.getSeconds() - 99); for(let i = 1; i < 100; i++) { data.push({ x: new Date(date.valueOf()), y: getRandomTemp() }); date.setSeconds(date.getSeconds() + 1); } } if(data.length === 100) { data.splice(0, 1); } data.push({ x: date, y: getRandomTemp() }); return data.slice(); } function getRandomTemp() { let seed = Math.random(); if(seed > 0.9) { return (Math.round(Math.random() * 800) / 10) + 20 ; } else if (seed > 0.6) { return (Math.round(Math.random() * 600) / 10) + 20 ; } else { return (Math.round(Math.random() * 300) / 10) + 20 ; } } import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './app.css'; // import * as React from 'react'; import * as ReactDOM from 'react-dom'; // import * as wjChart from '@grapecity/wijmo.react.chart'; import { getData } from './data'; class App extends React.Component { constructor(props) { super(props); this.state = { data: getData() }; } componentDidMount() { setInterval(() => { this.setState({ data: getData() }); }, 1000); } chartRendering(s, e) { var xMin = s.axisX.actualMin.valueOf(), xMax = s.axisX.actualMax.valueOf(), yMin = s.axisY.actualMin, yMax = s.axisY.actualMax; if (isNaN(xMin) && isNaN(xMax)) { return; } this.drawAlarmZone(s, e.engine, xMin, 80, xMax, yMax, 'alarm-zone'); this.drawAlarmZone(s, e.engine, xMin, 50, xMax, 80, 'warning-zone'); this.drawAlarmZone(s, e.engine, xMin, yMin, xMax, 50, 'safe-zone'); } drawAlarmZone(chart, engine, xMin, yMin, xMax, yMax, className) { var pt1 = chart.dataToPoint(xMin, yMin); var pt2 = chart.dataToPoint(xMax, yMax); engine.drawRect(Math.min(pt1.x, pt2.x), Math.min(pt1.y, pt2.y), Math.abs(pt2.x - pt1.x), Math.abs(pt2.y - pt1.y), className); } render() { return <div className='container-fluid'> <wjChart.FlexChart itemsSource={this.state.data} header='Device Temperature Monitor' chartType='Line' bindingX='x' rendering={this.chartRendering.bind(this)}> <wjChart.FlexChartLegend position='None'/> <wjChart.FlexChartSeries binding='y' name='Temperature'/> <wjChart.FlexChartAxis wjProperty='axisY' min={0} max={100} majorGrid={false} title='Temperature(°C)'/> </wjChart.FlexChart> </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>Grapecity Wijmo OLAP Pivot Chart Overview</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> body { margin-bottom: 24px; } label { margin-right: 3px; } .alarm-zone { fill: red; opacity: .15; stroke-width: 0; } .warning-zone { fill: orange; opacity: .15; stroke-width: 0; } .safe-zone { fill: green; opacity: .15; stroke-width: 0; } // get temperature(random data) of device. let data = []; export function getData() { let date = new Date(); if (data.length === 0) { date.setSeconds(date.getSeconds() - 99); for (let i = 1; i < 100; i++) { data.push({ x: new Date(date.valueOf()), y: getRandomTemp() }); date.setSeconds(date.getSeconds() + 1); } } if (data.length === 100) { data.splice(0, 1); } data.push({ x: date, y: getRandomTemp() }); return data.slice(); } function getRandomTemp() { let seed = Math.random(); if (seed > 0.9) { return (Math.round(Math.random() * 800) / 10) + 20; } else if (seed > 0.6) { return (Math.round(Math.random() * 600) / 10) + 20; } else { return (Math.round(Math.random() * 300) / 10) + 20; } }