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).
<!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="css/bootstrap.css"/> <link rel="stylesheet" type="text/css" href="css/wijmo.css" /> <link href="css/app.css" rel="stylesheet" type="text/css" /> <script src="scripts/wijmo.js" type="text/javascript"></script> <script src="scripts/wijmo.input.js" type="text/javascript"></script> <script src="scripts/wijmo.chart.js" type="text/javascript"></script> <script src="scripts/wijmo.chart.analytics.js" type="text/javascript"> </script> <script src="scripts/app.js" type="text/javascript"></script> </head> <body> <!-- this is the FlexChart --> <div id="gettingStartChart"></div> </body> </html>
// create FlexChart var gettingStartedChart = new wijmo.chart.FlexChart('#gettingStartedChart'); // initialize FlexChart's properties gettingStartedChart.initialize({ itemsSource: appData, bindingX: 'x', series: [{ name: 'Origin', binding: 'y', chartType: wijmo.chart.ChartType.Scatter }] }); //create TrendLine var trendLine = new wijmo.chart.analytics.TrendLine(); trendLine.name = 'Trend Line'; trendLine.binding = 'y'; trendLine.sampleCount = 100; gettingStartedChart.series.push(trendLine);
.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 TrendLine.

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

<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>
// create FlexChart and Menus var trendLineChart = new wijmo.chart.FlexChart('#trendLineChart'), fitTypeMenu = new wijmo.input.Menu('#fitTypeMenu'), trendLine; // initialize FlexChart's properties trendLineChart.initialize({ itemsSource: appData, bindingX: 'x', series: [{ name: 'Origin', binding: 'y', chartType: wijmo.chart.ChartType.Scatter }] }); //create TrendLine trendLine = new wijmo.chart.analytics.TrendLine(); trendLine.name = 'Trend Line'; trendLine.binding = 'y'; trendLine.sampleCount = 100; trendLineChart.series.push(trendLine); // update the menus' headers updateMenuHeader(); fitTypeMenu.selectedIndexChanged.addHandler(function () { if (fitTypeMenu.selectedValue) { // update TrendLine's fitType trendLine.fitType = parseInt(fitTypeMenu.selectedValue); // update menu header updateMenuHeader(); } }); // helper function for Menu headers function updateMenuHeader() { fitTypeMenu.header = '<b>Fit Type</b>: ' + fitTypeMenu.text; }

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:

<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" type="text" />
// create FlexChart and Menus var movingAverageChart = new wijmo.chart.FlexChart('#movingAverageChart'), typeMenu = new wijmo.input.Menu('#typeMenu'), periodInput = new wijmo.input.InputNumber('#periodInput'), movingAverage; //set inputnumber periodInput.value = 2; periodInput.min = 2; periodInput.max = 29; periodInput.step = 1; periodInput.format = "n0"; // initialize FlexChart's properties movingAverageChart.initialize({ itemsSource: getData(40), bindingX: 'x', series: [{ name: 'Origin', binding: 'y', chartType: wijmo.chart.ChartType.Scatter }] }); //create MovingAverage movingAverage = new wijmo.chart.analytics.MovingAverage(); movingAverage.name = 'MA'; movingAverage.binding = 'y'; movingAverage.sampleCount = 100; movingAverageChart.series.push(movingAverage); // update the menus' headers updateMenuHeader(); typeMenu.selectedIndexChanged.addHandler(function () { if (typeMenu.selectedValue) { // update MovingAverage's type movingAverage.type = parseInt(typeMenu.selectedValue); // update menu header updateMenuHeader(); } }); periodInput.valueChanged.addHandler(function () { // update MovingAverage's period movingAverage.period = periodInput.value; }); // helper function for Menu headers function updateMenuHeader() { typeMenu.header = '<b>Type</b>: ' + typeMenu.text; }

Result (live):

Period:

YFunctionSeries

This view shows Y Function Series in FlexChart. The YFunctionSeries allows to plot a function that is defined with formula y=y(x). Use the func property to specify the function.

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

Result (live):

ParametricFunctionSeries

The ParametricFunctionSeries allows to plot a function that is defined parametrically with formulas x = x(t) and y = y(t). Use the xFunc and yFunc properties to specify the functions for x and y coordinates.

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

Result (live):

Waterfall

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

