Moving Average

The MovingAverage class extends the regular Series class to provide a series of averages of different subsets of the full data set.

To add moving averages to a chart, follow these steps:

  1. Create one or more MovingAverage series,
  2. Configure the MovingAverage series as you would regular series, setting their binding, chartType, and style properties for example, and
  3. Set the MovingAverage's type and period properties to determine the type of moving average you want to create.
import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; import * as wjChart from '@grapecity/wijmo.chart'; import * as wjChartAnalytics from '@grapecity/wijmo.chart.analytics'; import * as wjInput from '@grapecity/wijmo.input'; import { getData } from './data'; // document.readyState === 'complete' ? init() : window.onload = init; // function init() { // create the chart let theChart = new wjChart.FlexChart('#theChart', { itemsSource: getData(), bindingX: 'date', chartType: 'Line', axisY: { min: 0 }, series: [ { name: 'Sales', binding: 'sales' } ] }); // // create a MovingAverage and add it to the Chart series collection let movingAvg = new wjChartAnalytics.MovingAverage(); movingAvg.name = 'Moving Average'; movingAvg.itemsSource = theChart.itemsSource; movingAvg.binding = 'sales'; movingAvg.period = 6; movingAvg.style = { stroke: 'darkred', strokeWidth: 3 }; theChart.series.push(movingAvg); // // select moving average period let period = new wjInput.InputNumber('#period', { value: movingAvg.period, step: 1, min: 2, max: 20, valueChanged: (s) => { if (s.value >= s.min && s.value <= s.max) { movingAvg.period = s.value; } } }); // // select moving average type let type = new wjInput.ComboBox('#type', { itemsSource: 'Simple,Weighted,Exponential,Triangular'.split(','), textChanged: (s) => movingAvg.type = s.text }); } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo FlexChart Moving Average</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"> <label for="type">MovingAverage Type: </label> <div id="type"></div> <label for="period">Period: </label> <div id="period"></div> <div id="theChart"></div> </div> </body> </html> import * as wjCore from '@grapecity/wijmo'; // // generate some random data export function getData() { let arr = [], today = new Date(), sales = 1000; // for (let i = 100; i >= 0; i--) { arr.push({ date: wjCore.DateTime.addDays(today, -i), sales: sales }); // sales += Math.round(Math.random() * 300 - 130); } // return arr; } .wj-flexchart { height: 250px; margin: 10px 0; } .wj-combobox, .wj-inputnumber { width: 120px; margin-right: 12px; } body { margin-bottom: 24pt; } 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 { WjInputModule } from '@grapecity/wijmo.angular2.input'; import { WjChartModule } from '@grapecity/wijmo.angular2.chart'; import { WjChartAnalyticsModule } from '@grapecity/wijmo.angular2.chart.analytics'; import { DataService } from './app.data'; // @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { data: any[]; typeData: any[]; type: string; period: number; // constructor(@Inject(DataService) private dataService: DataService) { this.data = dataService.getData(); this.typeData = dataService.getTypeData(); this.type = 'Simple'; this.period = 6; } } // @NgModule({ imports: [WjInputModule, WjChartModule, WjChartAnalyticsModule, 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 Moving Average</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"> <div class="form-group"> <label>MovingAverage Type: </label> <wj-combo-box [(text)]="type" [itemsSource]="typeData"></wj-combo-box> <label>Period: </label> <wj-input-number [(value)]="period" [step]="1" [min]="2" [max]="20"></wj-input-number> <wj-flex-chart [itemsSource]="data" bindingX="date" chartType="Line"> <wj-flex-chart-axis wjProperty="axisY" [min]="0"></wj-flex-chart-axis> <wj-flex-chart-series name="Sales" binding="sales"></wj-flex-chart-series> <wj-flex-chart-moving-average name="Moving Average" [itemsSource]="data" binding="sales" [period]="period" [style]="{stroke:'darkred', strokeWidth: 3}" [type]="type"></wj-flex-chart-moving-average> </wj-flex-chart> </div> </div> import { Injectable } from '@angular/core'; import * as wjCore from '@grapecity/wijmo'; // @Injectable() export class DataService { getData() { let arr = [], today = new Date(), sales = 1000; // for (let i = 100; i >= 0; i--) { arr.push({ date: wjCore.DateTime.addDays(today, -i), sales: sales }); // sales += Math.round(Math.random() * 300 - 130); } // return arr; } // getTypeData() { return 'Simple,Weighted,Exponential,Triangular'.split(','); } } .wj-flexchart { height: 250px; margin: 10px 0; } .wj-combobox, .wj-inputnumber { width: 120px; margin-right: 12px; } body { margin-bottom: 24pt; } <template> <div class="container-fluid"> <div class="form-group"> <label>MovingAverage Type: </label> <wj-combo-box :text="type" :itemsSource="typeData" :textChanged="typeChanged"></wj-combo-box> <label>Period: </label> <wj-input-number :value="period" :step="1" :min="2" :max="20" :valueChanged="periodChanged"></wj-input-number> <wj-flex-chart :itemsSource="data" bindingX="date" chartType="Line"> <wj-flex-chart-axis wjProperty="axisY" :min="0"></wj-flex-chart-axis> <wj-flex-chart-series name="Sales" binding="sales"></wj-flex-chart-series> <wj-flex-chart-moving-average name="Moving Average" :itemsSource="data" binding="sales" :period="period" :style="{stroke:'darkred', strokeWidth: 3}" :type="type"></wj-flex-chart-moving-average> </wj-flex-chart> </div> </div> </template> <script> import "@grapecity/wijmo.styles/wijmo.css"; import 'bootstrap.css'; import Vue from 'vue'; import '@grapecity/wijmo.vue2.core'; import '@grapecity/wijmo.vue2.input'; import '@grapecity/wijmo.vue2.chart'; import '@grapecity/wijmo.vue2.chart.analytics'; import { getData } from './data'; let App = Vue.extend({ name: 'app', data: function () { return { data: getData(), typeData: 'Simple,Weighted,Exponential,Triangular'.split(','), type: 'Simple', period: 6 } }, methods: { typeChanged: function(combo) { this.type = combo.text }, periodChanged: function(input) { if(input.value < input.min || input.value > input.max) { return; } this.period = input.value; } } }) new Vue({ render: h => h(App) }).$mount('#app'); </script> <style> body { margin-bottom: 24px; } label { margin-right: 3px; } </style> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo FlexChart Moving Average</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> export function getData() { let arr = [], today = new Date(), sales = 1000; // for (let i = 100; i >= 0; i--) { arr.push({ date: wijmo.DateTime.addDays(today, -i), sales: sales }); // sales += Math.round(Math.random() * 300 - 130); } // return arr; } import "@grapecity/wijmo.styles/wijmo.css"; import "bootstrap.css"; import "./app.css"; // import * as React from 'react'; import * as ReactDOM from 'react-dom'; // import * as wjChart from "@grapecity/wijmo.react.chart"; import * as wjChartAnalysis from "@grapecity/wijmo.react.chart.analytics"; import * as wjInput from "@grapecity/wijmo.react.input"; import { getData } from "./data"; class App extends React.Component { constructor(props) { super(props); this.state = { data: getData(), typeData: 'Simple,Weighted,Exponential,Triangular'.split(','), type: 'Simple', period: 6 }; } render() { return <div className="container-fluid"> <div className="form-group"> <label>MovingAverage Type: </label> <wjInput.ComboBox text={this.state.type} itemsSource={this.state.typeData} textChanged={this.typeChanged.bind(this)}></wjInput.ComboBox> <label>Period: </label> <wjInput.InputNumber value={this.state.period} step={1} min={2} max={20} valueChanged={this.periodChanged.bind(this)}></wjInput.InputNumber> <wjChart.FlexChart itemsSource={this.state.data} bindingX="date" chartType="Line"> <wjChart.FlexChartAxis wjProperty="axisY" min={0}></wjChart.FlexChartAxis> <wjChart.FlexChartSeries name="Sales" binding="sales"></wjChart.FlexChartSeries> <wjChartAnalysis.FlexChartMovingAverage name="Moving Average" itemsSource={this.state.data} binding="sales" period={this.state.period} style={{ stroke: 'darkred', strokeWidth: 3 }} type={this.state.type}></wjChartAnalysis.FlexChartMovingAverage> </wjChart.FlexChart> </div> </div>; } typeChanged(combo) { this.setState({ type: combo.text }); } periodChanged(input) { if (input.value < input.min || input.value > input.max) { return; } this.setState({ period: input.value }); } } 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; } import * as wjCore from "@grapecity/wijmo"; export function getData() { let arr = [], today = new Date(), sales = 1000; // for (let i = 100; i >= 0; i--) { arr.push({ date: wjCore.DateTime.addDays(today, -i), sales: sales }); // sales += Math.round(Math.random() * 300 - 130); } // return arr; }