趋势线

TrendLine类扩展常规Series类,以根据您选择的数据和参数提供计算的系列。

要将趋势线添加到图表,请按照下列步骤操作:

  1. 创建一个或多个TrendLine对象,
  2. 像常规系列一样配置TrendLine对象,设置 绑定chartTypestyle 属性,例如,
  3. 设置TrendLine的 fitTypeorder 属性,以确定要创建的趋势线的类型。
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(), chartType: 'Scatter', axisY: { axisLine: true }, bindingX: 'x', series: [ { name: 'Raw Data', binding: 'y' } ] }); // // show the equation on the chart let equation = document.getElementById('equation'); // // create a TrendLine and add it to the Chart series collection let trendLine = new wjChartAnalytics.TrendLine(); trendLine.binding = 'y'; trendLine.style = { stroke: 'darkred', strokeWidth: 3 }; trendLine.visibility = wjChart.SeriesVisibility.Hidden; theChart.series.push(trendLine); // // select trendline order let order = new wjInput.InputNumber('#order', { value: trendLine.order, step: 1, min: 1, max: 6, valueChanged: (s) => { if (s.value >= s.min && s.value <= s.max) { trendLine.order = s.value; showEquation(); } } }); // // select fit type let fitType = new wjInput.ComboBox('#fitType', { isRequired: false, placeholder: 'None', textChanged: (s) => { trendLine.name = s.text; if (s.text) { // show trendline trendLine.fitType = s.text; trendLine.visibility = wjChart.SeriesVisibility.Visible; } else { // hide trendline trendLine.visibility = wjChart.SeriesVisibility.Hidden; } switch (s.text) { // enable/disable order input case 'Polynomial': case 'Fourier': order.isDisabled = false; break; default: order.isDisabled = true; break; } showEquation(); }, itemsSource: 'Linear,Exponential,Logarithmic,Power,Fourier,Polynomial,MinX,MinY,MaxX,MaxY,AverageX,AverageY'.split(',') }); // // show updated equation on a timeOut since the TrendLine update is async function showEquation() { equation.innerHTML = ''; setTimeout(() => equation.innerHTML = trendLine.getEquation(), 100); } // // randomize the data document.querySelector('#btnRandomize').addEventListener('click', () => { theChart.itemsSource = getData(); showEquation(); }); } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo FlexChart Trendlines</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="fitType">Trendline Type: </label> <div id="fitType"></div><br /> <label for="order">Order: </label> <div id="order"></div><br /> <label>Equation: </label> <div id="equation" class="equation"></div><br /> <label for="btnRandomize">Randomize Data</label> <button id="btnRandomize" class="btn btn-default"> Go </button> <div id="theChart"></div> </div> </body> </html> // data sources export function getData() { let arr = [], cnt = 50, a = Math.random(), b = Math.random(); // for (let i = 1; i < cnt; i++) { arr.push({ x: i, y: a + i * b + i * Math.random() }); } // return arr; } .wj-flexchart { height: 250px; margin: 10px 0; } .wj-control { margin-bottom: 3px; } label { width: 120px; text-align: right; } .equation { display: inline-block; font-style: italic; font-size: 80%; } .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, ViewChild } 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'; import * as wjInput from '@grapecity/wijmo.input'; import * as wjChart from '@grapecity/wijmo.chart'; import * as wjChartAnalytics from '@grapecity/wijmo.chart.analytics'; // @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { data: any[]; cbData: string[]; order: number; @ViewChild('eqEle') eqEle: HTMLInputElement; @ViewChild('orderIpt') orderIpt: wjInput.InputNumber; @ViewChild('trendline') trendLine: wjChartAnalytics.TrendLine; // constructor(@Inject(DataService) private dataService: DataService) { this.data = dataService.getData(); this.cbData = dataService.getComboData(); this.order = 2; } // showEquation() { if(this.eqEle) { this.eqEle.innerHTML = ''; setTimeout(() => this.eqEle.innerHTML = this.trendLine.getEquation(), 100); } } // randomData() { this.data = this.dataService.getData(); this.showEquation(); } // textChanged(s: wjInput.ComboBox) { let trendLine = this.trendLine; if(!trendLine) { return; } trendLine.name = s.text; if (s.text) { // show trendline trendLine.fitType = <any>s.text; trendLine.visibility = wjChart.SeriesVisibility.Visible; } else { // hide trendline trendLine.visibility = wjChart.SeriesVisibility.Hidden; } switch (s.text) { // enable/disable order input case 'Polynomial': case 'Fourier': this.orderIpt.isDisabled = false; break; default: this.orderIpt.isDisabled = true; break; } this.showEquation(); } } // @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 Trendlines</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 for="fitType">Trendline Type: </label> <wj-combo-box #cb [isRequired]="false" placeholder="None" [itemsSource]="cbData" (textChanged)="textChanged(cb)"></wj-combo-box><br /> <label for="order">Order: </label> <wj-input-number #orderIpt [step]="1" [min]="1" [max]="6" [(value)]="order" (valueChanged)="showEquation()"></wj-input-number><br /> <label>Equation: </label> <div #eqEle id="equation" class="equation"></div><br /> <label for="btnRandomize">Randomize Data</label> <button id="btnRandomize" class="btn btn-default" (click)="randomData()"> Go </button> <wj-flex-chart [itemsSource]="data" chartType="Scatter" bindingX="x"> <wj-flex-chart-axis wjProperty="axisY" [axisLine]="true"></wj-flex-chart-axis> <wj-flex-chart-series name="Raw Data" binding="y"></wj-flex-chart-series> <wj-flex-chart-trend-line #trendline binding="y" [order]="order" [style]="{stroke:'darkred',strokeWidth:3}" visibility="Hidden"></wj-flex-chart-trend-line> </wj-flex-chart> </div> </div> import { Injectable } from '@angular/core'; // @Injectable() export class DataService { getData() { let arr = [], cnt = 50, a = Math.random(), b = Math.random(); // for (let i = 1; i < cnt; i++) { arr.push({ x: i, y: a + i * b + i * Math.random() }); } // return arr; } // getComboData() { return 'Linear,Exponential,Logarithmic,Power,Fourier,Polynomial,MinX,MinY,MaxX,MaxY,AverageX,AverageY'.split(','); } } .wj-flexchart { height: 250px; margin: 10px 0; } .wj-control { margin-bottom: 3px; } label { width: 120px; text-align: right; } .equation { display: inline-block; font-style: italic; font-size: 80%; } .wj-combobox, .wj-inputnumber { width: 120px; margin-right: 12px; } body { margin-bottom: 24pt; } <template> <div class="container-fluid"> <div class="form-group"> <label for="fitType">Trendline Type: </label> <wj-combo-box :isRequired="false" placeholder="None" :itemsSource="comboData" :textChanged="textChanged" :initialized="initializeCombo"></wj-combo-box><br /> <label for="order">Order: </label> <wj-input-number :step="1" :min="1" :max="6" :value="order" :valueChanged="orderChanged" :initialized="initializeInput"></wj-input-number><br /> <label>Equation: </label> <div id="equation" class="equation"></div><br /> <label for="btnRandomize">Randomize Data</label> <button id="btnRandomize" class="btn btn-default" v-on:click="randomData"> Go </button> <wj-flex-chart :itemsSource="data" chartType="Scatter" bindingX="x" :initialized="initializeChart"> <wj-flex-chart-axis wjProperty="axisY" :axisLine="true"></wj-flex-chart-axis> <wj-flex-chart-series name="Raw Data" binding="y"></wj-flex-chart-series> <wj-flex-chart-trend-line binding="y" :order="order" :style="{stroke:'darkred',strokeWidth:3}"></wj-flex-chart-trend-line> </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'; import * as wjChart from '@grapecity/wijmo.chart'; let App = Vue.extend({ name: 'app', data: function () { return { data: getData(), comboData: 'Linear,Exponential,Logarithmic,Power,Fourier,Polynomial,MinX,MinY,MaxX,MaxY,AverageX,AverageY'.split(','), order: 2 } }, mounted: function() { this.eqEle = document.querySelector('#equation'); this.reset(this.combo.selectedValue); }, methods: { initializeInput: function(flex) { this.orderIpt = flex; }, initializeCombo: function(flex) { this.combo = flex; }, initializeChart: function(flex) { this.theChart = flex; this.trendLine = flex.series[1]; }, orderChanged: function(s) { if (s.value >= s.min && s.value <= s.max) { this.order = s.value; this.showEquation(); } }, showEquation: function() { if(this.eqEle) { this.eqEle.innerHTML = ''; setTimeout(() => this.eqEle.innerHTML = this.trendLine.getEquation(), 100); } }, randomData: function() { this.data = getData(); this.showEquation(); }, textChanged: function(s) { this.reset(s.text); }, reset: function(text) { let trendLine = this.trendLine; if(!trendLine) { return; } trendLine.name = text; if (text) { // show trendline trendLine.fitType = text; trendLine.visibility = wjChart.SeriesVisibility.Visible; } else { // hide trendline trendLine.visibility = wjChart.SeriesVisibility.Hidden; } switch (text) { // enable/disable order input case 'Polynomial': case 'Fourier': this.orderIpt.isDisabled = false; break; default: this.orderIpt.isDisabled = true; break; } this.showEquation(); } } }) new Vue({ render: h => h(App) }).$mount('#app'); </script> <style> .wj-flexchart { height: 250px; margin: 10px 0; } .wj-control { margin-bottom: 3px; } label { width: 120px; text-align: right; } .equation { display: inline-block; font-style: italic; font-size: 80%; } .wj-combobox, .wj-inputnumber { width: 120px; margin-right: 12px; } body { margin-bottom: 24pt; } </style> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo FlexChart Trendlines</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 = [], cnt = 50, a = Math.random(), b = Math.random(); // for (let i = 1; i < cnt; i++) { arr.push({ x: i, y: a + i * b + i * Math.random() }); } // 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 wjcChart from "@grapecity/wijmo.chart"; import * as wjInput from '@grapecity/wijmo.react.input'; import * as wjChart from "@grapecity/wijmo.react.chart"; import * as wjChartAnalysis from "@grapecity/wijmo.react.chart.analytics"; import { getData } from "./data"; class App extends React.Component { constructor(props) { super(props); this.state = { data: getData(), comboData: 'Linear,Exponential,Logarithmic,Power,Fourier,Polynomial,MinX,MinY,MaxX,MaxY,AverageX,AverageY'.split(','), order: 2 }; } render() { return <div className="container-fluid"> <div className="form-group"> <label htmlFor="fitType">Trendline Type: </label> <wjInput.ComboBox isRequired={false} placeholder="None" itemsSource={this.state.comboData} textChanged={this.textChanged.bind(this)} initialized={this.initializeCombo.bind(this)}></wjInput.ComboBox><br /> <label htmlFor="order">Order: </label> <wjInput.InputNumber step={1} min={1} max={6} value={this.state.order} valueChanged={this.orderChanged.bind(this)} initialized={this.initializeInput.bind(this)}></wjInput.InputNumber><br /> <label>Equation: </label> <div id="equation" className="equation"></div><br /> <label htmlFor="btnRandomize">Randomize Data</label> <button id="btnRandomize" className="btn btn-default" onClick={this.randomData.bind(this)}> Go </button> <wjChart.FlexChart itemsSource={this.state.data} chartType="Scatter" bindingX="x" initialized={this.initializeChart.bind(this)}> <wjChart.FlexChartAxis wjProperty="axisY" axisLine={true}></wjChart.FlexChartAxis> <wjChart.FlexChartSeries name="Raw Data" binding="y"></wjChart.FlexChartSeries> <wjChartAnalysis.FlexChartTrendLine binding="y" order={this.state.order} style={{ stroke: 'darkred', strokeWidth: 3 }}></wjChartAnalysis.FlexChartTrendLine> </wjChart.FlexChart> </div> </div>; } componentDidMount() { this.eqEle = document.querySelector('#equation'); this.reset(this.combo.selectedValue); } initializeInput(flex) { this.orderIpt = flex; } initializeCombo(flex) { this.combo = flex; } initializeChart(flex) { this.theChart = flex; this.trendLine = flex.series[1]; } orderChanged(s) { if (s.value >= s.min && s.value <= s.max) { this.setState({ order: s.value }); this.showEquation(); } } showEquation() { if (this.eqEle) { this.eqEle.innerHTML = ''; setTimeout(() => this.eqEle.innerHTML = this.trendLine.getEquation(), 100); } } randomData() { this.setState({ data: getData() }); this.showEquation(); } textChanged(s) { this.reset(s.text); } reset(text) { let trendLine = this.trendLine; if (!trendLine) { return; } trendLine.name = text; if (text) { // show trendline trendLine.fitType = text; trendLine.visibility = wjcChart.SeriesVisibility.Visible; } else { // hide trendline trendLine.visibility = wjcChart.SeriesVisibility.Hidden; } switch (text) { // enable/disable order input case 'Polynomial': case 'Fourier': this.orderIpt.isDisabled = false; break; default: this.orderIpt.isDisabled = true; break; } this.showEquation(); } } 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> .wj-flexchart { height: 250px; margin: 10px 0; } .wj-control { margin-bottom: 3px; } label { width: 120px; text-align: right; } .equation { display: inline-block; font-style: italic; font-size: 80%; } .wj-combobox, .wj-inputnumber { width: 120px; margin-right: 12px; } body { margin-bottom: 24pt; } export function getData() { let arr = [], cnt = 50, a = Math.random(), b = Math.random(); // for (let i = 1; i < cnt; i++) { arr.push({ x: i, y: a + i * b + i * (Math.random() - .5) }); } // return arr; }