FlexChart Analytics

This page shows how to use function series and trend lines in Wijmo's FlexChart control. These features are included in wijmo.chart.analytics module.

Getting Started

Steps for getting started with the FlexChart Analytics in JavaScript applications:

  1. Add references to Wijmo.
  2. Add markup to serve as the FlexChart's host.
  3. Initialize the FlexChart via JavaScript and its itemSource property.
  4. Create one or more data series, and add each to the FlexChart's series collection (Optional).
  5. Create one or more trend line or function series, and add each to the FlexChart's series collection.
  6. Add some CSS to customize the chart's appearance (Optional).
HTML
<div id="gettingStartedChart"></div>
JS
// create a chart var gettingStartedChart = new wijmo.chart.FlexChart('#gettingStartedChart', { itemsSource: appData, bindingX: 'x', series: [ { name: 'Origin', binding: 'y', chartType: 'Scatter' } ] }); // add a TrendLine to the chart gettingStartedChart.series.push(new wijmo.chart.analytics.TrendLine({ name: 'Trendline', binding: 'y', sampleCount: 100, }));
CSS
.wj-flexchart { background-color: white; box-shadow: 4px 4px 10px 0px rgba(50, 50, 50, 0.75); height: 400px; margin-bottom: 12px; padding: 8px; }

Result (live):

TrendLine

You can use different trendline types by setting the fitType property of the TrendLine object.

The example below allows you to see what happens when you change this property:

HTML
<div id="trendLineChart"></div> <select id="fitTypeMenu"> <option value="0" selected="selected">Linear</option> <option value="1">Exponential</option> <option value="2">Logarithmic</option> <option value="3">Power</option> <option value="4">Fourier</option> <option value="5">Polynomial</option> <option value="6">MinX</option> <option value="7">MinY</option> <option value="8">MaxX</option> <option value="9">MaxY</option> <option value="10">AverageX</option> <option value="11">AverageY</option> </select>
JS
var trendLineChart = new wijmo.chart.FlexChart('#trendLineChart', { itemsSource: appData, bindingX: 'x', series: [ { name: 'Origin', binding: 'y', chartType: 'Scatter' }] }); // add TrendLine to the chart var trendLine = new wijmo.chart.analytics.TrendLine({ name: 'Trend Line', binding: 'y', sampleCount: 100 }); trendLineChart.series.push(trendLine); // trendline fit type menu var fitTypeMenu = new wijmo.input.Menu('#fitTypeMenu', { itemClicked: function (s, e) { trendLine.fitType = parseInt(fitTypeMenu.selectedValue); updateMenuHeader(s, 'Fit Type'); } }); updateMenuHeader(fitTypeMenu, 'Fit Type');

Result (live):

MovingAverage

You can use different moving average types by setting the type property of MovingAverage.

The MovingAverage class has a period property that allows you to set the number of periods for computing the average value.

The example below allows you to see what happens when you change these properties:

HTML
<div id="movingAverageChart"></div> <select id="typeMenu"> <option value="0" selected="selected">Simple</option> <option value="1">Weighted</option> <option value="2">Exponential</option> <option value="3">Triangular</option> </select> <b>Period:</b> <input id="periodInput"/>
JS
var movingAverageChart = new wijmo.chart.FlexChart('#movingAverageChart', { itemsSource: getData(40), bindingX: 'x', series: [ { name: 'Origin', binding: 'y', chartType: 'Scatter' }] }); // create MovingAverage series and add it to the chart var movingAverage = new wijmo.chart.analytics.MovingAverage({ name: 'Moving Avg', binding: 'y', sampleCount: 100 }); movingAverageChart.series.push(movingAverage); // change the moving average period var periodInput = new wijmo.input.InputNumber('#periodInput', { valueChanged: function (s, e) { if (s.value >= s.min && s.value <= s.max) { movingAverage.period = s.value; } }, value: 2, min: 2, max: 29, step: 1, format: 'n0' }); // change chart type var typeMenu = new wijmo.input.Menu('#typeMenu', { itemClicked: function (s, e) { movingAverage.type = parseInt(typeMenu.selectedValue); updateMenuHeader(s , 'Fit Type'); } }); updateMenuHeader(typeMenu, 'Fit Type');

Result (live):

Period:

