Trend Lines

The TrendLine class extends the regular Series class to provide a calculated series based on the data and parameters you select.

To add trend lines to a chart, follow these steps:

  1. Create one or more TrendLine objects,
  2. Configure the TrendLine objects as you would a regular series, setting their binding, chartType, and style properties for example, and
  3. Set the TrendLine's fitType and order properties to determine the type of trend line 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(), 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; }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, meta: { '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { 'jszip': 'npm:jszip/dist/jszip.js', '@grapecity/wijmo': 'npm:@grapecity/wijmo/index.js', '@grapecity/wijmo.input': 'npm:@grapecity/wijmo.input/index.js', '@grapecity/wijmo.styles': 'npm:@grapecity/wijmo.styles', '@grapecity/wijmo.cultures': 'npm:@grapecity/wijmo.cultures', '@grapecity/wijmo.chart': 'npm:@grapecity/wijmo.chart/index.js', '@grapecity/wijmo.chart.analytics': 'npm:@grapecity/wijmo.chart.analytics/index.js', '@grapecity/wijmo.chart.animation': 'npm:@grapecity/wijmo.chart.animation/index.js', '@grapecity/wijmo.chart.annotation': 'npm:@grapecity/wijmo.chart.annotation/index.js', '@grapecity/wijmo.chart.finance': 'npm:@grapecity/wijmo.chart.finance/index.js', '@grapecity/wijmo.chart.finance.analytics': 'npm:@grapecity/wijmo.chart.finance.analytics/index.js', '@grapecity/wijmo.chart.hierarchical': 'npm:@grapecity/wijmo.chart.hierarchical/index.js', '@grapecity/wijmo.chart.interaction': 'npm:@grapecity/wijmo.chart.interaction/index.js', '@grapecity/wijmo.chart.radar': 'npm:@grapecity/wijmo.chart.radar/index.js', '@grapecity/wijmo.chart.render': 'npm:@grapecity/wijmo.chart.render/index.js', '@grapecity/wijmo.chart.webgl': 'npm:@grapecity/wijmo.chart.webgl/index.js', '@grapecity/wijmo.gauge': 'npm:@grapecity/wijmo.gauge/index.js', '@grapecity/wijmo.grid': 'npm:@grapecity/wijmo.grid/index.js', '@grapecity/wijmo.grid.detail': 'npm:@grapecity/wijmo.grid.detail/index.js', '@grapecity/wijmo.grid.filter': 'npm:@grapecity/wijmo.grid.filter/index.js', '@grapecity/wijmo.grid.search': 'npm:@grapecity/wijmo.grid.search/index.js', '@grapecity/wijmo.grid.grouppanel': 'npm:@grapecity/wijmo.grid.grouppanel/index.js', '@grapecity/wijmo.grid.multirow': 'npm:@grapecity/wijmo.grid.multirow/index.js', '@grapecity/wijmo.grid.transposed': 'npm:@grapecity/wijmo.grid.transposed/index.js', '@grapecity/wijmo.grid.transposedmultirow': 'npm:@grapecity/wijmo.grid.transposedmultirow/index.js', '@grapecity/wijmo.grid.pdf': 'npm:@grapecity/wijmo.grid.pdf/index.js', '@grapecity/wijmo.grid.sheet': 'npm:@grapecity/wijmo.grid.sheet/index.js', '@grapecity/wijmo.grid.xlsx': 'npm:@grapecity/wijmo.grid.xlsx/index.js', '@grapecity/wijmo.grid.selector': 'npm:@grapecity/wijmo.grid.selector/index.js', '@grapecity/wijmo.grid.cellmaker': 'npm:@grapecity/wijmo.grid.cellmaker/index.js', '@grapecity/wijmo.nav': 'npm:@grapecity/wijmo.nav/index.js', '@grapecity/wijmo.odata': 'npm:@grapecity/wijmo.odata/index.js', '@grapecity/wijmo.olap': 'npm:@grapecity/wijmo.olap/index.js', '@grapecity/wijmo.pdf': 'npm:@grapecity/wijmo.pdf/index.js', '@grapecity/wijmo.pdf.security': 'npm:@grapecity/wijmo.pdf.security/index.js', '@grapecity/wijmo.viewer': 'npm:@grapecity/wijmo.viewer/index.js', '@grapecity/wijmo.xlsx': 'npm:@grapecity/wijmo.xlsx/index.js', '@grapecity/wijmo.undo': 'npm:@grapecity/wijmo.undo/index.js', '@grapecity/wijmo.interop.grid': 'npm:@grapecity/wijmo.interop.grid/index.js', '@grapecity/wijmo.touch': 'npm:@grapecity/wijmo.touch/index.js', '@grapecity/wijmo.cloud': 'npm:@grapecity/wijmo.cloud/index.js', '@grapecity/wijmo.barcode': 'npm:@grapecity/wijmo.barcode/index.js', '@grapecity/wijmo.barcode.common': 'npm:@grapecity/wijmo.barcode.common/index.js', '@grapecity/wijmo.barcode.composite': 'npm:@grapecity/wijmo.barcode.composite/index.js', '@grapecity/wijmo.barcode.specialized': 'npm:@grapecity/wijmo.barcode.specialized/index.js', 'jszip': 'npm:jszip/dist/jszip.js', 'bootstrap.css': 'npm:bootstrap/dist/css/bootstrap.min.css', 'css': 'npm:systemjs-plugin-css/css.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'js' }, "node_modules": { defaultExtension: 'js' }, } }); })(this);