This site uses cookies for analytics, personalized content and ads. By continuing to browse this site, you agree to this use. Learn more
Microsoft
Dynamics 365 Community
  • Home
    • Home
      • Sales
      • Customer Service
      • Field Service
      • Talent
      • Finance and Operations
      • Retail
      • Project Service Automation
      • Marketing
        • AI for Sales
        • AI for Customer Service
        • AI for Market Insights
        • Remote Assist
        • Layout
      • Business Central
      • General
      • Microsoft Dynamics CRM
      • Microsoft Dynamics AX
      • Microsoft Dynamics NAV
      • Microsoft Dynamics GP
      • Microsoft Dynamics SL
      • Other Products
  • NAV Forum
  • Ideas
    • Community Events
    • Partner Events
    • Learning Resources
    • Documentation
    • Community Gallery
    • NAV Blogs
    • Webinars
    • Design Patterns Wiki
  • User Groups
    • Community News
    • Get Started
    • Introduce Yourself
      • Earn Badges
      • View Badges
      • Compete on Leaderboards
      • View Leaderboards
    • Become a Top Contributor
    • Request a New Blog
    • Provide Feedback
    • Access personal data
      • Power BI Community
      • Flow Community
      • PowerApps Community
      • Microsoft Tech Community
      • Microsoft 365
      • Azure
      • Office 365
      • Dynamics 365
      • SQL
      • Windows 10
      • Windows Server
      • Enterprise Mobility + Security
      • Power BI
      • Teams
      • Visual Studio
      • Microsoft Advertising
      • AI
      • Internet of Things
      • Azure Cognitive Services
      • Quantum
      • Microsoft HoloLens
      • Mixed Reality
      • Docs
      • TechNet
      • Developer Network
      • Windows Dev Center
      • Windows IT Pro Center
      • FastTrack
      • Partner Network
      • Solution Providers
      • Partner Center
      • Cloud Hosting
      • Education
      • Financial services
      • Government
      • Health
      • Manufacturing & resources
      • Retail
      • Security
      • Licensing
      • AppSource
      • Azure Marketplace
      • Events
      • Research
    • View Sitemap
    Sign in


    Wiki Hero Banner

    Creating Custom Charts

    1. Home
    2. Microsoft Dynamics NAV
    3. Design Patterns
    4. Creating Custom Charts

    Options

    • Sign In
    • Rate:

    by Nikola Kukrika at Microsoft Development Center Copenhagen

    Abstract

    The goal of this solution is to enable you to:

    1. Use charts in the web client.
    2. Create charts with custom functionality.

    Description

    This pattern enables you to implement a business chart (Specific Chart type) in a way that is maintainable and reusable on other pages. This also enables you to provide specific functionality that is not possible with the Generic Chart type and it enables you to show charts in the web client.

    The Business Chart add-in is a special because it is a combination of .NET and Javascript add-ins depending on the display target. In the web client, it renders a JavaScript control, while in the win client, it renders a .Net control. Because of this behavior, you can expect minor differences in how the chart is presented in the win client versus in the web client. Note that this implementation is specific to NAV platform code, because it is not possible to create add-ins that combines .NET and JavaScript by using a framework API.

      

    Example of the same chart in the win client:

    The most obvious differences in chart rendering in the two clients are: Slightly different line heights, slightly different chart height, legends in web-client charts can be used as toggle filters to show/hide groups (this is not possible in the win client).

    Implementation Overview

    Add-in Buffer Table

    This table is used to encapsulate the logic of the Business Chart Add-in. The table handles the following logic:

    • Storing chart values and conversion from .NET to C/AL and vice versa
    • Handling of captions: We must use C/AL to provide multilanguage text in add-ins. In addition, the multilanguage text must be encapsulated in a single place, because we pass/read the same dataset from/to the add-in.
    • DrillDown logic
    • Other helper data related functions, for displaying date, periods, etc.[Bogdana1] [NK2] [NK3] 

     

    Note: It is recommended that you reuse the Business Chart Buffer table (485) as a buffer table or extend. It is a generic table which should cover most of the use cases. Implement a new buffer table only if this table does not meet your needs.

    CardPart page

    The CardPart page hosts the Business Chart add-in and must use the add-in buffer table as a source table.

    On the page, you must implement the following triggers:

    • AddInReady – Executed when the page is done rendering. Used to initialize the add-in.
    • DataPointClicked – Single-click on an element on the chart.
    • DataPointDoubleClicked – Double-click on an element on the chart

    The CardPart usually contains a StatusText variable to provide more information about the chart or dataset and a set of actions to control the chart.

    The most commonly used actions are:

    • Select Chart, Previous Chart, Next Chart
    • Set Period, Work Date
    • Actions to filter the data set
    • Refresh
    • Chart Information – a tooltip with a description of the chart and how data is calculated.

    Optional: Preserving User Personalization

    One of the most common functionalities is personalization. If the chart can be customized by the user, you should store the settings that the user has entered and apply them the next time the chart is loaded.

    To do this, you need the following:

    • A setup record to store the data. You can use the Business Chart User Setup table (487) or create a new setup table if you need to store more information.
    • A management codeunit to write/apply the settings to the chart and to encapsulate other logic. Since we should not write code on pages, the code for the actions and other logic that does not apply to the setup record should go in this codeunit.
    • Setup pages where users can customize how the chart is shown and set different settings.

    The relation between the components is visualized in the following diagram[

    Optional: Show Multiple Charts within a Single CardPart

    This option is useful on a Role Center where you want to show multiple charts using different datasets within a single part. In that case, you need a record to store the last chart selection, the setup records, and code units for separate charts.

    See, for example, the implementation of the Mini Generic Chart page (1390), which uses MiniChartManagment CodeUnit to manage separate management codeunits for charts and their setup records. The last selected chart is stored in a separate table, Mini Chart Definition (1310). 

    Usage

    To implement the pattern, create a new ChartPart and set the source table to Business Chart Buffer. 

    Add a field named BusinessChart and set the ControlAddIn property to Microsoft.Dynamics.Nav.Client.BusinessChart. 

    Then implement the AddInReady event. This event is executed when the page is done rendering. Code within this method must call the Update method from the Business Chart Buffer table, Update(CurrPage.BusinessChart) to initialize the chart and assign initial values. 

    If you need a setup record and codeunit, then it is a good idea to encapsulate this logic within a method.

     

    NAV Specific Example 1

    Implementation of the Finance Performance Chart page (762)

    BusinessChart::AddInReady()

    UpdateChart(Period::" ");

     

    LOCAL UpdateChart(Period : ',Next,Previous')

    MoveAndUpdateChart(Period,0);

     

    LOCAL MoveAndUpdateChart(Period : ',Next,Previous';Move : Integer)

    AccSchedChartManagement.GetSetupRecordset(AccountSchedulesChartSetup,AccountSchedulesChartSetup.Name,Move);

    AccSchedChartManagement.UpdateData(Rec,Period,AccountSchedulesChartSetup);

    Update(CurrPage.BusinessChart);

    StatusText := GetCurrentSelectionText("Period Filter Start Date","Period Filter End Date");

    In the MoveAndUpdateChart method, the AccSchedChartManagement codeunit gets a setup record and updates it if necessary. Then, it initializes the chart with setup data and sets the StatusText to show the period for which data is displayed. The same method is used by the actions to move and update the chart so that there is no code duplication.

    The following code is used to implement DataPointClicked

     BusinessChart::DataPointClicked(point : DotNet "Microsoft.Dynamics.Nav.Client.BusinessChart.BusinessChartDataPoint")

    SetDrillDownIndexes(point);

    AccSchedChartManagement.DrillDown(Rec,AccountSchedulesChartSetup);

    SetDrillDownindexes is a method from the Business Chart Buffer table that maps the DotNet point variable to C/AL data, so it must be used. The next method that you must implement is the action to be performed on Drilldown.

    The DataPointDoubleClicked trigger has the same implementation logic as the DataPointClicked trigger.

     

    NAV Specific Example 2

    Implementation of chart part 1390 on the Small Business Role Center page (9022)

    This chart part contains data from multiple charts within a single part. The Status Text field shows the name of the chart and the current period. Users can browse through the charts with Next Chart and Previous Chart or use Select Chart to choose from a list of available charts.

    On this dialog, users can choose if a chart should be enabled or disabled. If the chart is not enabled, it will be skipped on the Previous Chart and Next Chart actions. Charts used by this part use different codeunits and setup records. If the user changes the selected chart, this option will be saved and applied next time role center is opened.

    Users can also change the period length.

    Choosing the Chart Information button opens a short description of the chart.

    NAV Usages

    Implementation of multiple charts within a single part:

    • Page 1390, Mini Generic Chart

    Charts that use a setup record and select the chart with Customize Chart Setup pages:

    • Page 772, Inventory Performance
    • Page 771, Purchase Performance
    • Page 770, Sales Performance
    • Page 762, Finance Performance

    Chart that uses the Business Chart User Setup table:

    • Page 768, Aged Acc. Receivable Chart

    Other implementations:

    • Page 972, Time Sheet Chart
    • Page 869, Cash Flow Chart
    • Page 760, Trailing Sales Orders Chart

    Ideas for improvement

    We should consider making a generic table for the last chart that the user has used.

    We should investigate if we could make generic code for selecting periods and other common functionality by using RecordRefs.

    Add-In improvements – Different ways to visualize the data and to pick colors for categories.

    As a nice-to-have feature, we could implement functionality to cycle through the charts with a timer.

    Tags: Add-ins Chart Charts Instructions Pattern UI User experience web client

     

     picture
    Josep Pagès on 6/29/2014 11:30:17 PM

    I like Business Chart Add-in and I use it a lot.

    I made an improvement for to show a trend line.

    I added in my own CU (Generic Chart Manager):

    Function Init

    ...

    //Add trend columns

    IF (NoOfPeriods > 1) THEN BEGIN

     FOR k := 1 TO NoOfSeries DO BEGIN

       IF TrendCols[k] THEN BEGIN

         i += 1;

         Cols[k] := i;

         BusChartBuf.AddMeasure(BusChartBuf.GetMeasureName(k-1) + ' ' + 'Trend',

           i, BusChartBuf."Data Type"::Decimal, BusChartBuf."Chart Type"::Line);

       END;

     END;

    END;

    ...

    Function SetColumns

    ...

     //TrendCalc

     IF TrendCols[Serie] THEN BEGIN

       n[Serie] := Period + 1;

       y[Serie] += Values[Serie];

       x[Serie] += n[Serie];

       xy[Serie] += (n[Serie] * Values[Serie]);

       x2[Serie] += (n[Serie] * n[Serie]);

     END;

    ...

    Function SetTrend

    IF (NoOfPeriods > 1) THEN BEGIN

     FOR k := 1 TO NoOfSeries DO BEGIN

       IF TrendCols[k] THEN BEGIN

         a := ((x2[k] * y[k]) - (x[k] * xy[k])) / ((n[k] * x2[k]) - (x[k] * x[k]));

         b := ((n[k] * xy[k]) - (x[k] * y[k])) / ((n[k] * x2[k]) - (x[k] * x[k]));

         FOR Index := 0 TO NoOfPeriods - 1 DO BEGIN

           v := a + (b * (Index+1));

           BusChartBuf.SetValueByIndex(Cols[k]-1, Index, v);

         END;

       END;

     END;

    END;

    over 4 years ago
     picture
    Jan Boes on 6/29/2014 9:03:27 PM

    Idea for improvement:

    Not all the charts are usefull for every NAV user. I would suggest to create a table with a link between the NAV profile and the charts.

    When implemented: a financial employee sees only financial charts and a sales employee sees only sales/crm charts

    over 4 years ago

    Table of Contents

    • Welcome
    • 1. Patterns
      • .NET Exception Handling in C/AL
      • Activity Log
      • Argument Table
      • Blocked Entity
      • Cached Web Service Calls
      • Conditional Cascading Update
      • Copy Document
      • Create Data from Templates
      • Create URLs to NAV Clients
      • Creating Custom Charts
      • Cross Session Events
      • Currently Active Record
      • Data Migration Façade
      • Discovery Event
      • Document
      • Easy Update of Setup or Supplementary Information
      • Error Message Processing
      • Extending the Role Center Headlines
      • Feature Localization for Data Structures
      • Hooks
      • Implementation of surrogate keys using AutoIncrement pattern
      • Instructions in the UI
      • Integration of Addresses
      • Journal Error Processing
      • Journal Template-Batch-Line
      • Master Data
      • Multi-File Download
      • Multilanguage Application Data
      • Multi-Page List
      • No. Series
      • Notifications
      • Observer
      • Posting Routine - Select behavior
      • Product Name
      • Queries
      • Read Once Initialization and Validation
      • Released Entity
      • Report Selection
      • Security
      • Setup Specificity Fallback
      • Silent File Upload and Download
      • Singleton
      • Standard Journal
      • Temporary Dataset Report
      • Totals and Discounts on Subpages (Sales and Purchases)
      • Transfer Custom Fields
      • Variant Façade
    • 2. Anti-Patterns
    • 3. C/AL Coding Guidelines
    • 4. Get involved
    • Related links

    Wikis - Page Details

    Page Details

    Last revision by
    Bogdana Botez picture
    Bogdana Botez
    18 Sep 2015 7:50 PM
    • Revisions: 10
    • Comments: 2

    SBX - Two Col Forum

    Business Applications communities

    Select Community
      • Dynamics 365 Community
      • Power BI Community
      • Flow Community
      • PowerApps Community
      • Microsoft Tech Community

    SBX - Migrated JS

    What's new

    • NEW Surface Pro 6
    • NEW Surface Laptop 2
    • NEW Surface Go
    • Xbox One X
    • Xbox One S
    • VR & mixed reality
    • Windows 10 apps
    • Office apps

    Store & Support

    • Account profile
    • Download Center
    • Sales & support
    • Returns
    • Order tracking
    • Store locations
    • Support
    • Buy online, pick up in store

    Education

    • Microsoft in education
    • Office for students
    • Office 365 for schools
    • Deals for students & parents
    • Microsoft Azure in education

    Enterprise

    • Microsoft Azure
    • Enterprise
    • Data platform
    • Find a solution provider
    • Microsoft partner resources
    • Microsoft AppSource
    • Manufacturing & resources
    • Financial services

    Developer

    • Microsoft Visual Studio
    • Windows Dev Center
    • Developer Network
    • TechNet
    • Microsoft developer program
    • Channel 9
    • Office Dev Center
    • Microsoft Garage

    Company

    • Careers
    • About Microsoft
    • Company news
    • Privacy at Microsoft
    • Investors
    • Diversity and inclusion
    • Accessibility
    • Security
    English (United States)
    • Contact Us
    • Privacy & Cookies
    • Terms of Use
    • Trademarks
    • © Microsoft 2019