YFunctionSeries

The YFunctionSeries allows you to plot a function that is defined by formulas in the format y=y(x).

Use the func property to specify the function.

HTML
<div id="yFuncSeriesChart"></div>
JS
var yFuncSeriesChart = new wijmo.chart.FlexChart('#yFuncSeriesChart'); // add a YFunctionSeries series yFuncSeriesChart.series.push(new wijmo.chart.analytics.YFunctionSeries({ name: 'YFunc', min: -10, max: 10, sampleCount: 300, func: function (value) { return Math.sin(4 * value) * Math.cos(3 * value) } }));

Result (live):

ParametricFunctionSeries

The ParametricFunctionSeries allows you to plot functions defined by two formulas in the format x=x(t) and y=y(t).

Use the xFunc and yFunc properties to specify the functions.

HTML
<div id="paramFuncSeriesChart"></div>
JS
var paramFuncSeriesChart = new wijmo.chart.FlexChart('#paramFuncSeriesChart'); //create ParametricFunctionSeries var xParam = 5, yParam = 7; paramFuncSeriesChart.series.push(new wijmo.chart.analytics.ParametricFunctionSeries({ name: 'ParamFunc', max: 2 * Math.PI, sampleCount: 1000, xFunc: function (value) { return Math.cos(value * xParam); }, yFunc: function (value) { return Math.sin(value * yParam); } }));

Result (live):

Waterfall

The Waterfall series is normally used to demonstrate how the starting position either increases or decreases through a series of changes.

HTML
<div id="waterfallChart"></div> <dl class="dl-horizontal"> <dt><label for="relativeData">Relative Data</label></dt> <dd><input id="relativeData" type="checkbox" checked="checked" /></dd> <dt><label for="connectorLines">Show Connector Lines</label></dt> <dd><input id="connectorLines" type="checkbox" checked="checked" /></dd> <dt><label for="showTotal">Show Total</label></dt> <dd><input id="showTotal" type="checkbox" checked="checked" /></dd> <dt><label for="showIntermediateTotal">Show Intermediate Total</label></dt> <dd><input id="showIntermediateTotal" type="checkbox" checked="checked" /></dd> </dl>
JS
var waterfallChart = new wijmo.chart.FlexChart('#waterfallChart', { itemsSource: getWaterFallData(), binding: 'value', bindingX: 'name', tooltip: { content: function (ht) { return '<b>' + ht.x + '</b><br/>value: ' + ht.y; } } }); // create Waterfall series and add it to the chart var waterfall = new wijmo.chart.analytics.Waterfall({ relativeData: true, connectorLines: true, showTotal: true, start: 1000, showIntermediateTotal: true, intermediateTotalPositions: [3, 6, 9, 12], intermediateTotalLabels: ['Q1', 'Q2', 'Q3', 'Q4'], name: 'Increase,Decrease,Total', styles: { connectorLines: { stroke: '#333', strokeWidth: 3 }, start: { fill: '#7dc7ed' }, falling: { fill: '#dd2714', stroke: '#a52714' }, rising: { fill: '#0f9d58', stroke: '#0f9d58' }, intermediateTotal: { fill: '#7dc7ed' }, total: { fill: '#7dc7ed' } } }); waterfallChart.series.push(waterfall); // configure waterfall document.getElementById('relativeData').addEventListener('click', function (e) { waterfall.relativeData = e.target.checked; }); document.getElementById('connectorLines').addEventListener('click', function (e) { waterfall.connectorLines = e.target.checked; }); document.getElementById('showTotal').addEventListener('click', function (e) { waterfall.showTotal = e.target.checked; }); document.getElementById('showIntermediateTotal').addEventListener('click', function (e) { waterfall.showIntermediateTotal = e.target.checked; }); // create some data for the Waterfall chart function getWaterFallData() { var names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], data = []; names.forEach(function (item) { data.push({ name: item, value: Math.round((0.5 - Math.random()) * 1000) }); }); return data; }

Result (live):

Box & Whisker

The BoxWhisker series is normally used to compare distributions between different sets of numerical data.

