- Prerequisites
- Getting started With Webpack
- Adding JavaScript and CSS reference
- Initializing and configuring the widget
- Binding dashboard service
- Configuring routes for the router
- Running the application
- Upgrade Angular 4 app to Latest Version
- Binding dashboard service
Contact Support
Overview
Syncfusion Dashboard Platform SDK supports Angular Framework for the dashboard viewer widget.
Prerequisites
- Node JS (v6.x.x or higher).
- NPM (3.x.x or higher).
- Angular-Cli (1.5.X or higher).
Getting started With Webpack
Webpack is a popular module bundler, a tool for bundling application source code in convenient chunks and for loading that code from a server into a browser.
This section guides you to start with Angular framework for the dashboard viewer through step-by-step instructions.
Create a new folder ANGULAR
for creating an Angular application using web pack
under the Application folder create a files and folders based on the below structure
The following image illustrates the ANGULAR
folder structure.
Copy and paste the following dependencies in the package.json
file.
{
"name": "dashboard-angular-4",
"version": "1.2.1",
"repository": {},
"scripts": {
"start": "webpack-dev-server --port=4200",
"build": "webpack"
},
"private": true,
"dependencies": {
"@angular/animations": "4.3.1",
"@angular/common": "4.3.1",
"@angular/compiler": "4.3.1",
"@angular/core": "4.3.1",
"@angular/forms": "4.3.1",
"@angular/http": "4.3.1",
"@angular/platform-browser": "4.3.1",
"@angular/platform-browser-dynamic": "4.3.1",
"@angular/platform-server": "4.3.1",
"@angular/router": "4.3.1",
"bootstrap": "3.3.5",
"core-js": "2.4.1",
"ej-angular2": "^16.1.26",
"jquery": "1.12.4",
"jquery-validation": "1.16.0",
"jsrender": "^0.9.90",
"latest-version": "^3.1.0",
"require": "^2.4.20",
"rxjs": "5.1.0",
"web-animations-js": "2.2.2",
"syncfusion-javascript": "^16.1.37",
"zone.js": "0.8.4"
},
"devDependencies": {
"@angular/cli": "1.4.2",
"@angular/compiler-cli": "4.3.1",
"@types/bootstrap": "3.3.32",
"@types/ej.web.all": "^16.1.1",
"@types/jasmine": "2.5.38",
"@types/jquery": "^1.10.31",
"@types/node": "^6.0.73",
"codelyzer": "3.0.1",
"jasmine-core": "2.6.2",
"jasmine-spec-reporter": "4.1.0",
"karma": "1.7.0",
"karma-chrome-launcher": "2.1.1",
"karma-cli": "1.0.1",
"karma-coverage-istanbul-reporter": "1.2.1",
"karma-jasmine": "1.1.0",
"karma-jasmine-html-reporter": "0.2.2",
"protractor": "5.1.2",
"ts-node": "3.0.4",
"typescript": "2.3.3",
"webpack-dev-server": "~2.7.1",
"webpack": "~3.5.5",
"autoprefixer": "^6.5.3",
"css-loader": "^0.28.1",
"cssnano": "^3.10.0",
"exports-loader": "^0.6.3",
"file-loader": "^0.10.0",
"html-webpack-plugin": "^2.29.0",
"less-loader": "^4.0.5",
"postcss-loader": "^1.3.3",
"postcss-url": "^5.1.2",
"raw-loader": "^0.5.1",
"sass-loader": "^6.0.3",
"source-map-loader": "^0.2.0",
"istanbul-instrumenter-loader": "^2.0.0",
"style-loader": "^0.13.1",
"stylus-loader": "^3.0.1",
"url-loader": "^0.5.7",
"circular-dependency-plugin": "^3.0.0",
"webpack-concat-plugin": "1.4.0",
"copy-webpack-plugin": "^4.0.1"
}
}
Adding JavaScript and CSS reference
Copy the scripts, themes, and fonts folder from the Dashboard Platform SDK build installed location which is mentioned below and paste them in the src
folder under the newly created angularDemo
folder.
%localappdata%\Syncfusion\Dashboard Platform SDK\Getting Started Samples\JavaScript\angular\src
Create a new folder as dashboard
under the src/app
folder. In the dashboard
folder, create a new component as dashboard.component.ts
and import the scripts/themes references in the order mentioned in the following code example.
import 'jsrender';
import '../../scripts/jquery.easing.min';
import '../../../node_modules/syncfusion-javascript/Scripts/ej/web/ej.web.all.min';
import '../../scripts/ej.dashboardViewer.all.min';
import '../../themes/default-theme/ej.dashboardViewer.all.min.css';
In the Index.html file, add the following code snippet in the <head>
tag.
<style>
.e-dbrd-layout-wrapper{
height: 100% !important;
}
.e-dbrd-tab-wrapper {
height:100% !important;
}
#dashboard {
overflow: hidden !important;
height: 100% !important;
width: 100% !important;
position: absolute !important;
margin: 0;
}
</style>
Initializing and configuring the widget
Create a new folder as ej
in the src/app
folder.
Copy the angular dashboardviewer source files from the following Dashboard Platform SDK installed location and paste them into the ej
folder.
%localappdata%\Syncfusion\Dashboard Platform SDK\Getting Started Samples\JavaScript\angular\src\app\ej
Create another dashboard.component.html
view file in the dashboard
folder and initialize the ejDashboardViewer Angular component using the following code example.
<div>
<ej-dashboardviewer id="dashboard" [serviceUrl]="url" [dashboardPath]="dashboardPath"></ej-dashboardviewer>
</div>
Copy and paste the below code in dashboardviewer.component.ts
file under the dashboard
folder.
import { Component } from '@angular/core';
import 'jsrender';
import '../../scripts/jquery.easing.min';
import '../../scripts/ej.dashboardViewer.all.min';
import '../../themes/default-theme/ej.dashboardViewer.all.min.css';
declare var $:any;
@Component({
selector: 'app-root',
templateUrl: './dashboard.component.html'
})
export class DashboardComponent {
public url; report;dashboardPath;dashboardParametersSettings;
constructor() {
this.url = "https://dashboardsdk.syncfusion.com/DashboardService/DashboardService.svc"; //Service URL
this.dashboardPath ="https://dashboardsdk.syncfusion.com//Dashboards//NorthWind Product Details.sydx"; //path of the Dashboard
}
}
NOTE
The online dashboard service URL and dashboard path are provided for the demo purpose.
Make sure whether the given dashboard path should be accessible with the given Dashboard Service URL.
Binding dashboard service
To initiate the dashboard service instance, you can follow anyone of the following methods:
IMPORTANT
Hosting dashboard service at IIS is recommended to production environment for object management and other memory management features.
Configuring routes for the router
Before adding router configuration for the above created EJ_DASHBOARDVIEWER_COMPONENTS component, refer to the Angular Routing configuration.
Create a new dashboard.module.ts
file in the dashboard folder and paste the following code snippet in it.
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { DashboardComponent } from './dashboard.component';
import { DashboardRoutes } from './dashboard.routing';
import { EJ_DASHBOARDVIEWER_COMPONENTS} from '../ej/web.all';
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(DashboardRoutes),
],
declarations: [DashboardComponent,EJ_DASHBOARDVIEWER_COMPONENTS]
})
export class DashboardModule {
}
Edit the app.component.html
file under the src
folder for router configuration.
<router-outlet></router-outlet>
Import and declare the Syncfusion source component and EJ_DASHBOARDVIEWER_COMPONENTS component in the src\app\app.module.ts
file using the following code snippet.
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; // this is needed!
import { RouterModule } from '@angular/router';
import { HttpModule } from '@angular/http';
import { APP_BASE_HREF } from '@angular/common';
import { EJ_DASHBOARDVIEWER_COMPONENTS } from './ej/dashboardviewer.component';
import { AppComponent } from './app.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { AppRoutes } from './app.routing';
@NgModule({
imports: [
BrowserAnimationsModule,
RouterModule.forRoot(AppRoutes),
HttpModule
],
declarations: [
AppComponent
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Create a app.routing.ts
file under the src\app
folder and define the router in the src/app/app.routing.ts
file.
import { Routes } from '@angular/router';
export const AppRoutes: Routes = [{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full',
},{
path: '',
children: [{
path: '',
loadChildren: './dashboard/dashboard.module#DashboardModule'
}]
}
];
Create a app.component.spec.ts
file under the src\app
folder and define the router in the src/app/app.component.spec.ts
file.
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
}).compileComponents();
}));
it('should create the app', async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
}));
it(`should have as title 'app works!'`, async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('app works!');
}));
it('should render title in a h1 tag', async(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('app works!');
}));
});
Also, create a dashboard.routing.ts
file under the dashboard
folder and place the following code snippet.
import { Routes } from '@angular/router';
import { DashboardComponent } from './dashboard.component';
export const DashboardRoutes: Routes = [{
path: '',
children: [{
path: 'dashboard',
component: DashboardComponent
}]
}];
Refer the below codes to the required files created in the application
//In webpack.Config.js
const fs = require('fs');
const path = require('path');
const ConcatPlugin = require('webpack-concat-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
const CircularDependencyPlugin = require('circular-dependency-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const autoprefixer = require('autoprefixer');
const postcssUrl = require('postcss-url');
const cssnano = require('cssnano');
const { NoEmitOnErrorsPlugin, SourceMapDevToolPlugin, NamedModulesPlugin } = require('webpack');
const { InsertConcatAssetsWebpackPlugin, NamedLazyChunksWebpackPlugin, BaseHrefWebpackPlugin } = require('@angular/cli/plugins/webpack');
const { CommonsChunkPlugin } = require('webpack').optimize;
const { AotPlugin } = require('@ngtools/webpack');
const nodeModules = path.join(process.cwd(), 'node_modules');
const realNodeModules = fs.realpathSync(nodeModules);
const genDirNodeModules = path.join(process.cwd(), 'src', '$$_gendir', 'node_modules');
const entryPoints = ["inline","polyfills","sw-register","styles","vendor","main"];
const minimizeCss = false;
const baseHref = "";
const deployUrl = "";
const postcssPlugins = function () {
// safe settings based on: https://github.com/ben-eb/cssnano/issues/358#issuecomment-283696193
const importantCommentRe = /@preserve|@license|[@#]\s*source(?:Mapping)?URL|^!/i;
const minimizeOptions = {
autoprefixer: false,
safe: true,
mergeLonghand: false,
discardComments: { remove: (comment) => !importantCommentRe.test(comment) }
};
return [
postcssUrl({
url: (URL) => {
// Only convert root relative URLs, which CSS-Loader won't process into require().
if (!URL.startsWith('/') || URL.startsWith('//')) {
return URL;
}
if (deployUrl.match(/:\/\//)) {
// If deployUrl contains a scheme, ignore baseHref use deployUrl as is.
return `${deployUrl.replace(/\/$/, '')}${URL}`;
}
else if (baseHref.match(/:\/\//)) {
// If baseHref contains a scheme, include it as is.
return baseHref.replace(/\/$/, '') +
`/${deployUrl}/${URL}`.replace(/\/\/+/g, '/');
}
else {
// Join together base-href, deploy-url and the original URL.
// Also dedupe multiple slashes into single ones.
return `/${baseHref}/${deployUrl}/${URL}`.replace(/\/\/+/g, '/');
}
}
}),
autoprefixer(),
].concat(minimizeCss ? [cssnano(minimizeOptions)] : []);
};
module.exports = {
"resolve": {
"extensions": [
".ts",
".js"
],
"modules": [
"./node_modules",
"./node_modules"
],
"symlinks": true
},
"resolveLoader": {
"modules": [
"./node_modules",
"./node_modules"
]
},
"entry": {
"main": [
"./src\\main.ts"
],
"polyfills": [
"./src\\polyfills.ts"
],
"styles": [
"./src\\themes\\default-theme\\ej.dashboardViewer.all.min.css"
]
},
"output": {
"path": path.join(process.cwd(), "dist"),
"filename": "[name].bundle.js",
"chunkFilename": "[id].chunk.js"
},
"module": {
"rules": [
{
"enforce": "pre",
"test": /\.js$/,
"loader": "source-map-loader",
"exclude": [
/(\\|\/)node_modules(\\|\/)/
]
},
{
"test": /\.html$/,
"loader": "raw-loader"
},
{
"test": /\.(eot|svg|cur)$/,
"loader": "file-loader?name=[name].[hash:20].[ext]"
},
{
"test": /\.(jpg|png|webp|gif|otf|ttf|woff|woff2|ani|GIF)$/,
"loader": "url-loader?name=[name].[hash:20].[ext]&limit=10000"
},
{
"exclude": [
path.join(process.cwd(), "src\\themes\\default-theme\\ej.dashboardViewer.all.min.css")
],
"test": /\.css$/,
"use": [
"exports-loader?module.exports.toString()",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
}
]
},
{
"exclude": [
path.join(process.cwd(), "src\\themes\\default-theme\\ej.dashboardViewer.all.min.css")
],
"test": /\.scss$|\.sass$/,
"use": [
"exports-loader?module.exports.toString()",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
},
{
"loader": "sass-loader",
"options": {
"sourceMap": false,
"precision": 8,
"includePaths": []
}
}
]
},
{
"exclude": [
path.join(process.cwd(), "src\\themes\\default-theme\\ej.dashboardViewer.all.min.css")
],
"test": /\.less$/,
"use": [
"exports-loader?module.exports.toString()",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
},
{
"loader": "less-loader",
"options": {
"sourceMap": false,
"paths": []
}
}
]
},
{
"exclude": [
path.join(process.cwd(), "src\\themes\\default-theme\\ej.dashboardViewer.all.min.css")
],
"test": /\.styl$/,
"use": [
"exports-loader?module.exports.toString()",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
},
{
"loader": "stylus-loader",
"options": {
"sourceMap": false,
"paths": []
}
}
]
},
{
"include": [
path.join(process.cwd(), "src\\themes\\default-theme\\ej.dashboardViewer.all.min.css")
],
"test": /\.css$/,
"use": [
"style-loader",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
}
]
},
{
"include": [
path.join(process.cwd(), "src\\themes\\default-theme\\ej.dashboardViewer.all.min.css")
],
"test": /\.scss$|\.sass$/,
"use": [
"style-loader",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
},
{
"loader": "sass-loader",
"options": {
"sourceMap": false,
"precision": 8,
"includePaths": []
}
}
]
},
{
"include": [
path.join(process.cwd(), "src\\themes\\default-theme\\ej.dashboardViewer.all.min.css")
],
"test": /\.less$/,
"use": [
"style-loader",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
},
{
"loader": "less-loader",
"options": {
"sourceMap": false,
"paths": []
}
}
]
},
{
"include": [
path.join(process.cwd(), "src\\themes\\default-theme\\ej.dashboardViewer.all.min.css")
],
"test": /\.styl$/,
"use": [
"style-loader",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
},
{
"loader": "stylus-loader",
"options": {
"sourceMap": false,
"paths": []
}
}
]
},
{
"test": /\.ts$/,
"loader": "@ngtools/webpack"
}
]
},
"plugins": [
new NoEmitOnErrorsPlugin(),
new ConcatPlugin({
"uglify": false,
"sourceMap": true,
"name": "scripts",
"fileName": "[name].bundle.js",
"filesToConcat": [
"**\\node_modules\\jquery\\dist\\jquery.js",
"**\\node_modules\\bootstrap\\dist\\js\\bootstrap.js"
]
}),
new InsertConcatAssetsWebpackPlugin([
"scripts"
]),
new CopyWebpackPlugin([
{
"context": "**\\src/",
"to": "",
"from": {
"glob": "assets/**/*",
"dot": true
}
},
{
"context": "**\\src/",
"to": "",
"from": {
"glob": "favicon.ico",
"dot": true
}
}
], {
"ignore": [
".gitkeep"
],
"debug": "warning"
}),
new ProgressPlugin(),
new CircularDependencyPlugin({
"exclude": /(\\|\/)node_modules(\\|\/)/,
"failOnError": false
}),
new NamedLazyChunksWebpackPlugin(),
new HtmlWebpackPlugin({
"template": "./src\\index.html",
"filename": "./index.html",
"hash": false,
"inject": true,
"compile": true,
"favicon": false,
"minify": false,
"cache": true,
"showErrors": true,
"chunks": "all",
"excludeChunks": [],
"title": "Webpack App",
"xhtml": true,
"chunksSortMode": function sort(left, right) {
let leftIndex = entryPoints.indexOf(left.names[0]);
let rightindex = entryPoints.indexOf(right.names[0]);
if (leftIndex > rightindex) {
return 1;
}
else if (leftIndex < rightindex) {
return -1;
}
else {
return 0;
}
}
}),
new BaseHrefWebpackPlugin({}),
new CommonsChunkPlugin({
"name": [
"inline"
],
"minChunks": null
}),
new CommonsChunkPlugin({
"name": [
"vendor"
],
"minChunks": (module) => {
return module.resource
&& (module.resource.startsWith(nodeModules)
|| module.resource.startsWith(genDirNodeModules)
|| module.resource.startsWith(realNodeModules));
},
"chunks": [
"main"
]
}),
new SourceMapDevToolPlugin({
"filename": "[file].map[query]",
"moduleFilenameTemplate": "[resource-path]",
"fallbackModuleFilenameTemplate": "[resource-path]?[hash]",
"sourceRoot": "webpack:///"
}),
new CommonsChunkPlugin({
"name": [
"main"
],
"minChunks": 2,
"async": "common"
}),
new NamedModulesPlugin({}),
new AotPlugin({
"mainPath": "main.ts",
"replaceExport": false,
"hostReplacementPaths": {
"environments\\environment.ts": "environments\\environment.ts"
},
"exclude": [],
"tsConfigPath": "src\\tsconfig.app.json",
"skipCodeGeneration": true
})
],
"node": {
"fs": "empty",
"global": true,
"crypto": "empty",
"tls": "empty",
"net": "empty",
"process": true,
"module": false,
"clearImmediate": false,
"setImmediate": false
},
"devServer": {
"historyApiFallback": true
}
};
//in polyfills.ts
import 'core-js/es6/reflect';
import 'core-js/es7/reflect';
import 'zone.js/dist/zone';
//In main.ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule);
// In tsconfig.json
{
"compilerOptions": {
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es5",
"lib": [
"es2016",
"dom"
],
"outDir": "../out-tsc/app",
"module": "es2015",
"baseUrl": "",
"typeRoots": [
"node_modules/@types/"
],
"types": [
"jquery",
"ej.web.all"
]
},
"exclude": [
"**/*.spec.ts"
]
}
Running the application
- To run the application, execute the following command.
npm install
npm start
NOTE
While running the angular sample for the first time,
npm install
command is required to install the required packages in the angular followed bynpm start
to launch the sample.
- Browse to
http://localhost:4200
, to see the application. The component is rendered as shown in the below screenshot. You can make changes in the code found under thesrc
folder and the browser should auto-refresh itself while saving the files.
*If you face any issue, delete the node_modules folder and again run npm install
. After completing the installation process, run the npm start --port <"port">
command, for example: npm start --port 6200
.
Upgrade Angular 4 app to Latest Version
Update the Angular packages, using the following commands.
npm install -g npm-check-updates
ncu -u
If you get any error while running these commands, update your node and npm version. Follow the instructions given in this link to upgrade the node and npm.
Finally, delete the previous node_modules
folder and run npm install
command.
Now, your sample is updated to the Latest Angular version.
Binding dashboard service
To initiate the dashboard service instance, follow anyone of the following methods.
IMPORTANT
Hosting dashboard service at IIS is recommended to production environment for object management and other memory management features.
The following properties of ejDashboardViewer widget support model binding:
- serviceUrl
- dashboardPath