<div id="waterfallChart"></div> <div class="form-horizontal"> <div class="form-group"> <div class="col-md-offset-3 col-md-9"> <div class="checkbox"> <label> <input id="relativeData" type="checkbox"> Is RelativeData? </label> </div> </div> </div> <div class="form-group"> <div class="col-md-offset-3 col-md-9"> <div class="checkbox"> <label> <input id="connectorLines" type="checkbox"> Show Connector Lines? </label> </div> </div> </div> <div class="form-group"> <div class="col-md-offset-3 col-md-9"> <div class="checkbox"> <label> <input id="showTotal" type="checkbox"> Show Total? </label> </div> </div> </div> <div class="form-group"> <div class="col-md-offset-3 col-md-9"> <div class="checkbox"> <label> <input id="showIntermediateTotal" type="checkbox"> Show Intermediate Total? </label> </div> </div> </div> </div>
//create chart var waterfallChart = new wijmo.chart.FlexChart('#waterfallChart'), relativeData = document.getElementById('relativeData'), connectorLines = document.getElementById('connectorLines'), showTotal = document.getElementById('showTotal'), showIntermediateTotal = document.getElementById('showIntermediateTotal'); // populate itemsSource var names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], data = []; for (var i = 0, len = names.length; i < len; i++) { data.push({ name: names[i], value: Math.round((0.5 - Math.random()) * 1000) }); } waterfallChart.itemsSource = data; waterfallChart.binding = 'value'; waterfallChart.bindingX = 'name'; //create Waterfall series var waterfall = new wijmo.chart.analytics.Waterfall(); waterfall.relativeData = false; waterfall.connectorLines = false; waterfall.showTotal = false; waterfall.start = 1000; waterfall.showIntermediateTotal = false; waterfall.intermediateTotalPositions = [3, 6, 9, 12]; waterfall.intermediateTotalLabels = ['Q1', 'Q2', 'Q3', 'Q4']; waterfall.name = 'Increase,Decrease,Total'; waterfall.styles = { connectorLines: { stroke: '#333', 'stroke-dasharray': '5 5' }, start: { fill: '#7dc7ed' }, falling: { fill: '#dd2714', stroke: '#a52714' }, rising: { fill: '#0f9d58', stroke: '#0f9d58' }, intermediateTotal: { fill: '#7dc7ed' }, total: { fill: '#7dc7ed' } }; waterfallChart.series.push(waterfall); waterfallChart.tooltip.content = function (ht) { if (ht) { return '<b>' + ht.x + '</b><br/>value: ' + ht.y; } } // relativeData - initialize checkbox properties relativeData.addEventListener('change', function () { waterfall.relativeData = this.checked; }); // connectorLines - initialize checkbox properties connectorLines.addEventListener('change', function () { waterfall.connectorLines = this.checked; }); // showTotal - initialize checkbox properties showTotal.addEventListener('change', function () { waterfall.showTotal = this.checked; }); // showIntermediateTotal - initialize checkbox properties showIntermediateTotal.addEventListener('change', function () { waterfall.showIntermediateTotal = this.checked; });

Result (live):

Box & Whisker

The Box & Whisker series is normally used to compare distributions between different sets of numerical data

