Load desired report from list as default in React Pivot Table

15 Sep 202524 minutes to read

By default, the Pivot Table displays with the report configuration defined in the component initialization. To load a specific report from a previously saved report collection during the initial rendering process, configure the desired report name within the dataBound event. This approach allows the Pivot Table to automatically apply the selected report’s configuration, including field arrangements, filters, and formatting settings, as soon as the component completes its data binding process.

import {
  FieldList, Inject, PivotViewComponent, CalculatedField, Toolbar,
  ConditionalFormatting, NumberFormatting, PDFExport, ExcelExport
} from '@syncfusion/ej2-react-pivotview';
import * as React from 'react';
import{ getInstance, select} from '@syncfusion/ej2-base';
import {DropDownList} from '@syncfusion/ej2-dropdowns';
import { pivotData } from './datasource';

function App() {
  let isInitial = true;

  let dataSourceSettings = {
    dataSource: pivotData,
    columns: [{ name: 'Year' }, { name: 'Quarter' }],
    values: [{ name: 'Sold' }, { name: 'Amount' }],
    rows: [{ name: 'Country' }, { name: 'Products' }],
    formatSettings: [{ name: 'Amount', format: 'C0' }],
  }
  let pivotObj;
  let toolbarOptions = ['New', 'Save', 'SaveAs', 'Rename', 'Remove', 'Load',
    'Grid', 'Chart', 'Export', 'SubTotal', 'GrandTotal', 'ConditionalFormatting', 'NumberFormatting', 'FieldList'];
  function saveReport(args) {
    let reports = [];
    let isSaved = false;
    if (localStorage.pivotviewReports && localStorage.pivotviewReports !== "") {
      reports = JSON.parse(localStorage.pivotviewReports);
    }
    if (args.report && args.reportName && args.reportName !== '' && args.reportName !== 'Sample Report') {
      reports.map(function (item) {
        if (args.reportName === item.reportName) {
          item.report = args.report; isSaved = true;
        }
      });
      if (!isSaved) {
        reports.push(args);
      }
      localStorage.pivotviewReports = JSON.stringify(reports);
    }
  }
  function fetchReport(args) {
    let reportCollection = [];
    let reeportList = [];
    if (localStorage.pivotviewReports && localStorage.pivotviewReports !== "") {
      reportCollection = JSON.parse(localStorage.pivotviewReports);
    }
    reportCollection.map(function (item) { reeportList.push(item.reportName); });
    args.reportName = reeportList;
  }
  function loadReport(args) {
    let reportCollection = [];
    if (localStorage.pivotviewReports && localStorage.pivotviewReports !== "") {
      reportCollection = JSON.parse(localStorage.pivotviewReports);
    }
    reportCollection.map(function (item) {
      if (args.reportName === item.reportName) {
        args.report = item.report;
      }
    });
    if (args.report) {
      pivotObj.dataSourceSettings = JSON.parse(args.report).dataSourceSettings;
    }
  }
  function removeReport(args) {
    let reportCollection= [];
    if (localStorage.pivotviewReports && localStorage.pivotviewReports !== "") {
      reportCollection = JSON.parse(localStorage.pivotviewReports);
    }
    for (let i = 0; i < reportCollection.length; i++) {
      if (reportCollection[i].reportName === args.reportName) {
        reportCollection.splice(i, 1);
      }
    }
    if (localStorage.pivotviewReports && localStorage.pivotviewReports !== "") {
      localStorage.pivotviewReports = JSON.stringify(reportCollection);
    }
  }
  function renameReport(args) {
    let reportCollection= [];
    if (localStorage.pivotviewReports && localStorage.pivotviewReports !== "") {
      reportCollection = JSON.parse(localStorage.pivotviewReports);
    }
    if (args.isReportExists) {
      for (let i = 0; i < reportCollection.length; i++) {
        if (reportCollection[i].reportName === args.rename) {
          reportCollection.splice(i, 1);
        }
      }
    }
    reportCollection.map(function (item) {
      if (args.reportName === item.reportName) {
        item.reportName = args.rename;
      }
    });
    if (localStorage.pivotviewReports && localStorage.pivotviewReports !== "") {
      localStorage.pivotviewReports = JSON.stringify(reportCollection);
    }
  }
  function dataBound() {
    if (pivotObj && isInitial) {
      isInitial = false;
      pivotObj.toolbarModule.action = 'Load';
      /* replace the report name by yours */
      let reportList = getInstance(select('#' + pivotObj.element.id + '_reportlist', pivotObj.element), DropDownList);
      reportList.value = 'Default report';
      loadReport({ reportName: 'Default report' });
    }
  }
  function load(){
    // Save the desired report that needs to be loaded at initial rendering here.
    let dataSourceSettings = {
      dataSource: pivotData,
      columns: [{ name: 'Year' }],
      enableSorting: true,
      allowLabelFilter: true,
      values: [{ name: 'Sold', caption: 'Units Sold' }],
      allowValueFilter: true,
      formatSettings: [{ name: 'Sold', format: 'C0' }],
      rows: [{ name: 'Country' }],
    };
    let displayOption = { view: 'Both' };
    let gridSettings = {columnWidth: 100};
    let report = { dataSourceSettings: dataSourceSettings, displayOption: displayOption, gridSettings: gridSettings };
    let reports = [
      {
        report: JSON.stringify(report),
        reportName: 'Default report',
      },
    ];
  localStorage['pivotviewReports'] = JSON.stringify(reports);
  }
  function newReport() {
    pivotObj.setProperties({ dataSource: { columns: [], rows: [], values: [], filters: [] } }, false);
  }
  function beforeToolbarRender(args) {
    args.customToolbar.splice(6, 0, {
      type: 'Separator'
    });
    args.customToolbar.splice(9, 0, {
      type: 'Separator'
    });
  }

  return (<PivotViewComponent id='PivotView' ref={d => pivotObj = d} dataSourceSettings={dataSourceSettings} width={'100%'}
    height={350} showFieldList={true} gridSettings= allowExcelExport={true}
    allowConditionalFormatting={true} allowNumberFormatting={true} allowPdfExport={true} showToolbar={true}
    allowCalculatedField={true} displayOption= toolbar={toolbarOptions} newReport={newReport.bind(this)}
    renameReport={renameReport.bind(this)} removeReport={removeReport.bind(this)} loadReport={loadReport.bind(this)}
    fetchReport={fetchReport.bind(this)} saveReport={saveReport.bind(this)} toolbarRender={beforeToolbarRender.bind(this)} dataBound={dataBound.bind(this)}
    load={load.bind(this)}>
    <Inject services={[FieldList, CalculatedField, Toolbar, PDFExport, ExcelExport, ConditionalFormatting, NumberFormatting]} />
  </PivotViewComponent>);

};
export default App;
import {
  FieldList, Inject, PivotViewComponent, CalculatedField, Toolbar, RemoveReportArgs, ToolbarArgs,
  ConditionalFormatting, IDataSet, RenameReportArgs, SaveReportArgs, FetchReportArgs,
  LoadReportArgs, NumberFormatting, PDFExport, ExcelExport
} from '@syncfusion/ej2-react-pivotview';
import { DataSourceSettingsModel } from '@syncfusion/ej2-pivotview/src/model/datasourcesettings-model';
import * as React from 'react';
import{ getInstance, select} from '@syncfusion/ej2-base';
import {DropDownList} from '@syncfusion/ej2-dropdowns';
import { pivotData } from './datasource';

