Category: The Others

Refactoring the ChartJS SPFx Web Part  Using IoC Container

Refactoring the ChartJS SPFx Web Part Using IoC Container

In the previous blog post, I introduced how to create Chart.js enabled SPFx web parts. In the example I have used in that blog post, I created a IDataSource interface and implemented the interface with a MockDataSource class that was instantiated in the React component.


However, there is an issue with this design as the ChartJs React component class depends on the concrete data source class implementation instead of the abstraction of the data sources. In this way, we have to change the ChartJs React component code if we want to substitute the MockDataSource with other data sources that implements the IDataSource interfaces.

In future, we may create other data sources for the chart web part such as SharePoint data source, Office Excel data source, or Rest API data source. Instead of changing the code in ChartJs React component to substitute the data source type, we expect a better approach that allow us to configure the data source type outside of the ChartJs React component so that we can have the ChartJs React component closed to change when we need add a new data source type.

Here a IoC container will help. In this blog post, I improved the ChartJs SPFx web part solution with InversifyJS IoC container to manage the dependencies. Please find the source code used for this blog post here in github.

Setup InversifyJS in ChartJs web part project

It is pretty easy to setup InversifyJS library in our ChartJs web part project. Firstly, we run the npm command: npm install inversify reflect-metadata –save to install the library, and then we need to modify the compiler options of Typescript in the tsconfig.json file to add additional settings for “lib”, “types”, “moduleResolution”, “experimentalDecorators”, and “emitDecoratorMetadata” as the snapshot below shown.


Annotate data source classes with @injectable decorator

We need to add @injectable decorator to the data source classes that are implemented the IDataSource interface.


Apart from the MockDataSource class we already have, we are going to create another data source class for testing purpose, namely MockDataSourceForTestIOC. All the values of the mock data feed from this class are set as “10” as a comparison to the orginal MockDataSoruce class.


Add Inversify configuration file

We need to create a Inversify configuration file in the src folder that declares the Inversify IoC container and register the concrete data source class implementation to IDataSource interface.


In this file, we need import the IDataSource interface and the concrete data source classes, and then we create an instance of Inversify Container and bind a concrete class to the IDataSource interface.


Use abstraction in Chart.js component

In the Chart.js component class that depends on the data source implementation, we firstly import the container declared in the Inversify configuration file.


We then use the get method of the container  (kernel.get(“IDataSource”)) to resolve the dependency.



We have setup the Inversify IoC container in our project. We can now test the setup through binding the IDataSource interface to different data sources. Firstly, we bind the interface to MockDataSource class. After run gulp serve to preview the web part in local workbench, we have the results showing as:


Then we bind the IDataSource interface to MockDataSourceForTestIOC class that provides the data set with all the groups having same value as “10”.


After run the preview, we can see that the chart is rendered using the data provided by the MockDataSourceForTestIOC implementation.


Building SPFx Client-Side Web Parts using Chart.js

Building SPFx Client-Side Web Parts using Chart.js

Chart.js is a very handy Javascript charting library, lightweight, flexible, sleek UI and free of charge. In this blog post, I will walk through the steps to build SharePoint Framework client-side web parts using Chart.js library.

I have created a demo client-side chart web part with the source code on github. This web part allows users to select chart type on the web part properties panel and then renders the chart in the selected chart type using Chart.js library. An interface, IDataSource, was created in the web part and we can implement the interface with all kinds of data sources such as SharePoint, Office Excel, and Rest APIs. For this demo web part, I just implemented the interface with a mock data source class MockDataSource, however we can add any data source class in future as long as the class implements the getData method defined in the IDataSource interface.


Setup development environment and scaffold the project structures

Please follow this guide from Microsoft to setup the SharePoint Framework development environment.

After the development environment is ready, run yo @microsoft/sharepoint in node.js command prompt to scaffold the project structures and select “React” as the Javascript framework.

Create data access interface/classes