<div id="boxwhiskerChart"></div> <div class="form-horizontal"> <dl class="dl-horizontal"> <dt>Group Width</dt> <dd> <div id="boxGroupWidth"></div> </dd> </dl> <dl class="dl-horizontal"> <dt>Gap Width</dt> <dd> <div id="boxGapWidth"></div> </dd> </dl> <dl class="dl-horizontal"> <dt> <label for="boxShowMeanLine">Show Mean Line</label> </dt> <dd> <input id="boxShowMeanLine" type="checkbox" /> </dd> </dl> <dl class="dl-horizontal"> <dt> <label for="boxShowMeanMarker">Show Mean Marker</label> </dt> <dd> <input id="boxShowMeanMarker" type="checkbox" /> </dd> </dl> <dl class="dl-horizontal"> <dt> <label for="boxShowInnerPoints">Show Inner Points</label> </dt> <dd> <input id="boxShowInnerPoints" type="checkbox" /> </dd> </dl> <dl class="dl-horizontal"> <dt> <label for="boxShowOutliers">Show Outliers</label> </dt> <dd> <input id="boxShowOutliers" type="checkbox" /> </dd> </dl> <dl class="dl-horizontal"> <dt> <label for="boxRotated">Rotated</label> </dt> <dd> <input id="boxRotated" type="checkbox" /> </dd> </dl> <dl class="dl-horizontal"> <dt> <label for="boxShowLabel">Show Label</label> </dt> <dd> <input id="boxShowLabel" type="checkbox" /> </dd> </dl> <dl class="dl-horizontal"> <dt>Quartile Calculation</dt> <dd> <select id="boxQuartileCalculation"> <option value="0" selected="selected">Inclusive Median</option> <option value="1">Exclusive Median</option> </select> </dd> </dl> </div>
//create chart var boxwhiskerChart = new wijmo.chart.FlexChart('#boxwhiskerChart'), groupWidth = new wijmo.input.InputNumber('#boxGroupWidth'), gapWidth = new wijmo.input.InputNumber('#boxGapWidth'), quartileCalculation = new wijmo.input.Menu('#boxQuartileCalculation'); // populate itemsSource // generate some random data var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','), funnelData = [], boxData = []; for (var i = 0; i < countries.length; i++) { boxData.push({ country: countries[i], downloads: [getData(), getData(), getData(), getData(), getData(), getData(), getData(), getData(), getData(), getData(), getData(), getData()], sales: [getData(), getData(), getData(), getData(), getData(), getData(), getData(), getData(), getData(), getData(), getData()], expenses: [getData(), getData(), getData(), getData(), getData(), getData(), getData(), getData(), getData(), getData(), getData(), getData(), getData()] }); } function getData() { return Math.round(Math.random() * 100); } //create Box & Whisker series boxwhiskerChart.beginUpdate(); boxwhiskerChart.tooltip.content = function (hti) { return '<b>' + hti.name + '</b> - <b>' + hti.x + '</b></br>' + '<b>min</b>: ' + hti.item.min + '</br>' + '<b>firstQuartile</b>: ' + hti.item.firstQuartile + '</br>' + '<b>median</b>: ' + hti.item.median + '</br>' + '<b>thirdQuartile</b>: ' + hti.item.thirdQuartile + '</br>' + '<b>max</b>: ' + hti.item.max + '</br>' + '<b>mean</b>: ' + hti.item.mean + '</br>'; } boxwhiskerChart.itemsSource = boxData; boxwhiskerChart.bindingX = 'country'; var boxwhisker1 = new wijmo.chart.analytics.BoxWhisker(); boxwhisker1.name = 'downloads'; boxwhisker1.binding = 'downloads'; boxwhiskerChart.series.push(boxwhisker1); var boxwhisker2 = new wijmo.chart.analytics.BoxWhisker(); boxwhisker2.name = 'sales'; boxwhisker2.binding = 'sales'; boxwhiskerChart.series.push(boxwhisker2); var boxwhisker3 = new wijmo.chart.analytics.BoxWhisker(); boxwhisker3.name = 'expenses'; boxwhisker3.binding = 'expenses'; boxwhiskerChart.series.push(boxwhisker3); boxwhiskerChart.endUpdate(); // groupWidth - initialize InputNumber's properties groupWidth.min = 0; groupWidth.max = 1; groupWidth.step = 0.1; groupWidth.valueChanged.addHandler(function (sender) { if (sender.value < sender.min || sender.value > sender.max) { return; } boxwhisker1.groupWidth = sender.value; boxwhisker2.groupWidth = sender.value; boxwhisker3.groupWidth = sender.value; boxwhiskerChart.refresh(true); }); groupWidth.value = 0.8; // gapWidth - initialize InputNumber's properties gapWidth.min = 0; gapWidth.max = 1; gapWidth.step = 0.1; gapWidth.valueChanged.addHandler(function (sender) { if (sender.value < sender.min || sender.value > sender.max) { return; } boxwhisker1.gapWidth = sender.value; boxwhisker2.gapWidth = sender.value; boxwhisker3.gapWidth = sender.value; boxwhiskerChart.refresh(true); }); gapWidth.value = 0.1; updateMenuHeader(quartileCalculation); quartileCalculation.selectedIndexChanged.addHandler(function () { if (quartileCalculation.selectedValue) { var val = +quartileCalculation.selectedValue; boxwhisker1.quartileCalculation = val; boxwhisker2.quartileCalculation = val; boxwhisker3.quartileCalculation = val; updateMenuHeader(quartileCalculation); boxwhiskerChart.refresh(true); } }); var showMeanLine = document.getElementById('boxShowMeanLine'); showMeanLine.addEventListener('click', function () { boxwhisker1.showMeanLine = this.checked; boxwhisker2.showMeanLine = this.checked; boxwhisker3.showMeanLine = this.checked; boxwhiskerChart.refresh(true); }); var showMeanMarker = document.getElementById('boxShowMeanMarker'); showMeanMarker.addEventListener('click', function () { boxwhisker1.showMeanMarker = this.checked; boxwhisker2.showMeanMarker = this.checked; boxwhisker3.showMeanMarker = this.checked; boxwhiskerChart.refresh(true); }); var boxShowInnerPoints = document.getElementById('boxShowInnerPoints'); boxShowInnerPoints.addEventListener('click', function () { boxwhisker1.showInnerPoints = this.checked; boxwhisker2.showInnerPoints = this.checked; boxwhisker3.showInnerPoints = this.checked; boxwhiskerChart.refresh(true); }); var boxShowOutliers = document.getElementById('boxShowOutliers'); boxShowOutliers.addEventListener('click', function () { boxwhisker1.showOutliers = this.checked; boxwhisker2.showOutliers = this.checked; boxwhisker3.showOutliers = this.checked; boxwhiskerChart.refresh(true); }); var boxRotated = document.getElementById('boxRotated'); boxRotated.addEventListener('click', function () { boxwhiskerChart.rotated = this.checked; boxwhiskerChart.refresh(true); }); var boxShowLabel = document.getElementById('boxShowLabel'); boxShowLabel.addEventListener('click', function () { boxwhiskerChart.dataLabel.content = this.checked ? '{y}' : ''; boxwhiskerChart.refresh(true); }); // helper function for Menu headers function updateMenuHeader(menu) { menu.header = menu.text; }

