Error Bars

Error bars allow you to quickly display margins of error and standard deviations in your charts.

The demo is being dynamically compiled to support real-time code editing... For quicker access to features, switch to the "JavaScript" tab for a smoother experience! :)
Description
app.vue
index.html
Copy to CodeMine

When using charts to display data, it can be useful to display margins of error for each point. Showing a positive or negative error amount in the results of a scientific experiment can show the variability of the results at a glance.

The error type (error amount) can be set with the following:

  • Fixed Value - set error bar with a fixed value.
  • Percentage - set error bar with a percentage of the data value in the same direction axis.
  • Standard deviation - set error bar with a calculating value which depends on the set deviation and chart data value.
  • Standard error - set error bar with a calculating value which only depends on the chart data value.
  • Custom - set error bar with positive and negative values represented by formulas or fixed numbers.

This feature supports the following chart types:

  • Column
  • Line
  • Bar
  • Area
  • Scatter
  • Bubble

Customize

type: Specify the visibility of negative error bar and positive error bar.

noEndCap: Specify the visibility of the error bar caps.

style: Specify the line style of the error bar including color, width, and dash line.

You can customize the error bars using the following code:

    var series = chart.series().get(0);
    series.errorBars = {
        horizontal: {
            type: GC.Spread.Sheets.Charts.ErrorBarType.both,
            valueType: GC.Spread.Sheets.Charts.ErrorBarValueType.fixedValue,
            value: 0.4, // error bar value
            noEndCap: true,
            style: {
                width: 4, // line width
                dashStyle: GC.Spread.Sheets.Charts.LineDashStyle.dash
            }
        },
        vertical: {
            type: GC.Spread.Sheets.Charts.ErrorBarType.minus,
            valueType: GC.Spread.Sheets.Charts.ErrorBarValueType.percentage,
            value: 90, // 90%
            style: {
                color: 'red' // line color
            }
        }
    };
    chart.series().set(0, series);