In this demo, three data access interface/classes need to be created, including ChartJSData DTO class, IDataSoruce interface, and MockDataSoruce class.


Firstly, we need to create a DTO class, ChartJSData, that holds the data read from the data sources and will be rendered using Chart.js charts.


We then create the IDataSource interface with the getData() method signature and implement the interface with a mock data source, MockDataSource.



Import Chart.js library into client-side web part

To import the Chart.js library into the client-side web part, we need add an external entry in the config.json file and point it to the CDN hosted Chart.js file.


Then import the library in the React component file (ChartJs.tsx) that will render the Chart.js charts.


Create and Render the Chart.js charts in client-side web part

In the React component file (ChartJs.tsx), we firstly import the MockDataSource class and ChartJSData class defined earlier.


In the render() method of the ChartJs React component, we add the canvas tag where the Chart.js charts will be drew on.

We then create a private method renderChart() that creates and renders the Chart.js chart object with the data read from the MockDataSource. This method will be called in the both componentDidMount() method and componentDidUpdate() method. The reason to re-render the chart in the componentDidUpdate() method is to allow users changing chart type using the web part properties panel.


We now have the Chart.js library ready to render charts in the demo client-side web part. We can run gulp serve to preview the web part on the local workbench.


ABC Classification Analysis with Tableau

In one of my previous posts, I have conducted an ABC Classification analysis using MDX against a SSAS Cube. In this post, I will conduct an ABC Classification analysis using Tableau calculations.

In this example, we want to classify the products based on their sales amount into three categories: ‘A’ (make up the top 5% of total sales), ‘B’ (make up the top %5-20%), ‘C’ (the others).

Firstly, we add the Product Name attribute and Sales Amount measure onto a tableau table and sort the table by Sales Amount in Desc order.


We then create three calculations, “Sales Running Total”, “% Sales Running Total”, and “ABC Classification Category”:

1. [Sales Running Total]


This calculation sums up the total sales amount from the top ranked product to the product of current row.

2. [% Sales Running Total]


While the [Sales Running Total] is divided by the total sales of all products, we can have the related position of the current product against all products.

3. [ABC Classification Category]


This calculation checks the position of the current product in the sales amount range and place the product into the corresponding category. Tableau LOOKUP function is used to evaluate whether the total sales of all the higher ranked products above the current product is < 5% of total sales of all products, if so, the current product falls into the category ‘A’, if the total sales of all the higher ranked products > or = 5%, that means the current product does not consist of the top 5% product sales amount and it will falls into the category ‘B’ or ‘C’. Then we can use the same approach to find which product falls into category ‘B’ and the remaining ones will be in category ‘C’.

We can then add the calculations into the table and have the products mapped to the categories.


or a nice little chart:


Tableau #2 – Visualising Eurovision Voting Path

In the last blog post, I’ve created a box-and-whisker plot to compare UK’s performance on Eurovision contest with others.  That would be good to have a nice Viz to show where the votes from for each country. This can be achieved using Tableau Map and Path.


It is straightforward to create this Viz using the Path Shelf on Tableau. However, we need have the source data in the right structure. The snapshot below shows the structure of original raw data for Eurovision final voting. Each vote is stored in a single row with the [Country] column storing where the score was given to and the [Giver] column storing where the score was given from.


To use the Path feature in Tableau, we need transform the vote row into two rows, one row stores details for the start point of the path and the other is for the destination point of the path. the snapshot below shows the required data structure for the Viz.


To transform the data structure, I have loaded the original Eurovision voting data into SQL Server and create a Stored Procedure to output the data in the required structure.


The original vote row is UNPIVOT on the [Country] and [Giver] column and generate two rows with details on where the vote is from and to. For each path pair, we need give them a unique [Path ID] and also assign the [Path Order] to the Start and To row. We can have the actual [Score] number on the [Giver] row so that we can assign the SUM([Score]) value to Size of the Start point to represent the size of voting score.