HTML
<div id="boxwhiskerChart"></div> <dl class="dl-horizontal"> <dt><label for="boxGroupWidth">Group Width</label></dt> <dd><div id="boxGroupWidth"></div></dd> <dt><label for="boxGapWidth">Gap Width</label></dt> <dd><div id="boxGapWidth"></div></dd> <dt><label for="boxQuartileCalculation">Quartile Calculation</label></dt> <dd> <select id="boxQuartileCalculation"> <option value="0" selected="selected">Inclusive Median</option> <option value="1">Exclusive Median</option> </select> </dd> <dt><label for="boxShowMeanLine">Show Mean Line</label></dt> <dd><input id="boxShowMeanLine" type="checkbox" /></dd> <dt><label for="boxShowMeanMarker">Show Mean Marker</label></dt> <dd><input id="boxShowMeanMarker" type="checkbox" /></dd> <dt><label for="boxShowInnerPoints">Show Inner Points</label></dt> <dd><input id="boxShowInnerPoints" type="checkbox" /></dd> <dt><label for="boxShowOutliers">Show Outliers</label></dt> <dd><input id="boxShowOutliers" type="checkbox" /></dd> <dt><label for="boxRotated">Rotated</label></dt> <dd><input id="boxRotated" type="checkbox" /></dd> <dt><label for="boxShowLabel">Show Label</label></dt> <dd><input id="boxShowLabel" type="checkbox" /></dd> </dl>
JS
var boxwhiskerChart = new wijmo.chart.FlexChart('#boxwhiskerChart', { itemsSource: getBoxWhiskerData(), bindingX: 'country', tooltip: { content: function (ht) { return '<b>' + ht.name + '</b> - <b>' + ht.x + '</b></br>' + '<b>min</b>: ' + ht.item.min + '</br>' + '<b>firstQuartile</b>: ' + ht.item.firstQuartile + '</br>' + '<b>median</b>: ' + ht.item.median + '</br>' + '<b>thirdQuartile</b>: ' + ht.item.thirdQuartile + '</br>' + '<b>max</b>: ' + ht.item.max + '</br>' + '<b>mean</b>: ' + ht.item.mean + '</br>'; } } }); // add some BoxWhisker series to the chart boxwhiskerChart.series.push(new wijmo.chart.analytics.BoxWhisker({ name: 'Downloads', binding: 'downloads' })); boxwhiskerChart.series.push(new wijmo.chart.analytics.BoxWhisker({ name: 'Sales', binding: 'sales' })); boxwhiskerChart.series.push(new wijmo.chart.analytics.BoxWhisker({ name: 'Expenses', binding: 'expenses' })); // configure the chart var groupWidth = new wijmo.input.InputNumber('#boxGroupWidth', { min: 0, max: 1, step: 0.1, valueChanged: function (s) { if (s.value >= s.min && s.value <= s.max) { boxwhiskerChart.series.forEach(function (series) { series.groupWidth = s.value; }) } }, value: 0.8 }); var gapWidth = new wijmo.input.InputNumber('#boxGapWidth', { min: 0, max: 1, step: 0.1, valueChanged: function (s) { if (s.value >= s.min && s.value <= s.max) { boxwhiskerChart.series.forEach(function (series) { series.gapWidth = s.value; }); } }, value: 0.1 }); var quartileCalculation = new wijmo.input.Menu('#boxQuartileCalculation', { itemClicked: function (s, e) { var val = parseInt(s.selectedValue); boxwhiskerChart.series.forEach(function (series) { series.quartileCalculation = val; }); updateMenuHeader(s); } }); updateMenuHeader(quartileCalculation); // handle checkboxes document.getElementById('boxShowMeanLine').addEventListener('click', function (e) { boxwhiskerChart.series.forEach(function (series) { series.showMeanLine = e.target.checked; }); }); document.getElementById('boxShowMeanMarker').addEventListener('click', function (e) { boxwhiskerChart.series.forEach(function (series) { series.showMeanMarker = e.target.checked; }); }); document.getElementById('boxShowInnerPoints').addEventListener('click', function (e) { boxwhiskerChart.series.forEach(function (series) { series.showInnerPoints = e.target.checked; }); }); document.getElementById('boxShowOutliers').addEventListener('click', function (e) { boxwhiskerChart.series.forEach(function (series) { series.showOutliers = e.target.checked; }); }); document.getElementById('boxRotated').addEventListener('click', function (e) { boxwhiskerChart.rotated = e.target.checked; }); document.getElementById('boxShowLabel').addEventListener('click', function (e) { boxwhiskerChart.dataLabel.content = e.target.checked ? '{y}' : ''; }); // create some data for the BoxWhisker chart function getBoxWhiskerData() { var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','), data = []; countries.forEach(function (country) { data.push({ country: country, downloads: getBoxWhiskerArray(12, 100), sales: getBoxWhiskerArray(11, 100), expenses: getBoxWhiskerArray(13, 100) }); }); return data; } function getBoxWhiskerArray(cnt, maxVal) { var arr = []; for (var i = 0; i < cnt; i++) { arr.push(Math.round(Math.random() * maxVal)); } return arr; }