Result (live):

Group Width
Gap Width
Quartile Calculation

ErrorBar

The ErrorBar helps you see margins of error and standard deviations at a glance.

<div id="errorbarChart"></div> <div class="form-horizontal"> <dl class="dl-horizontal"> <dt> <label for="ebRotated">Rotated</label> </dt> <dd> <input id="ebRotated" type="checkbox" /> </dd> </dl> <dl class="dl-horizontal"> <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> </dl> <dl class="dl-horizontal"> <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> </dl> <dl class="dl-horizontal"> <dt>End Style</dt> <dd> <select id="ebEndStyle"> <option value="0" selected="selected">Cap</option> <option value="1">No Cap</option> </select> </dd> </dl> <dl class="dl-horizontal"> <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> </div>
//create chart var errorbarChart = new wijmo.chart.FlexChart('#errorbarChart'), chartType = new wijmo.input.Menu('#ebChartType'), errorAmount = new wijmo.input.Menu('#ebErrorAmount'), endStyle = new wijmo.input.Menu('#ebEndStyle'), direction = new wijmo.input.Menu('#ebDirection'); var countries = 'US,Germany,UK,Japan,Italy,Greece,China,France,Russia'.split(','), appData = []; for (var i = 0; i < countries.length; i++) { appData.push({ country: countries[i], downloads: getData(), sales: getData() }); } function getData() { var val = Math.round(Math.random() * 100); return val > 10 ? val : val + 10; } //create Box & Whisker series errorbarChart.beginUpdate(); errorbarChart.tooltip.content = '{y}'; errorbarChart.itemsSource = appData; errorbarChart.bindingX = 'country'; var errorBar = new wijmo.chart.analytics.ErrorBar(); errorBar.binding = 'downloads'; errorBar.value = 10; errorbarChart.series.push(errorBar); errorbarChart.endUpdate(); var ebRotated = document.getElementById('ebRotated'); ebRotated.addEventListener('click', function () { errorbarChart.rotated = this.checked; errorbarChart.refresh(true); }); updateMenuHeader(chartType); chartType.selectedIndexChanged.addHandler(function () { if (chartType.selectedValue) { var val = +chartType.selectedValue; errorbarChart.chartType = val; updateMenuHeader(chartType); errorbarChart.refresh(true); } }); updateMenuHeader(errorAmount); errorAmount.selectedIndexChanged.addHandler(function () { if (errorAmount.selectedValue) { var val = +errorAmount.selectedValue; errorBar.errorAmount = val; if (val === 0) { errorBar.value = 10; } else if (val === 1) { errorBar.value = 0.1; } else if (val === 2) { errorBar.value = 1; } else if (val === 4) { errorBar.value = { minus: 5, plus: 10 }; } updateMenuHeader(errorAmount); errorbarChart.refresh(true); } }); updateMenuHeader(endStyle); endStyle.selectedIndexChanged.addHandler(function () { if (endStyle.selectedValue) { var val = +endStyle.selectedValue; errorBar.endStyle = val; updateMenuHeader(endStyle); errorbarChart.refresh(true); } }); updateMenuHeader(direction); direction.selectedIndexChanged.addHandler(function () { if (direction.selectedValue) { var val = +direction.selectedValue; errorBar.direction = val; updateMenuHeader(direction); errorbarChart.refresh(true); } }); // helper function for Menu headers function updateMenuHeader(menu) { menu.header = menu.text; }

Result (live):

Chart Type
Error Amount
End Style
Direction