diff --git a/BlazorFusionCharts/README.md b/BlazorFusionCharts/README.md index 4dbbb38..20e5d38 100644 --- a/BlazorFusionCharts/README.md +++ b/BlazorFusionCharts/README.md @@ -1,13 +1,19 @@ -# Blazor FusionCharts +# BlazorFusionCharts + FusionCharts is a JavaScript charting library providing 100+ charts and 2,000+ maps for your web and mobile applications. All the visualizations are interactive and animated, which are rendered using webview. This plugin provides Flutter interface which integrates with FC Core JavaScript library using webview. This package also contains FusionTime (timeseries charts), FusionWidgets (gauges, real-time charts), PowerCharts (statistical and advanced charts), and FusionMaps (choropleth geo maps). + - Official Website: [https://www.fusioncharts.com/](https://www.fusioncharts.com/) - Documentation: [https://www.fusioncharts.com/dev/](https://www.fusioncharts.com/dev/) - Licensing: [Legal Terms & Customer Agreements](https://www.ideracorp.com/legal/FusionCharts#tabs-2) - Support: [https://www.fusioncharts.com/contact-support](https://www.fusioncharts.com/contact-support) + ## Introduction + Every year, new frameworks emerge in the JavaScript ecosystem. FusionCharts, being a JavaScript library, needs to keep up with these developments to encourage wider adoption. There has been observed an increase in the demand for integration, especially among Blazor developers. As a result, this project focuses on creating an integration specifically tailored for Blazor developer community + ## Demo + - Github Repo: [https://github.com/fusioncharts/blazor-fusioncharts](https://github.com/fusioncharts/blazor-fusioncharts) - Documentation: []() - Support: []() @@ -15,15 +21,17 @@ Every year, new frameworks emerge in the JavaScript ecosystem. FusionCharts, bei - Official Website: [https://www.fusioncharts.com/](https://www.fusioncharts.com/) - Official NPM Package: [https://www.npmjs.com/package/fusioncharts](https://www.npmjs.com/package/fusioncharts) - Issues: []() - ## Table of Contents + +## Table of Contents + - [Blazor FusionCharts](#blazor-fusioncharts) - [Demo](#demo) - [Table of Contents](#table-of-contents) - [Getting Started](#getting-started) - [Requirements](#requirements) - [Installation](#installation) - - [Setup steps for a new project](#setup-steps-for-a-new-project) - - [Setup using NuGet Package](#setup-using-nuget-package) + - [Setup steps for a new project](#setup-steps-for-a-new-project) + - [Setup using NuGet Package](#setup-using-nuget-package) - [Quick Start](#quick-start) - [Working with APIs](#working-with-apis) - [Working with Events](#working-with-events) @@ -32,21 +40,28 @@ Every year, new frameworks emerge in the JavaScript ecosystem. FusionCharts, bei - [Licensing](#licensing) ## Getting Started + ### Requirements + - Visual Studio (Used Community Edition 2022 - 17.6.1) + ### Installation + #### Setup steps for a new project + 1. Start by referring to the Blazor documentation link for a detailed guide on setting up and installing the necessary dependencies. -2. Clone the code repository from (https://github.com/fusioncharts/blazor-fusioncharts) to your local machine. +2. Clone the code repository from () to your local machine. 3. Windows Installation: -If you're on Windows, ensure that the following workloads are selected during the Visual Studio installation: + If you're on Windows, ensure that the following workloads are selected during the Visual Studio installation: + - ASP.NET and Web development - Azure Development - .NET Desktop - After installation, launch Visual Studio and choose "Open a project or solution." Navigate to the 'BlazorApp1.sln' file in the - extracted folder. Run the BlazorApp1 by clicking the run button in the toolbar. + extracted folder. Run the BlazorApp1 by clicking the run button in the toolbar. + 4. MacOS or Linux Installation: -For MacOS or Linux users, run the 'dotnet watch' command from your project directory in the terminal. + For MacOS or Linux users, run the 'dotnet watch' command from your project directory in the terminal. 5. Open your preferred web browser and navigate to the appropriate address to view and interact with your Blazor app. #### Setup using NuGet Package @@ -61,26 +76,33 @@ For MacOS or Linux users, run the 'dotnet watch' command from your project direc 8. Move to Browse tab of the same window , enter the credentials when prompted and install the package BlazorApp1. ## Quick Start + The application's operational flow can be described as follows: + 1. Create a new blazor application. 2. Verify the existence of the FusionCharts package at the below loctions, if the package exists, remove it. - For Windows: C:\Users\XXX\.nuget\packages - For macOS and Linux: ~/.nuget/packages 3. Check if there is an existing fusioncharts package in the local at this location "C:\Users\XXX\.nuget\packages" for Windows and for mac and linux the location is “~/.nuget/packages”. If so delete the package. 4. Install the latest package from Nuget.org. -5. Upon successful installation, we need to manually add the blazor-fusionCharts.js file from +5. Upon successful installation, we need to manually add the blazor-fusionCharts.js file from “C:\Users\XXX\.nuget\packages\blazorfusioncharts\1.0.0\staticwebassets” to wwwroot folder. 6. In Hosts.cshtml file the below 2 script tags has to be added: + ``` ``` -7. In _Imports.razor file, add the FusionChartsInterop: + +7. In \_Imports.razor file, add the FusionChartsInterop: + ``` @using FusionCharts.FusionChartsInterop ``` + 8. In Program.cs file, add the FusionCharts service: - ``` + + ``` builder.Services.AddScoped(); ``` @@ -88,6 +110,7 @@ The application's operational flow can be described as follows: We have to write the logic to render a FusionCharts inside the Index.razor file. Inorder to render your own chart, edit this file.\ Here is the code to render a time chart: + ``` private async Task renderTimeCharts() { @@ -132,11 +155,13 @@ private async Task renderTimeCharts() ``` Invoking the generic method from Index.razor file: + ``` await fusionChartsService.CallFusionChartsFunction("chartType", "CHART_ID"); ``` The above method call is directed to the FusionChartsService.cs file which is a generic method calling another method generic method written in blazor-fusionCharts.js, and its implentation is: + ``` public async Task CallFusionChartsFunction(String functionName, String chartId, params object[] args) { @@ -146,6 +171,7 @@ public async Task CallFusionChartsFunction(String functionName, String c ``` The generic method which is used to call any FusionCharts methods is embedded inside the blazor-fusioncharts.js file as shown: + ``` window.FusionCharts.invokeChartFunction = (functionName, chartID, ...args) => { let currentChart = FusionCharts(chartID), @@ -182,10 +208,12 @@ There are two ways to attach event listeners to Fusioncharts: To invoke a JavaScript method upon an event trigger, we have to follow the steps below: 1. Generate a JavaScript file within the wwwroot directory that encompasses the implementation of the event handler method. -2. Include the above created file as script tag in the _Hosts.cshtml. Here the created file name is custom.js present in wwwroot folder. +2. Include the above created file as script tag in the \_Hosts.cshtml. Here the created file name is custom.js present in wwwroot folder. + ``` ``` + 4. Implement the JavaScript function to activate it when the event is triggered. 5. Execute an anonymous function to invoke the JS method upon event trigger. @@ -200,17 +228,22 @@ Please use the 'function()' format for the function definition in JavaScript. Ar To invoke a Blazor method upon an event trigger, we have to follow the steps below: 1. Create an instance inside Index.razor file as shown below. + ``` public static Index _instance; ``` -2. Instantiate the instance inside the constructor to refer to the current file/page name where it is being applied. + +2. Instantiate the instance inside the constructor to refer to the current file/page name where it is being applied. + ``` public () { _instance = this; } ``` + 3. Implement a JSInvokable static method to invoke a non-static method using the instance. + ``` [JSInvokable("ChangeData")] public static async Task ChangeData() @@ -218,14 +251,18 @@ To invoke a Blazor method upon an event trigger, we have to follow the steps bel await _instance.NonStaticMethod(); } ``` + 4. Code the non-static method to perform any functionality, here we call the generic method to invoke FusionCharts methods. + ``` public async Task NonStaticMethod() { await fusionChartsService.CallFusionChartsFunction("setChartAttribute", "CHART_ID", "caption", "new-caption"); } ``` + 5. Now we are writing an anonymous function to call the Blazor method upon event trigger. Here 'DotNet' is available in the global scope of JavaScript. + ``` myEvent.dataPlotClick = "function() { DotNet.invokeMethodAsync('BlazorApp1', 'ChangeData') }"; ``` @@ -234,13 +271,15 @@ To invoke a Blazor method upon an event trigger, we have to follow the steps bel The addEventListener method listens to events across all FusionCharts instances on a page and executes custom functions when an event is triggered. -The generic method implemented above can be used to add a custom event listener which invokes a callback method and here it is: +The generic method implemented above can be used to add a custom event listener which invokes a callback method and here it is: + ``` var jsonData = new { type="callback", eventname = "dataPlotClick", fn = "function() {console.log('I am a callback function')}" }; await fusionChartsService.CallFusionChartsFunction("addEventListener", "CHART_ID", jsonData); ``` Below code snippet demonstrates the callback method implementation upon the event trigger. + ``` if (args.length > 0 && args[0].type === CALLBACK) { let { event, fn } = args[0]; @@ -252,13 +291,14 @@ if (args.length > 0 && args[0].type === CALLBACK) { ``` - ## Fixes ### Time Series Method + setDataStore() : This method is used in TimeSeries and FusionGrid, this method takes data and schema from as input from the external files and creates a data source and a data table so as to render the chart. Initially an empty data source is created in the Index.razor file as shown: + ``` myDataSource.data = new {}; ``` @@ -275,6 +315,7 @@ await fusionChartsService.setDataStore("chartId", dataContent, schemaContent); ``` Upon invoking the setDataStore() method above, it leads to the below code snippet in the FusionChartsService.cs file which in turn invokes another user-defined method in the blazor-fusioncharts.js: + ``` public async Task setDataStore(String id, params object[] args){ await _jsruntime.InvokeVoidAsync("FusionCharts.setDataStore", id, args); @@ -290,7 +331,7 @@ window.FusionCharts.setDataStore = (id, args) => { let currentChart = FusionCharts(id); let fusionDataStore = new FusionCharts.DataStore(); - + let data = JSON.parse(args[0]); let schema = JSON.parse(args[1]); @@ -307,10 +348,13 @@ resizeTo() : Resizes the chart to the specified width and height. While invoking In order to mitigate the issue of circular deps in the FusionCharts, you can add your method definition where no data is returned back to the JS environment. This is caused due to the fact that certain methods return JSON which contain circular deps in FusionCharts and serialising a circular deps JSON isn't possible. This method is invoked in the Index.razor file directly as below: + ``` await fusionChartsService.resizeTo("chartId", 450, 500); ``` + It then leads to the FusionChartsService.cs file where inturn invokes the method which will not return anything as returned object json is having circular references. + ``` public async Task resizeTo(String id, params object[] args){ await _jsruntime.InvokeVoidAsync("FusionCharts.resizeTo", id, args); @@ -318,6 +362,7 @@ public async Task resizeTo(String id, params object[] args){ ``` The actual implementation is in the blazor-fusioncharts.js file which invokes the resizeTo method with the height and width parameters. + ``` window.FusionCharts.resizeTo = (id, args) => { let currentChart = FusionCharts(id); @@ -334,12 +379,14 @@ Annotations are defined inside the annotations object. This object has an array Here we have created an external json file which contains the chart data and we implemented a button when clicked renders the chart with the annotation. In the Index.razor file, firstly the data is read from the json file and the chart is rendered as follows: + ``` string jsonUrl = navigationManager.ToAbsoluteUri("demo1.json").ToString(); dynamic myDataSource = jsonUrl; await fusionChartsService.renderChart(chartConfig); await fusionChartsService.CallFusionChartsFunction("setJSONUrl", "demoId", jsonUrl); ``` + Now there is a user-defined method addAnnotaotion() which acts renders the chart by adding an item or a group upon button click. Here is the sample where an item is added: ``` @@ -356,12 +403,15 @@ private async Task addAnnotation(){ }, true); } ``` + The flow leads to FusionChartsService.cs file and its implementation is as follows: + ``` public async Task addAnnotations(String functionName, String id, params object[] args){ await _jsruntime.InvokeVoidAsync("FusionCharts.addAnnotations", functionName, id, args); } ``` + Finally the user-defined addAnnotations() is invoked to add either an item or a group to the rendered chart: ``` @@ -372,25 +422,25 @@ window.FusionCharts.addAnnotations = (functionName, id, args) => { ``` -### Cancel Events +### Cancel Events The functionality to trigger the Cancel Events is implemented in Blazor, which disposes the event that is already triggered on the chart. In the Index.razor file, the functionality of the event that has to be disposed is as follows: ``` myEvent.dataPlotClick = "function() {DotNet.invokeMethodAsync('BlazorApp2TestQA2', 'ChangeData')}"; -myEvent.beforeDispose = "function(e) { console.log(e); e.preventDefault() }"; +myEvent.beforeDispose = "function(e) { console.log(e); e.preventDefault() }"; myEvent.disposeCancelled = "function() { console.log('dispose cancelled') }"; ``` Upon a button click, the event can be canclelled by invoking the callDispose() method whose implementation is attached below: + ``` private async Task callDispose(){ await fusionChartsService.CallFusionChartsFunction("dispose", "demoId"); } ``` - Note: Any method that we invoke that is manipulating or interacting with the chart data then it has to be called after the chart is rendered which means it has to be called after the "loaded" or "renderComplete" event has triggered. Here is the link to an example that demonstrates the above point.\ @@ -401,18 +451,18 @@ Here is the link to an example that demonstrates the above point.\ - Explore 20+ pre-built business specific dashboards for different industries like energy and manufacturing to business functions like sales, marketing and operations [here](https://www.fusioncharts.com/explore/dashboards). - See [Data Stories](https://www.fusioncharts.com/explore/data-stories) built using FusionCharts’ interactive JavaScript visualizations and learn how to communicate real-world narratives through underlying data to tell compelling stories. - ## Licensing There is a license activation mechanism followed by FusionCharts. This means that if you are an active customer then you have to provide license keys in your project to remove the watermark.\ To activate your license follow these steps: + 1. Download the latest version of FusionCharts for your prefered framework. 2. Embed the library in your project. 3. Add the license key to your project, especially where you have instantiated FusionCharts. - # Setup steps - Using CLI -1. Download and install long term support version of dotnet from https://dotnet.microsoft.com/en-us/download. ( Version 6.0 was the LTS during the time of research ) + +1. Download and install long term support version of dotnet from . ( Version 6.0 was the LTS during the time of research ) 2. Navigate to /BlazopApp1 directory and open the terminal (or command prompt). 3. Run `dotnet build` to build the project. 4. Run `dotnet run` to run the project. diff --git a/blazor-fusioncharts.code-workspace b/blazor-fusioncharts.code-workspace index 362d7c2..876a149 100644 --- a/blazor-fusioncharts.code-workspace +++ b/blazor-fusioncharts.code-workspace @@ -3,5 +3,6 @@ { "path": "." } - ] + ], + "settings": {} } \ No newline at end of file