Result (live):

Error Bars

The ErrorBar series shows error margins and standard deviations.

HTML
<div id="errorbarChart"></div> <dl class="dl-horizontal"> <dt><label for="ebRotated">Rotated</label></dt> <dd><input id="ebRotated" type="checkbox" /></dd> <dt>Chart Type</dt> <dd> <select id="ebChartType"> <option value="0" selected="selected">Column</option> <option value="1">Bar</option> <option value="2">Scatter</option> <option value="3">Line</option> <option value="4">LineSymbols</option> <option value="5">Area</option> <option value="9">Spline</option> <option value="10">SplineSymbols</option> <option value="11">SplineArea</option> </select> </dd> <dt>Error Amount</dt> <dd> <select id="ebErrorAmount"> <option value="0" selected="selected">FixedValue</option> <option value="1">Percentage</option> <option value="2">StandardDeviation</option> <option value="3">StandardError</option> <option value="4">Custom</option> </select> </dd> <dt>End Style</dt> <dd> <select id="ebEndStyle"> <option value="0" selected="selected">Cap</option> <option value="1">No Cap</option> </select> </dd> <dt>Direction</dt> <dd> <select id="ebDirection"> <option value="0" selected="selected">Both</option> <option value="1">Minus</option> <option value="2">Plus</option> </select> </dd> </dl>
JS
var errorbarChart = new wijmo.chart.FlexChart('#errorbarChart', { itemsSource: getErrorBarData(), bindingX: 'country', tooltip: { content: '{y}' }, }); // add ErrorBar series to the chart var errorBar = new wijmo.chart.analytics.ErrorBar({ binding: 'downloads', value: 10 }); errorbarChart.series.push(errorBar); // customize chart/ErrorAmount series document.getElementById('ebRotated').addEventListener('click', function (e) { errorbarChart.rotated = e.target.checked; }); var chartType = new wijmo.input.Menu('#ebChartType', { itemClicked: function (s, e) { var val = parseInt(chartType.selectedValue); errorbarChart.chartType = val; updateMenuHeader(chartType); } }); updateMenuHeader(chartType); var errorAmount = new wijmo.input.Menu('#ebErrorAmount', { itemClicked: function (s, e) { var val = parseInt(errorAmount.selectedValue); errorBar.errorAmount = val; switch (val) { case 0: errorBar.value = 10; break; case 1: errorBar.value = 0.1; break; case 2: errorBar.value = 1; break; case 4: errorBar.value = { minus: 5, plus: 10 }; break; } updateMenuHeader(errorAmount); } }); updateMenuHeader(errorAmount); var endStyle = new wijmo.input.Menu('#ebEndStyle', { itemClicked: function (s, e) { var val = parseInt(s.selectedValue); errorBar.endStyle = val; updateMenuHeader(s); } }); updateMenuHeader(endStyle); var direction = new wijmo.input.Menu('#ebDirection', { itemClicked: function (s, e) { var val = parseInt(s.selectedValue); errorBar.direction = val; updateMenuHeader(s); } }); updateMenuHeader(direction); // create some data for the Error Bar chart function getErrorBarData() { var countries = 'US,Germany,UK,Japan,Italy,Greece,China,France,Russia'.split(','), data = []; countries.forEach(function (country) { data.push({ country: country, downloads: getErrorBarValue(), sales: getErrorBarValue() }); }); return data; } function getErrorBarValue() { var val = Math.round(Math.random() * 100); return val > 10 ? val : val + 10; }

Result (live):

Chart Type
Error Amount
End Style
Direction