function App() {
  let isInitial: boolean = true;

  let dataSourceSettings: DataSourceSettingsModel = {
    dataSource: pivotData as IDataSet[],
    columns: [{ name: 'Year' }, { name: 'Quarter' }],
    values: [{ name: 'Sold' }, { name: 'Amount' }],
    rows: [{ name: 'Country' }, { name: 'Products' }],
    formatSettings: [{ name: 'Amount', format: 'C0' }],
  }
  let pivotObj: PivotViewComponent;
  let toolbarOptions: any = ['New', 'Save', 'SaveAs', 'Rename', 'Remove', 'Load',
    'Grid', 'Chart', 'Export', 'SubTotal', 'GrandTotal', 'ConditionalFormatting', 'NumberFormatting', 'FieldList'];
  function saveReport(args: any): void {
    let reports: SaveReportArgs[] = [];
    let isSaved: boolean = false;
    if (localStorage.pivotviewReports && localStorage.pivotviewReports !== "") {
      reports = JSON.parse(localStorage.pivotviewReports);
    }
    if (args.report && args.reportName && args.reportName !== '' && args.reportName !== 'Sample Report') {
      reports.map(function (item: any): any {
        if (args.reportName === item.reportName) {
          item.report = args.report; isSaved = true;
        }
      });
      if (!isSaved) {
        reports.push(args);
      }
      localStorage.pivotviewReports = JSON.stringify(reports);
    }
  }
  function fetchReport(args: FetchReportArgs): void {
    let reportCollection: string[] = [];
    let reeportList: string[] = [];
    if (localStorage.pivotviewReports && localStorage.pivotviewReports !== "") {
      reportCollection = JSON.parse(localStorage.pivotviewReports);
    }
    reportCollection.map(function (item: any): void { reeportList.push(item.reportName); });
    args.reportName = reeportList;
  }
  function loadReport(args: LoadReportArgs): void {
    let reportCollection: string[] = [];
    if (localStorage.pivotviewReports && localStorage.pivotviewReports !== "") {
      reportCollection = JSON.parse(localStorage.pivotviewReports);
    }
    reportCollection.map(function (item: any): void {
      if (args.reportName === item.reportName) {
        args.report = item.report;
      }
    });
    if (args.report) {
      pivotObj.dataSourceSettings = JSON.parse(args.report).dataSourceSettings;
    }
  }
  function removeReport(args: RemoveReportArgs): void {
    let reportCollection: any[] = [];
    if (localStorage.pivotviewReports && localStorage.pivotviewReports !== "") {
      reportCollection = JSON.parse(localStorage.pivotviewReports);
    }
    for (let i: number = 0; i < reportCollection.length; i++) {
      if (reportCollection[i].reportName === args.reportName) {
        reportCollection.splice(i, 1);
      }
    }
    if (localStorage.pivotviewReports && localStorage.pivotviewReports !== "") {
      localStorage.pivotviewReports = JSON.stringify(reportCollection);
    }
  }
  function renameReport(args: RenameReportArgs): void {
    let reportCollection: any[] = [];
    if (localStorage.pivotviewReports && localStorage.pivotviewReports !== "") {
      reportCollection = JSON.parse(localStorage.pivotviewReports);
    }
    if (args.isReportExists) {
      for (let i: number = 0; i < reportCollection.length; i++) {
        if (reportCollection[i].reportName === args.rename) {
          reportCollection.splice(i, 1);
        }
      }
    }
    reportCollection.map(function (item: any): any {
      if (args.reportName === item.reportName) {
        item.reportName = args.rename;
      }
    });
    if (localStorage.pivotviewReports && localStorage.pivotviewReports !== "") {
      localStorage.pivotviewReports = JSON.stringify(reportCollection);
    }
  }
  function dataBound(): void {
    if (pivotObj && isInitial) {
      isInitial = false;
      pivotObj.toolbarModule.action = 'Load';
      /* replace the report name by yours */
      let reportList = getInstance(select('#' + pivotObj.element.id + '_reportlist', pivotObj.element), DropDownList);
      (reportList as DropDownList).value = 'Default report';
      loadReport({ reportName: 'Default report' });
    }
  }
  function load(): void{
    // Save the desired report that needs to be loaded at initial rendering here.
    let dataSourceSettings = {
      dataSource: pivotData as IDataSet[],
      columns: [{ name: 'Year' }],
      enableSorting: true,
      allowLabelFilter: true,
      values: [{ name: 'Sold', caption: 'Units Sold' }],
      allowValueFilter: true,
      formatSettings: [{ name: 'Sold', format: 'C0' }],
      rows: [{ name: 'Country' }],
    };
    let displayOption = { view: 'Both' };
    let gridSettings = {columnWidth: 100};
    let report = { dataSourceSettings: dataSourceSettings, displayOption: displayOption, gridSettings: gridSettings };
    let reports = [
      {
        report: JSON.stringify(report),
        reportName: 'Default report',
      },
    ];
    localStorage['pivotviewReports'] = JSON.stringify(reports);
  }
  function newReport(): void {
    pivotObj.setProperties({ dataSource: { columns: [], rows: [], values: [], filters: [] } }, false);
  }
  function beforeToolbarRender(args: any): void {
    args.customToolbar.splice(6, 0, {
      type: 'Separator'
    });
    args.customToolbar.splice(9, 0, {
      type: 'Separator'
    });
  }

  return (<PivotViewComponent id='PivotView' ref={ (d: PivotViewComponent) => pivotObj = d } dataSourceSettings={dataSourceSettings} width={'100%'}
    height={350} showFieldList={true} gridSettings= allowExcelExport={true}
    allowConditionalFormatting={true} allowNumberFormatting={true} allowPdfExport={true} showToolbar={true}
    allowCalculatedField={true} displayOption= toolbar={toolbarOptions} newReport={newReport.bind(this)}
    renameReport={renameReport.bind(this)} removeReport={removeReport.bind(this)} loadReport={loadReport.bind(this)}
    fetchReport={fetchReport.bind(this)} saveReport={saveReport.bind(this)} toolbarRender={beforeToolbarRender.bind(this)} dataBound={dataBound.bind(this)}
    load={load.bind(this)}>
    <Inject services={[FieldList, CalculatedField, Toolbar, PDFExport, ExcelExport, ConditionalFormatting, NumberFormatting]} />
  </PivotViewComponent>);

};
export default App;
export let pivotData = [
    { 'In_Stock': 34, 'Sold': 51, 'Amount': 383, 'Country': 'France', 'Product_Categories': 'Accessories', 'Products': 'Bottles and Cages', 'Order_Source': 'Retail Outlets', 'Year': 'FY 2015', 'Quarter': 'Q1' },
    { 'In_Stock': 4, 'Sold': 423, 'Amount': 3595.5, 'Country': 'France', 'Product_Categories': 'Accessories', 'Products': 'Cleaners', 'Order_Source': 'Sales Person', 'Year': 'FY 2016', 'Quarter': 'Q1' },
    { 'In_Stock': 11, 'Sold': 19, 'Amount': 85.5, 'Country': 'France', 'Product_Categories': 'Bikes', 'Products': 'Touring Bikes', 'Order_Source': 'Retail Outlets', 'Year': 'FY 2017', 'Quarter': 'Q4' },
    { 'In_Stock': 10, 'Sold': 64, 'Amount': 320, 'Country': 'France', 'Product_Categories': 'Bikes', 'Products': 'Mountain Bikes', 'Order_Source': 'Sales Person', 'Year': 'FY 2018', 'Quarter': 'Q4' },
    { 'In_Stock': 2, 'Sold': 141, 'Amount': 1692, 'Country': 'France', 'Product_Categories': 'Clothing', 'Products': 'Jerseys', 'Order_Source': 'Sales Person', 'Year': 'FY 2015', 'Quarter': 'Q1' },
    { 'In_Stock': 30, 'Sold': 332, 'Amount': 3735, 'Country': 'France', 'Product_Categories': 'Clothing', 'Products': 'Shorts', 'Order_Source': 'Teleshopping', 'Year': 'FY 2016', 'Quarter': 'Q1' },
    { 'In_Stock': 9, 'Sold': 353, 'Amount': 3000.5, 'Country': 'Germany', 'Product_Categories': 'Clothing', 'Products': 'Vests', 'Order_Source': 'Sales Person', 'Year': 'FY 2015', 'Quarter': 'Q1' },
    { 'In_Stock': 32, 'Sold': 269, 'Amount': 1345, 'Country': 'Germany', 'Product_Categories': 'Accessories', 'Products': 'Helmets', 'Order_Source': 'Sales Person', 'Year': 'FY 2016', 'Quarter': 'Q1' },
    { 'In_Stock': 31, 'Sold': 73, 'Amount': 1387, 'Country': 'Germany', 'Product_Categories': 'Accessories', 'Products': 'Tires and Tubes', 'Order_Source': 'App Store', 'Year': 'FY 2017', 'Quarter': 'Q1' },
    { 'In_Stock': 19, 'Sold': 279, 'Amount': 205363, 'Country': 'Germany', 'Product_Categories': 'Bikes', 'Products': 'Road Bikes', 'Order_Source': 'App Store', 'Year': 'FY 2018', 'Quarter': 'Q1' },
    { 'In_Stock': 41, 'Sold': 82, 'Amount': 922.5, 'Country': 'Germany', 'Product_Categories': 'Bikes', 'Products': 'Mountain Bikes', 'Order_Source': 'Teleshopping', 'Year': 'FY 2017', 'Quarter': 'Q1' },
    { 'In_Stock': 15, 'Sold': 188, 'Amount': 1457, 'Country': 'Germany', 'Product_Categories': 'Accessories', 'Products': 'Bottles and Cages', 'Order_Source': 'Teleshopping', 'Year': 'FY 2018', 'Quarter': 'Q1' },
    { 'In_Stock': 31, 'Sold': 78, 'Amount': 1677, 'Country': 'United Kingdom', 'Product_Categories': 'Accessories', 'Products': 'Bottles and Cages', 'Order_Source': 'Retail Outlets', 'Year': 'FY 2015', 'Quarter': 'Q3' },
    { 'In_Stock': 46, 'Sold': 393, 'Amount': 6681, 'Country': 'United Kingdom', 'Product_Categories': 'Bikes', 'Products': 'Mountain Bikes', 'Order_Source': 'Sales Person', 'Year': 'FY 2016', 'Quarter': 'Q3' },
    { 'In_Stock': 35, 'Sold': 61, 'Amount': 991.25, 'Country': 'United Kingdom', 'Product_Categories': 'Accessories', 'Products': 'Fenders', 'Order_Source': 'Teleshopping', 'Year': 'FY 2017', 'Quarter': 'Q1' },
    { 'In_Stock': 34, 'Sold': 271, 'Amount': 4336, 'Country': 'United Kingdom', 'Product_Categories': 'Bikes', 'Products': 'Touring Bikes', 'Order_Source': 'App Store', 'Year': 'FY 2018', 'Quarter': 'Q1' },
    { 'In_Stock': 48, 'Sold': 361, 'Amount': 10469, 'Country': 'United Kingdom', 'Product_Categories': 'Clothing', 'Products': 'Shorts', 'Order_Source': 'Sales Person', 'Year': 'FY 2015', 'Quarter': 'Q1' },
    { 'In_Stock': 20, 'Sold': 464, 'Amount': 13108, 'Country': 'United Kingdom', 'Product_Categories': 'Clothing', 'Products': 'Jerseys', 'Order_Source': 'Teleshopping', 'Year': 'FY 2017', 'Quarter': 'Q1' },
    { 'In_Stock': 45, 'Sold': 257, 'Amount': 28784, 'Country': 'United States', 'Product_Categories': 'Clothing', 'Products': 'Vests', 'Order_Source': 'Sales Person', 'Year': 'FY 2015', 'Quarter': 'Q4' },
    { 'In_Stock': 5, 'Sold': 333, 'Amount': 2081.25, 'Country': 'United States', 'Product_Categories': 'Clothing', 'Products': 'Gloves', 'Order_Source': 'Teleshopping', 'Year': 'FY 2016', 'Quarter': 'Q4' },
    { 'In_Stock': 47, 'Sold': 252, 'Amount': 401940, 'Country': 'United Kingdom', 'Product_Categories': 'Accessories', 'Products': 'Helmets', 'Order_Source': 'App Store', 'Year': 'FY 2018', 'Quarter': 'Q1' },
    { 'In_Stock': 38, 'Sold': 287, 'Amount': 457765, 'Country': 'United Kingdom', 'Product_Categories': 'Accessories', 'Products': 'Fenders', 'Order_Source': 'App Store', 'Year': 'FY 2016', 'Quarter': 'Q3' },
    { 'In_Stock': 29, 'Sold': 92, 'Amount': 146786, 'Country': 'United States', 'Product_Categories': 'Bikes', 'Products': 'Touring Bikes', 'Order_Source': 'Retail Outlets', 'Year': 'FY 2018', 'Quarter': 'Q3' },
    { 'In_Stock': 14, 'Sold': 535, 'Amount': 10165, 'Country': 'United States', 'Product_Categories': 'Bikes', 'Products': 'Mountain Bikes', 'Order_Source': 'App Store', 'Year': 'FY 2017', 'Quarter': 'Q4' },
    { 'In_Stock': 47, 'Sold': 405, 'Amount': 3037.5, 'Country': 'United States', 'Product_Categories': 'Accessories', 'Products': 'Bottles and Cages', 'Order_Source': 'App Store', 'Year': 'FY 2017', 'Quarter': 'Q4' },
];
export let pivotData: object[] = [
    { 'In_Stock': 34, 'Sold': 51, 'Amount': 383, 'Country': 'France', 'Product_Categories': 'Accessories', 'Products': 'Bottles and Cages', 'Order_Source': 'Retail Outlets', 'Year': 'FY 2015', 'Quarter': 'Q1' },
    { 'In_Stock': 4, 'Sold': 423, 'Amount': 3595.5, 'Country': 'France', 'Product_Categories': 'Accessories', 'Products': 'Cleaners', 'Order_Source': 'Sales Person', 'Year': 'FY 2016', 'Quarter': 'Q1' },
    { 'In_Stock': 11, 'Sold': 19, 'Amount': 85.5, 'Country': 'France', 'Product_Categories': 'Bikes', 'Products': 'Touring Bikes', 'Order_Source': 'Retail Outlets', 'Year': 'FY 2017', 'Quarter': 'Q4' },
    { 'In_Stock': 10, 'Sold': 64, 'Amount': 320, 'Country': 'France', 'Product_Categories': 'Bikes', 'Products': 'Mountain Bikes', 'Order_Source': 'Sales Person', 'Year': 'FY 2018', 'Quarter': 'Q4' },
    { 'In_Stock': 2, 'Sold': 141, 'Amount': 1692, 'Country': 'France', 'Product_Categories': 'Clothing', 'Products': 'Jerseys', 'Order_Source': 'Sales Person', 'Year': 'FY 2015', 'Quarter': 'Q1' },
    { 'In_Stock': 30, 'Sold': 332, 'Amount': 3735, 'Country': 'France', 'Product_Categories': 'Clothing', 'Products': 'Shorts', 'Order_Source': 'Teleshopping', 'Year': 'FY 2016', 'Quarter': 'Q1' },
    { 'In_Stock': 9, 'Sold': 353, 'Amount': 3000.5, 'Country': 'Germany', 'Product_Categories': 'Clothing', 'Products': 'Vests', 'Order_Source': 'Sales Person', 'Year': 'FY 2015', 'Quarter': 'Q1' },
    { 'In_Stock': 32, 'Sold': 269, 'Amount': 1345, 'Country': 'Germany', 'Product_Categories': 'Accessories', 'Products': 'Helmets', 'Order_Source': 'Sales Person', 'Year': 'FY 2016', 'Quarter': 'Q1' },
    { 'In_Stock': 31, 'Sold': 73, 'Amount': 1387, 'Country': 'Germany', 'Product_Categories': 'Accessories', 'Products': 'Tires and Tubes', 'Order_Source': 'App Store', 'Year': 'FY 2017', 'Quarter': 'Q1' },
    { 'In_Stock': 19, 'Sold': 279, 'Amount': 205363, 'Country': 'Germany', 'Product_Categories': 'Bikes', 'Products': 'Road Bikes', 'Order_Source': 'App Store', 'Year': 'FY 2018', 'Quarter': 'Q1' },
    { 'In_Stock': 41, 'Sold': 82, 'Amount': 922.5, 'Country': 'Germany', 'Product_Categories': 'Bikes', 'Products': 'Mountain Bikes', 'Order_Source': 'Teleshopping', 'Year': 'FY 2017', 'Quarter': 'Q1' },
    { 'In_Stock': 15, 'Sold': 188, 'Amount': 1457, 'Country': 'Germany', 'Product_Categories': 'Accessories', 'Products': 'Bottles and Cages', 'Order_Source': 'Teleshopping', 'Year': 'FY 2018', 'Quarter': 'Q1' },
    { 'In_Stock': 31, 'Sold': 78, 'Amount': 1677, 'Country': 'United Kingdom', 'Product_Categories': 'Accessories', 'Products': 'Bottles and Cages', 'Order_Source': 'Retail Outlets', 'Year': 'FY 2015', 'Quarter': 'Q3' },
    { 'In_Stock': 46, 'Sold': 393, 'Amount': 6681, 'Country': 'United Kingdom', 'Product_Categories': 'Bikes', 'Products': 'Mountain Bikes', 'Order_Source': 'Sales Person', 'Year': 'FY 2016', 'Quarter': 'Q3' },
    { 'In_Stock': 35, 'Sold': 61, 'Amount': 991.25, 'Country': 'United Kingdom', 'Product_Categories': 'Accessories', 'Products': 'Fenders', 'Order_Source': 'Teleshopping', 'Year': 'FY 2017', 'Quarter': 'Q1' },
    { 'In_Stock': 34, 'Sold': 271, 'Amount': 4336, 'Country': 'United Kingdom', 'Product_Categories': 'Bikes', 'Products': 'Touring Bikes', 'Order_Source': 'App Store', 'Year': 'FY 2018', 'Quarter': 'Q1' },
    { 'In_Stock': 48, 'Sold': 361, 'Amount': 10469, 'Country': 'United Kingdom', 'Product_Categories': 'Clothing', 'Products': 'Shorts', 'Order_Source': 'Sales Person', 'Year': 'FY 2015', 'Quarter': 'Q1' },
    { 'In_Stock': 20, 'Sold': 464, 'Amount': 13108, 'Country': 'United Kingdom', 'Product_Categories': 'Clothing', 'Products': 'Jerseys', 'Order_Source': 'Teleshopping', 'Year': 'FY 2017', 'Quarter': 'Q1' },
    { 'In_Stock': 45, 'Sold': 257, 'Amount': 28784, 'Country': 'United States', 'Product_Categories': 'Clothing', 'Products': 'Vests', 'Order_Source': 'Sales Person', 'Year': 'FY 2015', 'Quarter': 'Q4' },
    { 'In_Stock': 5, 'Sold': 333, 'Amount': 2081.25, 'Country': 'United States', 'Product_Categories': 'Clothing', 'Products': 'Gloves', 'Order_Source': 'Teleshopping', 'Year': 'FY 2016', 'Quarter': 'Q4' },
    { 'In_Stock': 47, 'Sold': 252, 'Amount': 401940, 'Country': 'United Kingdom', 'Product_Categories': 'Accessories', 'Products': 'Helmets', 'Order_Source': 'App Store', 'Year': 'FY 2018', 'Quarter': 'Q1' },
    { 'In_Stock': 38, 'Sold': 287, 'Amount': 457765, 'Country': 'United Kingdom', 'Product_Categories': 'Accessories', 'Products': 'Fenders', 'Order_Source': 'App Store', 'Year': 'FY 2016', 'Quarter': 'Q3' },
    { 'In_Stock': 29, 'Sold': 92, 'Amount': 146786, 'Country': 'United States', 'Product_Categories': 'Bikes', 'Products': 'Touring Bikes', 'Order_Source': 'Retail Outlets', 'Year': 'FY 2018', 'Quarter': 'Q3' },
    { 'In_Stock': 14, 'Sold': 535, 'Amount': 10165, 'Country': 'United States', 'Product_Categories': 'Bikes', 'Products': 'Mountain Bikes', 'Order_Source': 'App Store', 'Year': 'FY 2017', 'Quarter': 'Q4' },
    { 'In_Stock': 47, 'Sold': 405, 'Amount': 3037.5, 'Country': 'United States', 'Product_Categories': 'Accessories', 'Products': 'Bottles and Cages', 'Order_Source': 'App Store', 'Year': 'FY 2017', 'Quarter': 'Q4' },
];