Tableau #1 – Analysis of UK’s Eurovision performance

Eurovision is my favourite song contest programme, not only because of the not bad songs but also the acid humour from the BBC presenter Terry Wogan. I have been watching this show for a few years, from my memory, UK has constantly performed poorly on the final voting which has been blamed as “tactical Eastern bloc voting” by Terry Wogan.

As I came across the raw data of Eurovision results (from 1998 to 2012) a few days ago, it gives me an opportunities to feed my curiosity on how UK has performed in the contest statistically.

I loaded the raw data into Tableau and create a box-and-whisker plot to compare the average place of each country participated in the contest.


From the chart, we can see that UK did perform below average and ranked 9th from bottom with France, Portugal etl. countries below it. The average rank of UK is 16.33, below the overall average rank of all countries (12.70).


From the box-and-whisker plot of UK, we can see that UK’s ranks in the contest from 1998 to 2012 have wide spread from the 2nd place to 26th place. The median of the ranks is 16 and the lower quartile is 11.50 which makes UK at the average-below level compared to other countries. However, the interesting part is the upper quartile which is as high as 24 which indicates that UK has been at the bottom of the contest for quite a few years. In comparison to the box plot of France’s and Portugal’s, although both average and median of the two countries’s ranks are lower than UK’s, the distribution of the ranks are less spread and the upper quartile of the two countries’ are lower than UK’s. That may explain why my perception of UK’s performance on Eurovision is worse than those two countries.

Dynamics CRM 2011 Computer-Telephony Integration Solution Using Flexor CTI Add-on

I have been searching for CTI solutions for Dynamics CRM 2011 and found Flexor CTI is a good choice which provides most of common CTI features, such as click-to-dial, screen popping, on-screen call control, journal and log calls direct to customer records in Dynamics CRM, and also management reporting. This add-on is very easy to install and configure, and it supports a wide range of telephony devices. You could find the list of supported devices here.

This blog post goes through the steps to integrate Flexor CTI Add-on with an on-premier Dynamics CRM 2011 through Asterisk PBX.

  1. Download and install Flexor CTI for Dynamics CRM add-on.
  2. After the add-on is installed, a configuration dialogue is poped up. you need firstly login the Flexor CTI manager with your account. If you have not gotten a account, you can register as a trial user with 14 days trial period.


  1. Looking for telephony devices in your organisation.


As the telephony devices used in this example are based on Asterisk PBX. We need set the asterisk server details and AMI (Asterisk Manager Interface) user credentials. Flexor CTI communicates with Asterisk server through AMI, so we need edit the manager.conf in Asterisk server to enable AMI and also create a user credential for connecting to the AMI. You could find more details for configuring Asterisk Server here.


After the Flexor CTI manager connects to Asterisk server, you could scan the server and get all the available telephony devices in your organisation. Then you could select and add the telephony device you want to connect to the current PC.


Now, the Flexor CTI manager is installed and configured.


  1. Deploy Flexor CTI customisation solution on Dynamics CRM. Firstly, locate the “” file in the Flexor CTI program folder (in Program Files folder). Then log on Dynamics CRM and navigate to Solutions page, import the “” solution to the Dynamics CRM instance.



Don’t forget to publish the solution after it is imported.


  1. Repeat step 1 – 3 to install Flexor CTI add-on on all client PCs in your organisation.

Now, the Flexor CTI is integrated with Dynamincs CRM system. As the snapshot below shows, you can directly make a phone call to your contacts through the Dynamics CRM UI.


Once there is a phone call coming in, an inbound call panel pops up. You could hang off, hold, forward the phone call through the panel.


In addition, you could add the caller into Dynamics CRM as a Lead, Contact, or Account. Also, you could create a customer service Case record from the phone call.


More importantly, you can edit subject and journal entry on the call panel. Once the phone call is completed, the phone call activity will be logged in Dynamics CRM.