When using charts to display data, it can be useful to display margins of error for each point. Showing a positive or negative error amount in the results of a scientific experiment can show the variability of the results at a glance. The error type (error amount) can be set with the following: Fixed Value - set error bar with a fixed value. Percentage - set error bar with a percentage of the data value in the same direction axis. Standard deviation - set error bar with a calculating value which depends on the set deviation and chart data value. Standard error - set error bar with a calculating value which only depends on the chart data value. Custom - set error bar with positive and negative values represented by formulas or fixed numbers. This feature supports the following chart types: Column Line Bar Area Scatter Bubble Customize type: Specify the visibility of negative error bar and positive error bar. noEndCap: Specify the visibility of the error bar caps. style: Specify the line style of the error bar including color, width, and dash line. You can customize the error bars using the following code:
<template> <div class="sample-tutorial"> <gc-spread-sheets class="sample-spreadsheets" @workbookInitialized="initSpread"> <gc-worksheet /> <gc-worksheet /> <gc-worksheet /> </gc-spread-sheets> </div> </template> <script setup> import { ref } from 'vue'; import '@mescius/spread-sheets-vue'; import GC from '@mescius/spread-sheets'; import '@mescius/spread-sheets-shapes'; import '@mescius/spread-sheets-charts'; const spreadRef = ref(null); const COLORS = { deepBlue: '#3e619f', blue: '#a1b8e1', deepOrange: '#c55a11', orange: '#f6be98', white: '#ffffff' }; function initSpread(spread) { spreadRef.value = spread; addBasicChart(spread.getSheet(0)); addStepChart(spread.getSheet(1)); addGanttChart(spread.getSheet(2)); } function addBasicChart(sheet) { sheet.name("BaseUsage"); let salesData = [ ['', 'Sales'], ['Jan', 54], ['Feb', 60], ['Mar', 86], ['Apr', 92], ['May', 112], ['Jun', 157], ['Jul', 202], ['Aug', 195], ['Sep', 187], ['Oct', 194], ['Nov', 238], ['Dec', 289], ]; sheet.setArray(0, 0, salesData); let chart1 = sheet.charts.add("chart1", GC.Spread.Sheets.Charts.ChartType.xyScatterSmooth, 140, 5, 500, 350, "A1:B13", GC.Spread.Sheets.Charts.RowCol.columns); let series = chart1.series().get(0); series.errorBars = { vertical: { type: GC.Spread.Sheets.Charts.ErrorBarType.both, valueType: GC.Spread.Sheets.Charts.ErrorBarValueType.standardError, style: { color: COLORS.deepOrange } } }; chart1.series().set(0, series); } function addStepChart(sheet) { sheet.name("StepChart"); let priceData = [ ['', 'Price', 'x-error', 'y-error-negative', 'y-error-positive'], [new Date('5/7/2019'), 39], [new Date('5/27/2019'), 47], [new Date('6/15/2019'), 30], [new Date('6/24/2019'), 46], [new Date('8/3/2019'), 37], [new Date('8/28/2019'), 50], [new Date('9/29/2019'), 43], [new Date('10/30/2019'), 48], ]; sheet.setArray(0, 0, priceData); sheet.setFormula(1, 2, "=IF(A3, A3-A2, 20)"); sheet.setFormula(1, 3, "=IFERROR(IF(B1-B2>0, B1-B2, 0), 0)"); sheet.setFormula(1, 4, "=IFERROR(IF(B2-B1>0, B2-B1, 0), 0)"); sheet.fillAuto(new GC.Spread.Sheets.Range(1, 2, 1, 3), new GC.Spread.Sheets.Range(1, 2, 8, 3), { direction: GC.Spread.Sheets.Fill.FillDirection.down, fillType: GC.Spread.Sheets.Fill.FillType.auto }); sheet.getRange(1, 1, 8, 1).formatter('_($* #,##0.00_);_($* (#,##0.00);_($* "-"??_);_(@_)'); sheet.setColumnWidth(0, 100); let chart = sheet.charts.add("StepChart", GC.Spread.Sheets.Charts.ChartType.xyScatter, 160, 5, 800, 450, "A1:B9", GC.Spread.Sheets.Charts.RowCol.columns); let axes = chart.axes(); axes.primaryCategory.format = 'm/d/yyyy'; axes.primaryCategory.majorTickPosition = GC.Spread.Sheets.Charts.TickMark.outside; chart.axes(axes); chart.legend({ visible: false }); let series = chart.series().get(0); series.symbol = { fill: null, border: { color: null } }; // Hide the symbol. series.errorBars = { horizontal: { type: GC.Spread.Sheets.Charts.ErrorBarType.plus, valueType: GC.Spread.Sheets.Charts.ErrorBarValueType.custom, noEndCap: true, custom: { positive: '=StepChart!$C$2:$C$9' } }, vertical: { valueType: GC.Spread.Sheets.Charts.ErrorBarValueType.custom, noEndCap: true, custom: { positive: '=StepChart!$D$2:$D$9', negative: '=StepChart!$E$2:$E$9' }, style: { color: "gray", dashStyle: GC.Spread.Sheets.Charts.LineDashStyle.dash } } }; chart.series().set(0, series); let dataLabels = chart.dataLabels(); dataLabels.showValue = true; dataLabels.position = GC.Spread.Sheets.Charts.DataLabelPosition.above; dataLabels.format = '$* #,##0.00'; dataLabels.color = "red"; chart.dataLabels(dataLabels); } function addGanttChart(sheet) { let self = this; sheet.name("GanttChart"); let ganttData = [ ['End Date', 'Height'], [new Date('4/15/2019'), 0.9375], [new Date('4/29/2019'), 0.8125], [new Date('5/6/2019'), 0.6875], [new Date('5/20/2019'), 0.5625], [new Date('5/27/2019'), 0.4375], [new Date('6/17/2019'), 0.3125], [new Date('6/24/2019'), 0.1875], [new Date('7/1/2019'), 0.0625] ]; sheet.setArray(0, 0, ganttData); sheet.setColumnWidth(0, 100); let SIZE = 12; let ZFACTOR = 25; let chart = sheet.charts.add("GanttChart", GC.Spread.Sheets.Charts.ChartType.xyScatter, 180, 5, 500, 350, "A1:B9", GC.Spread.Sheets.Charts.RowCol.columns); chart.title({ text: 'Advanced Gantt Chart' }); let axes = chart.axes(); axes.primaryCategory.format = 'm/d/yyyy'; axes.primaryCategory.majorTickPosition = GC.Spread.Sheets.Charts.TickMark.outside; axes.primaryValue.visible = false; chart.axes(axes); chart.legend({ visible: false }); let backgroundSeriesIndex = 0; let backgroundSeries = chart.series().get(backgroundSeriesIndex); let backgroundErrorBar = { type: GC.Spread.Sheets.Charts.ErrorBarType.minus, valueType: GC.Spread.Sheets.Charts.ErrorBarValueType.custom, noEndCap: true, custom: { negative: '={' + ZFACTOR + '}' }, style: { color: COLORS.blue, width: SIZE } }; backgroundSeries.errorBars = { horizontal: backgroundErrorBar }; backgroundSeries.symbol = { shape: GC.Spread.Sheets.Charts.SymbolShape.diamond, size: SIZE, fill: COLORS.deepBlue }; chart.series().set(backgroundSeriesIndex, backgroundSeries); let unfinishedSeries = { chartType: GC.Spread.Sheets.Charts.ChartType.xyScatter, axisGroup: GC.Spread.Sheets.Charts.AxisGroup.primary, xValues: 'GanttChart!$A$2:$A$9', yValues: 'GanttChart!$B$2:$B$9', symbol: { shape: GC.Spread.Sheets.Charts.SymbolShape.diamond, size: SIZE - 4, fill: COLORS.deepOrange }, errorBars: { horizontal: { type: GC.Spread.Sheets.Charts.ErrorBarType.minus, valueType: GC.Spread.Sheets.Charts.ErrorBarValueType.custom, noEndCap: true, custom: { negative: '={' + createErrorBarValue(ganttData.slice(1), ZFACTOR).toString() + '}' }, style: { color: COLORS.orange, width: SIZE } } } }; chart.series().add(unfinishedSeries); let dataLabels = chart.dataLabels(); dataLabels.showValue = true; dataLabels.position = GC.Spread.Sheets.Charts.DataLabelPosition.below; dataLabels.format = '#,##0%'; dataLabels.color = COLORS.orange; chart.dataLabels(dataLabels); } function createErrorBarValue(dataSource, z) { let values = []; for (let i = 0; i < dataSource.length; i++) { values.push(dataSource[i][1] * z); } return values; } </script> <style scoped> .sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-spreadsheets { width: 100%; height: 100%; overflow: hidden; float: left; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } #app { height: 100%; } </style>
<!DOCTYPE html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title>SpreadJS VUE</title> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/vue3/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/en/vue3/node_modules/systemjs/dist/system.src.js"></script> <script src="./systemjs.config.js"></script> <script src="./compiler.js" type="module"></script> <script> var System = SystemJS; System.import("./src/app.js"); System.import('$DEMOROOT$/en/lib/vue3/license.js'); </script> </head> <body> <div id="app"></div> </body> </html>
(function (global) { SystemJS.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, packageConfigPaths: [ './node_modules/*/package.json', "./node_modules/@mescius/*/package.json", "./node_modules/@babel/*/package.json", "./node_modules/@vue/*/package.json" ], map: { 'vue': "npm:vue/dist/vue.esm-browser.js", 'tiny-emitter': 'npm:tiny-emitter/index.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', "systemjs-babel-build": "npm:systemjs-plugin-babel/systemjs-babel-browser.js", '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-resources-en': 'npm:@mescius/spread-sheets-resources-en/index.js', '@mescius/spread-sheets-vue': 'npm:@mescius/spread-sheets-vue/index.js', '@mescius/spread-sheets-shapes': 'npm:@mescius/spread-sheets-shapes/index.js', '@mescius/spread-sheets-charts': 'npm:@mescius/spread-sheets-charts/index.js', }, meta: { '*.css': { loader: 'systemjs-plugin-css' }, '*.vue': { loader: "../plugin-vue/index.js" } } }); })(this);