Getting Started
Steps for getting started with the FlexChart in AngularJS applications:
Add references to AngularJS, Wijmo, and Wijmo's AngularJS directives.
Add a component to provide data and logic.
Add a FlexChart to the page and bind it to the data.
Add some CSS to customize the chart's appearance.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/bootstrap.css" />
<link rel="stylesheet" type="text/css" href="css/wijmo.css" />
<link rel="stylesheet" type="text/css" href="css/app.css"/>
<!-- Angular 2 --/>
<!-- Polyfill(s) for older browsers -->
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<!-- Configure SystemJS -->
<script src="systemjs.config.js"></script>
<!-- JQuery/Bootstrap -->
<script src="bin/Devel/external/jquery.js" type="text/javascript"></script>
<script src="bin/Devel/external/bootstrap.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="bin/Devel/external/bootstrap/css/bootstrap.css" />
<script src="scripts/wijmo.js" type="text/javascript"/></script/>
<script src="scripts/wijmo.input.js" type="text/javascript"/></script/>
<script src="scripts/wijmo.chart.js" type="text/javascript"/></script/>
<script src="scripts/wijmo.angular2.js" type="text/javascript"/></script/>
<!-- Load the root application module -->
<script>
System.import('./src/app');
</script>
</head>
<body>
<!-- Add root application component -->
<app-cmp>
<wj-flex-chart [itemsSource]="data"
[bindingX]="'country'">
<wj-flex-chart-series [name]="'Sales'" [binding]="'sales'"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Expenses'" [binding]="'expenses'"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Downloads'" [binding]="'downloads'"></wj-flex-chart-series>
</wj-flex-chart>
</app-cmp>
</body>
</html>
import { Injectable } from '@angular/core';
// Common data service
@Injectable()
export class DataSvc {
getData(countries: string[]): any[] {
var data = [];
for (let i = 0; i < countries.length; i++) {
data.push({
country: countries[i],
downloads: Math.round(Math.random() * 20000),
sales: Math.random() * 10000,
expenses: Math.random() * 5000
});
}
return data;
}
}
--------------------Component-----------------------
// Angular
import * as wjcCore from 'wijmo/wijmo';
import * as wjcChart from 'wijmo/wijmo.chart';
import * as wjcInput from 'wijmo/wijmo.input';
import { Component, EventEmitter, Input, Inject, enableProdMode, ViewChild, NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { BrowserModule } from '@angular/platform-browser';
import { WjChartModule } from 'wijmo/wijmo.angular2.chart';
import { WjInputModule } from 'wijmo/wijmo.angular2.input';
import { TabsModule } from './components/AppTab';
import { DataSvc } from './services/DataSvc';
// The Explorer application root component.
@Component({
selector: 'app-cmp',
templateUrl: 'src/app.html'
})
export class AppCmp {
countries = 'US,Germany,UK,Japan,Italy,Greece'.split(',');
data: { country: string, downloads: number, sales: number, expenses: number }[];
protected dataSvc: DataSvc;
constructor(@Inject(DataSvc) dataSvc: DataSvc) {
// data for FlexChart
this.dataSvc = dataSvc;
this.data = this.dataSvc.getData(this.countries);
}
}
@NgModule({
imports: [WjInputModule, WjChartModule, BrowserModule, FormsModule, TabsModule],
declarations: [AppCmp],
providers: [DataSvc],
bootstrap: [AppCmp]
})
export class AppModule {
}
enableProdMode();
// Bootstrap application with hash style navigation and global services.
platformBrowserDynamic().bootstrapModule(AppModule);
/* set default chart style */
.wj-flexchart {
height: 400px;
background-color: white;
box-shadow: 4px 4px 10px 0px rgba(50, 50, 50, 0.75);
padding: 8px;
margin-bottom: 12px;
display:block;
}
Result (live):
Chart Types
The FlexChart control has three properties that allow you to customize the chart
type:
chartType : Selects the default chart type to be used for all series objects.
Individual series objects can override this.
stacking : Determines whether series objects are plotted independently,
stacked, or stacked so their sum is 100%.
rotated : Flips the X and Y axes so X becomes vertical and Y horizontal.
The example below allows you to see what happens when you change these properties:
<wj-flex-chart [itemsSource]="data"
[chartType]="chartType"
[stacking]="stacking"
[rotated]="rotated"
[bindingX]="'country'">
<wj-flex-chart-series [name]="'Sales'" [binding]="'sales'"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Expenses'" [binding]="'expenses'"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Downloads'" [binding]="'downloads'"></wj-flex-chart-series>
</wj-flex-chart>
<wj-menu [(value)]="chartType" [header]="'Chart Type'">
<wj-menu-item [value]="'Column'">Column</wj-menu-item>
<wj-menu-item [value]="'Bar'">Bar</wj-menu-item>
<wj-menu-item [value]="'Scatter'">Scatter</wj-menu-item>
<wj-menu-item [value]="'Line'">Line</wj-menu-item>
<wj-menu-item [value]="'LineSymbols'">LineSymbols</wj-menu-item>
<wj-menu-item [value]="'Area'">Area</wj-menu-item>
<wj-menu-item [value]="'Spline'">Spline</wj-menu-item>
<wj-menu-item [value]="'SplineSymbols'">SplineSymbols</wj-menu-item>
<wj-menu-item [value]="'SplineArea'">SplineArea</wj-menu-item>
</wj-menu>
<wj-menu [(value)]="stacking" [header]="'Stacking'">
<wj-menu-item [value]="'None'">None</wj-menu-item>
<wj-menu-item [value]="'Stacked'">Stacked</wj-menu-item>
<wj-menu-item [value]="'Stacked100pc'">Stacked 100%</wj-menu-item>
</wj-menu>
<wj-menu [(value)]="rotated" [header]="'Rotated'">
<wj-menu-item [value]="false">False</wj-menu-item>
<wj-menu-item [value]="true">True</wj-menu-item>
</wj-menu>
export class AppCmp {
countries = 'US,Germany,UK,Japan,Italy,Greece'.split(',');
data: { country: string, downloads: number, sales: number, expenses: number }[];
protected dataSvc: DataSvc;
//chart properties
chartType = 'Column';
stacking = 'None';
rotated = false;
constructor(@Inject(DataSvc) dataSvc: DataSvc) {
// data for FlexChart
this.dataSvc = dataSvc;
this.data = this.dataSvc.getData(this.countries);
}
}
Result (live):
Column
Bar
Scatter
Line
LineSymbols
Area
Spline
SplineSymbols
SplineArea
None
Stacked
Stacked 100%
False
True
Funnel Charts
The example below shows you how to create and customize Funnel Chart.
<wj-flex-chart #funnelChart
[itemsSource]="funnelData"
chartType="Funnel"
labelContent="{y}"
bindingX="country">
<wj-flex-chart-series name="Sales" binding="sales"></wj-flex-chart-series>
</wj-flex-chart>
<dl class="dl-horizontal">
<dt>Neck Width</dt>
<dd>
<wj-input-number #inputNeckWidth (valueChanged)="neckWidthChanged(inputNeckWidth)"
[min]="0"
[value]="0.2"
[max]="1"
[step]=".1">
</wj-input-number>
</dd>
</dl>
<dl class="dl-horizontal">
<dt>Neck Height</dt>
<dd>
<wj-input-number #inputNeckHeight (valueChanged)="neckHeightChanged(inputNeckHeight)"
[min]="0"
[value]="0.2"
[max]="1"
[step]=".1">
</wj-input-number>
</dd>
</dl>
<dl class="dl-horizontal">
<dt></dt>
<dd>
<wj-menu #funnelTypeMenu header="Funnel Type: " value="default"
(itemClicked)="funnelTypeChanged(funnelTypeMenu)">
<wj-menu-item value="default">Default</wj-menu-item>
<wj-menu-item value="rectangle">Rectangle</wj-menu-item>
</wj-menu>
</dd>
</dl>
export class AppCmp {
funnelData;
@ViewChild('funnelChart') funnelChart: wjcChart.FlexChart;
protected dataSvc: DataSvc;
constructor(@Inject(DataSvc) dataSvc: DataSvc) {
this.dataSvc = dataSvc;
this.funnelData = this.dataSvc.getFunnelData(this.countries);
}
ngAfterViewInit() {
this.funnelChart.options = {
funnel: {
neckWidth: 0.2,
neckHeight: 0.2,
type: 'default'
}
};
}
neckWidthChanged = (sender: wjcInput.InputNumber) => {
if (sender.value < sender.min || sender.value > sender.max) {
return;
}
if (!this.funnelChart.options) {
return;
}
this.funnelChart.options.funnel.neckWidth = sender.value;
this.funnelChart.refresh(true);
};
neckHeightChanged = (sender: wjcInput.InputNumber) => {
if (sender.value < sender.min || sender.value > sender.max) {
return;
}
if (!this.funnelChart.options) {
return;
}
this.funnelChart.options.funnel.neckHeight = sender.value;
this.funnelChart.refresh(true);
};
funnelTypeChanged = (sender: wjcInput.Menu) => {
if (!this.funnelChart.options) {
return;
}
this.funnelChart.options.funnel.type = sender.selectedValue;
this.funnelChart.refresh(true);
};
}
Result (live):
Neck Width
Neck Height
Default
Rectangle
Mixed Chart Types
You can use different chart types for each chart series by setting the chartType
property on the series itself. This overrides the chart's default chart type.
In the example below, the chart's chartType property is set to Column ,
but the Downloads series overrides that to use the LineAndSymbol
chart type:
<wj-flex-chart [itemsSource]="data"
[chartType]="'Column'"
[bindingX]="'country'">
<wj-flex-chart-series [name]="'Sales'" [binding]="'sales'"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Expenses'" [binding]="'expenses'"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Downloads'" [binding]="'downloads'" [chartType]="'LineSymbols'"></wj-flex-chart-series>
</wj-flex-chart>
Result (live):
Legend and Titles
Use the legend properties to customize the appearance of the chart legend, and
the header , footer , and axis title properties to add titles
to your charts.
You can style the legend and titles using CSS. The CSS tab below shows the rules
used to customize the appearance of the legend and titles. Notice that these are
SVG elements, so you have to use CSS attributes such as "fill" instead of "color."
<wj-flex-chart [itemsSource]="data"
[bindingX]="'country'"
[header]="header"
[footer]="footer">
<wj-flex-chart-legend [position]="legendPosition"></wj-flex-chart-legend>
<wj-flex-chart-axis [wjProperty]="'axisX'" [title]="titleX"></wj-flex-chart-axis>
<wj-flex-chart-axis [wjProperty]="'axisY'" [title]="titleY"></wj-flex-chart-axis>
<wj-flex-chart-series [name]="'Sales'" [binding]="'sales'"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Expenses'" [binding]="'expenses'"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Downloads'" [binding]="'downloads'"></wj-flex-chart-series>
</wj-flex-chart>
<dl class="dl-horizontal">
<dt>Header</dt>
<dd><input [(ngModel)]="header" class="form-control" /></dd>
<dt>Footer</dt>
<dd><input [(ngModel)]="footer" class="form-control" /></dd>
<dt>X-Axis Title</dt>
<dd><input [(ngModel)]="titleX" class="form-control" /></dd>
<dt>Y-Axis Title</dt>
<dd><input [(ngModel)]="titleY" class="form-control" /></dd>
<dt></dt>
<dd>
<wj-menu [(value)]="legendPosition" [header]="'Legend'">
<wj-menu-item [value]="'None'">None</wj-menu-item>
<wj-menu-item [value]="'Left'">Left</wj-menu-item>
<wj-menu-item [value]="'Top'">Top</wj-menu-item>
<wj-menu-item [value]="'Right'">Right</wj-menu-item>
<wj-menu-item [value]="'Bottom'">Bottom</wj-menu-item>
</wj-menu>
</dd>
</dl>
export class AppCmp {
countries = 'US,Germany,UK,Japan,Italy,Greece'.split(',');
data: { country: string, downloads: number, sales: number, expenses: number }[];
//chart properties
chartType = 'Column';
legendPosition = 'Right';
header = 'Sample Chart';
footer= 'copyright (c) ComponentOne';
titleX= 'country';
titleY = 'amount';
protected dataSvc: DataSvc;
constructor(@Inject(DataSvc) dataSvc: DataSvc) {
// data for FlexChart
this.dataSvc = dataSvc;
this.data = this.dataSvc.getData(this.countries);
}
}
.wj-flexchart .wj-title {
font-weight: bold;
}
.wj-flexchart .wj-header .wj-title {
font-size: 18pt;
fill: #80044d;
}
.wj-flexchart .wj-footer .wj-title {
fill: #80044d;
}
.wj-flexchart .wj-axis-x .wj-title,
.wj-flexchart .wj-axis-y .wj-title {
font-style: italic;
}
The FlexChart has built-in support for tooltips. By default, the control displays
tooltips when the user touches or hovers the mouse on a data point.
The tooltip content is generated using a template that may contain the following
parameters:
seriesName : The name of the series that contains the chart element.
pointIndex : The index of the chart element within the series.
x : The x value of the chart element.
y : The y value of the chart element.
By default, the tooltip template is set to
<b>{seriesName}</b><br/>{x} {y},
and you can see how that works in the charts above.
In this example, we set the tooltip template to
<b>{seriesName}</b> <img src='resources/{x}.png'/><br/>{y},
which replaces the country name with the country's flag.
You can disable the chart tooltips by setting the template to an empty string.
<wj-flex-chart [itemsSource]="data"
[tooltipContent]="tooltipContent"
[bindingX]="'country'">
<wj-flex-chart-series [name]="'Sales'" [binding]="'sales'"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Expenses'" [binding]="'expenses'"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Downloads'" [binding]="'downloads'"></wj-flex-chart-series>
</wj-flex-chart>
export class AppCmp {
countries = 'US,Germany,UK,Japan,Italy,Greece'.split(',');
data: { country: string, downloads: number, sales: number, expenses: number }[];
//chart properties
tooltipContent = '<img src="resources/{x}.png" /> <b>{seriesName} </b><br/ > {y}';
protected dataSvc: DataSvc;
constructor(@Inject(DataSvc) dataSvc: DataSvc) {
// data for FlexChart
this.dataSvc = dataSvc;
this.data = this.dataSvc.getData(this.countries);
}
}
Result (live):
Styling Series
The FlexChart automatically picks colors for each series based on a default
palette, which you can override by setting the palette property.
But you can also override the default settings by setting the style
property of any series to an object that specifies SVG styling attributes,
including fill , stroke , strokeThickness , and so on.
The Series.style property is an exception to the general rule that
all styling in Wijmo is done through CSS. The exception reflects the fact
that many charts have dynamic series, which would be impossible to style
in advance. For example, a stock chart may show series selected by the
user while running the application.
The chart in this example uses the style and symbolStyle properties
to select style attributes for each series:
<wj-flex-chart [itemsSource]="data"
[bindingX]="'country'">
<wj-flex-chart-series [name]="'Sales'"
[binding]="'sales'"
[style]="{'fill':'green', 'stroke':'darkgreen', 'stroke-width': '1'}"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Expenses'"
[binding]="'expenses'"
[style]="{'fill':'red', 'stroke':'darkred', 'stroke-width': '1'}"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Downloads'"
[binding]="'downloads'"
[chartType]="'LineSymbols'"
[style]="{'stroke':'orange', 'stroke-width': '5'}"
[symbolStyle]="{'fill':'gold', 'stroke':'gold' }"
></wj-flex-chart-series>
</wj-flex-chart>
Result (live):
Customizing Axes
Use axis properties to customize the chart's axes,
including ranges (minimum and maximum), label format, tickmark spacing, and
gridlines.
The Axis class has boolean properties that allow you to turn features on
or off (axisLine , labels , majorTickMarks , and majorGrid .)
You can style the appearance of the features that are turned on using CSS.
<wj-flex-chart [itemsSource]="data"
[bindingX]="'country'">
<wj-flex-chart-axis [wjProperty]="'axisX'"
[axisLine]="true"
[majorGrid]="true"></wj-flex-chart-axis>
<wj-flex-chart-axis [wjProperty]="'axisY'"
[format]="'c0'"
[max]="10000"
[majorUnit]="2000"
[axisLine]="true"
[majorGrid]="true"></wj-flex-chart-axis>
<wj-flex-chart-series [name]="'Sales'"
[binding]="'sales'"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Expenses'"
[binding]="'expenses'"></wj-flex-chart-series>
</wj-flex-chart>
Result (live):
Theming
The appearance of the FlexChart is defined in CSS. In addition to the default theme, we
include about a dozen professionally designed themes that customize the appearance of
all Wijmo controls to achieve a consistent, attractive look.
To customize the appearance of the chart, inspect the elements you want to style and
create some CSS rules that apply to those elements.
For example, if you right-click one of the labels on the X axis in IE or Chrome, you
will see that it is an element with the "wj-label" class, that it is contained in an
element with the "wj-axis-x" class, which is contained in the the top-level control
element, which has the "wj-flexchart" class. The first CSS rule in this example uses
this information to customize the X labels. The rule selector adds the additional
requirement that the parent element must be have the "wj-flexchart" and the
"custom-flex-chart" classes. Without this, the rule would apply to all charts on the
page.
<wj-flex-chart [class]="'custom-flex-chart'"
[itemsSource]="data"
[bindingX]="'country'">
<wj-flex-chart-series [name]="'Sales'" [binding]="'sales'"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Expenses'" [binding]="'expenses'"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Downloads'" [binding]="'downloads'"></wj-flex-chart-series>
</wj-flex-chart>
/* custom chart theme */
.custom-flex-chart {
height: 400px;
background-color: white;
box-shadow: 4px 4px 10px 0px rgba(50, 50, 50, 0.75);
padding: 8px;
margin-bottom: 12px;
display:block;
}
.custom-flex-chart .wj-axis-x .wj-label {
font-family: Courier New, Courier, monospace;
font-weight: bold;
}
.custom-flex-chart .wj-legend .wj-label {
font-family: Courier New, Courier, monospace;
font-weight: bold;
}
.custom-flex-chart .wj-legend > rect {
fill: #f8f8f8;
stroke: #c0c0c0;
}
.custom-flex-chart .wj-plot-area > rect {
fill: #f8f8f8;
stroke: #c0c0c0;
}
Result (live):
Selection Modes
The FlexChart allows you to select series or data points by clicking or touching them.
Use the selectionMode property to specify whether you want to allow selection
by series, by data point, or no selection at all (selection is off by default.)
Setting the selectionMode property to Series or Point causes
the FlexChart to update the Selection property when the user clicks the
mouse, and to apply the "wj-state-selected" class to selected chart elements.
The Selection property returns the currently selected series. To get the
currently selected data point, get the currently selected item within the
selected series using the Series.collectionView.currentItem property
as shown in the example.
<wj-flex-chart #selectionChart
[itemsSource]="data"
[bindingX]="'country'"
[tooltipContent]=""
[chartType]="chartType"
[selectionMode]="selectionMode">
<wj-flex-chart-series [name]="'Sales'" [binding]="'sales'"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Expenses'" [binding]="'expenses'"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Downloads'" [binding]="'downloads'"></wj-flex-chart-series>
</wj-flex-chart>
<wj-menu [(value)]="selectionMode" [header]="'Selection Mode'">
<wj-menu-item [value]="'None'">None</wj-menu-item>
<wj-menu-item [value]="'Series'">Series</wj-menu-item>
<wj-menu-item [value]="'Point'">Point</wj-menu-item>
</wj-menu>
<wj-menu [(value)]="chartType" [header]="'Chart Type'">
<wj-menu-item [value]="'Column'">Column</wj-menu-item>
<wj-menu-item [value]="'Bar'">Bar</wj-menu-item>
<wj-menu-item [value]="'Scatter'">Scatter</wj-menu-item>
<wj-menu-item [value]="'Line'">Line</wj-menu-item>
<wj-menu-item [value]="'LineSymbols'">LineSymbols</wj-menu-item>
<wj-menu-item [value]="'Area'">Area</wj-menu-item>
<wj-menu-item [value]="'Spline'">Spline</wj-menu-item>
<wj-menu-item [value]="'SplineSymbols'">SplineSymbols</wj-menu-item>
<wj-menu-item [value]="'SplineArea'">SplineArea</wj-menu-item>
</wj-menu>
<div [ngStyle]="{display: (selectionMode == 'None' || selectionChart.selection == null) ? 'none' : ''}">
<h4>
Current Selection
</h4>
<p>
Series: <b>{{selectionChart.selection? selectionChart.selection.name : ''}}</b>
</p>
<dl class="dl-horizontal" *ngIf="selectionChart.selection && selectionChart.selection.collectionView && selectionChart.selection.collectionView.currentItem">
<dt>Country</dt>
<dd>{{selectionChart.selection.collectionView.currentItem.country}}</dd>
<dt>Sales</dt>
<dd>{{selectionChart.selection.collectionView.currentItem.sales | number:'3.1-2'}}</dd>
<dt>Expenses</dt>
<dd>{{selectionChart.selection.collectionView.currentItem.expenses | number:'3.1-2'}}</dd>
<dt>Downloads</dt>
<dd>{{selectionChart.selection.collectionView.currentItem.downloads | number:'3.1-2'}}</dd>
</dl>
</div>
export class AppCmp {
countries = 'US,Germany,UK,Japan,Italy,Greece'.split(',');
data: { country: string, downloads: number, sales: number, expenses: number }[];
//chart properties
chartType = 'Column';
selectionMode = 'Series';
protected dataSvc: DataSvc;
constructor(@Inject(DataSvc) dataSvc: DataSvc) {
// data for FlexChart
this.dataSvc = dataSvc;
this.data = this.dataSvc.getData(this.countries);
}
}
Result (live):
None
Series
Point
Column
Bar
Scatter
Line
LineSymbols
Area
Spline
SplineSymbols
SplineArea
Current Selection
Series: {{selectionChart.selection? selectionChart.selection.name : ''}}
Country
{{selectionChart.selection.collectionView.currentItem.country}}
Sales
{{selectionChart.selection.collectionView.currentItem.sales | number:'3.1-2'}}
Expenses
{{selectionChart.selection.collectionView.currentItem.expenses | number:'3.1-2'}}
Downloads
{{selectionChart.selection.collectionView.currentItem.downloads | number:'3.1-2'}}
Toggle Series
The Series class has a visibility property that allows you to
determine whether a series should be shown in the chart and in the legend,
only in the legend, or completely hidden.
This sample shows how you can use the visibility property to toggle
the visibility of a series using two methods:
Clicking on legend entries:
The chart directive sets the chart's legendToggle property to true,
which toggles the visibility property of a series when its legend entry is
clicked.
Using checkboxes:
The page uses Angular directives to bind input controls directly to the visibility
property of each series.
<wj-flex-chart #toggleChart [itemsSource]="data" [legendToggle]="true" >
<wj-flex-chart-series [name]="'Sales'" [binding]="'sales'" [(visibility)]="series1Visible"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Expenses'" [binding]="'expenses'" [(visibility)]="series2Visible"></wj-flex-chart-series>
<wj-flex-chart-series [name]="'Downloads'" [binding]="'downloads'" [(visibility)]="series3Visible"></wj-flex-chart-series>
</wj-flex-chart>
<!-- toggle series with checkboxes -->
Sales <input type="checkbox" #salesChecked
(click)="seriesVisible(0, salesChecked.checked)"
[checked]="toggleChart.series[0].visibility===0" /><br />
Expenses <input type="checkbox" #expensesChecked
(click)="seriesVisible(1, expensesChecked.checked)"
[checked]="toggleChart.series[1].visibility===0"/><br />
Downloads <input type="checkbox" #downloadsChecked
(click)="seriesVisible(2, downloadsChecked.checked)"
[checked]="toggleChart.series[2].visibility===0"/>
export class AppCmp {
countries = 'US,Germany,UK,Japan,Italy,Greece'.split(',');
data: { country: string, downloads: number, sales: number, expenses: number }[];
// chart properties
selectionMode = 'Series';
series1Visible = wjcChart.SeriesVisibility.Visible;
series2Visible = wjcChart.SeriesVisibility.Visible;
series3Visible = wjcChart.SeriesVisibility.Visible;
protected dataSvc: DataSvc;
constructor(@Inject(DataSvc) dataSvc: DataSvc) {
// data for FlexChart
this.dataSvc = dataSvc;
this.data = this.dataSvc.getData(this.countries);
}
seriesVisible = (idx, checked) => {
if (idx === 0) {
this.series1Visible = checked ?
wjcChart.SeriesVisibility.Visible : wjcChart.SeriesVisibility.Hidden;
} else if (idx === 1) {
this.series2Visible = checked ?
wjcChart.SeriesVisibility.Visible : wjcChart.SeriesVisibility.Hidden;
} else if (idx === 2) {
this.series3Visible = checked ?
wjcChart.SeriesVisibility.Visible : wjcChart.SeriesVisibility.Hidden;
}
}
}
Result (live):
Sales
Expenses
Downloads
Gradient Colors
The FlexChart supports gradient colors.
The gradient descriptor is an expression formatted as
follows: <type>(<coords>)<colors>[:<offset>[:<opacity>]][-<colors>[:<offset>[:<opacity>]]]-<colors>[:<offset>[:<opacity>]].
The <type> can be either linear or radial.
The uppercase L or R letters indicate absolute coordinates offset from the SVG surface.
Lowercase l or r letters indicate coordinates calculated relative to the element to which the gradient is applied.
Coordinates specify a linear gradient vector as x1, y1, x2, y2,
or a radial gradient as cx, cy, r and optional fx, fy, fr
specifying a focal point away from the center of the circle.
Specify <colors> as a list of dash-separated CSS color values.
Each color may be followed by a custom offset and opacity value, separated with a colon character.
Linear gradient format example:
'l(0,0,1,0)#ff0000-#00ff00-#0000ff', 'L(0,0,300,300)#ff0000:0.2:0.2-00ff00:0.8'
Radial gradient format example:
'r(0.5,0.5,1)#ff0000-#0000ff', 'R(100,100,100,200,200,200)#ff0000-#0000ff'
Basic
Select from the predefined gradient colors to see the different appearances.
<wj-flex-chart [itemsSource]="data"
bindingX="country">
<wj-flex-chart-series binding="sales" [style]="predefinedColor"></wj-flex-chart-series>
</wj-flex-chart>
<div class="dl-horizontal">
<wj-menu #predefinedColorMenu [(value)]="predefinedColor" header="Color">
<wj-menu-item [value]="{fill:'l(0,0,1,0)#89f7fe-#66a6ff'}">Light Blue - {fill:'l(0, 0, 1, 0)#89f7fe-#66a6ff'}</wj-menu-item>
<wj-menu-item [value]="{fill:'l(0,0,0,1)#13547a-#80d0c7'}">Aqua - {fill:'l(0, 0, 0, 1)#13547a-#80d0c7'}</wj-menu-item>
<wj-menu-item [value]="{fill:'l(0,0,1,1)#ff0844-#ffb199'}">Red - {fill:'l(0, 0, 1, 1)#ff0844-#ffb199'}</wj-menu-item>
<wj-menu-item [value]="{fill:'l(0,0,1,0)#b224ef-#7579ff-#b224ef'}">Purple - {fill:'l(0, 0, 1, 0)#b224ef-#7579ff-#b224ef'}</wj-menu-item>
<wj-menu-item [value]="{fill:'r(0.5,0.5,0.7)#cc208e-#6713d2'}">Plum - {fill:'r(0.5,0.5,0.7)#cc208e-#6713d2'}</wj-menu-item>
<wj-menu-item [value]="{fill:'l(0,0,1,0)#30cfd0-#330867'}">Deep Blue - {fill:'l(0, 0, 1, 0)#30cfd0-#330867'}</wj-menu-item>
<wj-menu-item [value]="{fill:'l(0,0,0,1)#e27f00-#ae1a73'}">Orange - {fill:'l(0, 0, 0, 1)#e27f00-#ae1a73'}</wj-menu-item>
<wj-menu-item [value]="{fill:'l(0,0,1,1)#abd800-#5c7e00'}">Green - {fill:'l(0, 0, 1, 1)#abd800-#5c7e00'}</wj-menu-item>
</wj-menu>
</div>
export class AppCmp {
predefinedColor = { fill: 'l(0,0,1,0)#89f7fe-#66a6ff' };
@ViewChild('predefinedColorMenu') predefinedColorMenu: wjcInput.Menu;
ngAfterViewInit() {
this.predefinedColorMenu.selectedIndex = 0;
}
}
Result (live):
Light Blue - l(0, 0, 1, 0)#89f7fe-#66a6ff
Aqua - l(0, 0, 0, 1)#13547a-#80d0c7
Red - l(0, 0, 1, 1)#ff0844-#ffb199
Purple - l(0, 0, 1, 0)#b224ef-#7579ff-#b224ef
Plum - r(0.5,0.5,0.7)#cc208e-#6713d2
Deep Blue - l(0, 0, 1, 0)#30cfd0-#330867
Orange - l(0, 0, 0, 1)#e27f00-#ae1a73
Green - l(0, 0, 1, 1)#abd800-#5c7e00
Advanced
Set multiple options to customize gradient color.
<wj-flex-chart [itemsSource]="data"
#gradientColorChart>
<wj-flex-chart-series [binding]="'sales'"></wj-flex-chart-series>
</wj-flex-chart>
<dl class="dl-horizontal">
<dt>Generated fill string:</dt>
<dd>
<label>{{ gradientFill }}</label>
</dd>
</dl>
<dl class="dl-horizontal">
<dt></dt>
<dd>
<wj-menu #gradientChartTypeMenu value="gradientChartType" header="Chart Type"
(itemClicked)="gradientChartTypeChanged(gradientChartTypeMenu)">
<wj-menu-item value="0">Column</wj-menu-item>
<wj-menu-item value="1">Bar</wj-menu-item>
<wj-menu-item value="5">Area</wj-menu-item>
<wj-menu-item value="11">SplineArea</wj-menu-item>
</wj-menu>
</dd>
</dl>
<dl class="dl-horizontal">
<dt></dt>
<dd>
<wj-menu #gradientTypeMenu value="l" header="Type"
(itemClicked)="gradientTypeChanged(gradientTypeMenu)">
<wj-menu-item value="l">Linear</wj-menu-item>
<wj-menu-item value="r">Radial</wj-menu-item>
</wj-menu>
</dd>
</dl>
<dl class="dl-horizontal" [hidden]="gradientTypeMenu.selectedValue === 'r'">
<dt></dt>
<dd>
<wj-menu #gradientDirectionMenu value="horizontal" header="Direction"
(itemClicked)="gradientDirectionChanged(gradientDirectionMenu)">
<wj-menu-item value="horizontal">Horizontal</wj-menu-item>
<wj-menu-item value="vertical">Vertical</wj-menu-item>
</wj-menu>
</dd>
</dl>
<dl class="dl-horizontal">
<dt>Start Color:</dt>
<dd>
<wj-input-color #inputStartColor (valueChanged)="startColorChanged(inputStartColor)" value="#ff0000">
</wj-input-color>
</dd>
</dl>
<dl class="dl-horizontal">
<dt>Start Offset:</dt>
<dd>
<wj-input-number #inputStartOffset (valueChanged)="startOffsetChanged(inputStartOffset)"
[min]="0"
[value]="0"
[max]="1"
[step]=".1">
</wj-input-number>
</dd>
</dl>
<dl class="dl-horizontal">
<dt>Start Opacity:</dt>
<dd>
<wj-input-number #inputStartOpacity (valueChanged)="startOpacityChanged(inputStartOpacity)"
[min]="0"
[value]="1"
[max]="1"
[step]=".1">
</wj-input-number>
</dd>
</dl>
<dl class="dl-horizontal">
<dt>End Color:</dt>
<dd>
<wj-input-color #inputEndColor (valueChanged)="endColorChanged(inputEndColor)" value="#0000ff">
</wj-input-color>
</dd>
</dl>
<dl class="dl-horizontal">
<dt>End Offset:</dt>
<dd>
<wj-input-number #inputEndOffset (valueChanged)="endOffsetChanged(inputEndOffset)"
[min]="0"
[value]="1"
[max]="1"
[step]=".1">
</wj-input-number>
</dd>
</dl>
<dl class="dl-horizontal">
<dt>End Opacity:</dt>
<dd>
<wj-input-number #inputEndOpacity (valueChanged)="endOpacityChanged(inputEndOpacity)"
[min]="0"
[value]="1"
[max]="1"
[step]=".1">
</wj-input-number>
</dd>
</dl>
export class AppCmp {
// generate some random data
countries = 'US,Germany,UK,Japan,Italy,Greece'.split(',');
gradientChartType = wjcChart.ChartType.Column;
data: { country: string, downloads: number, sales: number, expenses: number }[];
//chart properties
gradientFill: string;
@ViewChild('gradientColorChart') gradientColorChart: wjcChart.FlexChart;
@ViewChild('gradientTypeMenu') gradientTypeMenu: wjcInput.Menu;
@ViewChild('gradientDirectionMenu') gradientDirectionMenu: wjcInput.Menu;
@ViewChild('inputStartColor') startColor: wjcInput.InputColor;
@ViewChild('inputStartOffset') startOffset: wjcInput.InputNumber;
@ViewChild('inputStartOpacity') startOpacity: wjcInput.InputNumber;
@ViewChild('inputEndColor') endColor: wjcInput.InputColor;
@ViewChild('inputEndOffset') endOffset: wjcInput.InputNumber;
@ViewChild('inputEndOpacity') endOpacity: wjcInput.InputNumber;
//help
_toAddData = null;
_interval = null;
protected dataSvc: DataSvc;
constructor( @Inject(DataSvc) dataSvc: DataSvc) {
this.dataSvc = dataSvc;
this.data = this.dataSvc.getData(this.countries);
}
ngAfterViewInit() {
this._applyGradientColor();
}
gradientChartTypeChanged = (sender: wjcInput.Menu) => {
if (this.gradientColorChart == null) {
return;
}
this.gradientColorChart.chartType = +sender.selectedValue;
};
gradientDirectionChanged = (sender: wjcInput.Menu) => {
this._applyGradientColor();
};
startColorChanged = (sender: wjcInput.InputColor) => {
this._applyGradientColor();
};
startOffsetChanged = (sender: wjcInput.InputNumber) => {
if (sender.value < sender.min || sender.value > sender.max) {
return;
}
this._applyGradientColor();
};
startOpacityChanged = (sender: wjcInput.InputNumber) => {
if (sender.value < sender.min || sender.value > sender.max) {
return;
}
this._applyGradientColor();
};
endColorChanged = (sender: wjcInput.InputColor) => {
this._applyGradientColor();
};
endOffsetChanged = (sender: wjcInput.InputNumber) => {
if (sender.value < sender.min || sender.value > sender.max) {
return;
}
this._applyGradientColor();
};
endOpacityChanged = (sender: wjcInput.InputNumber) => {
if (sender.value < sender.min || sender.value > sender.max) {
return;
}
this._applyGradientColor();
};
private _applyGradientColor = () => {
if (this.gradientColorChart == null) {
return;
}
var chart = this.gradientColorChart,
color = '',
type = this.gradientTypeMenu.selectedValue,
direction = this.gradientDirectionMenu.selectedValue;
color = type;
if (type === 'l') {
if (direction === 'horizontal') {
color += '(0, 0, 1, 0)';
} else {
color += '(0, 0, 0, 1)';
}
} else {
color += '(0.5, 0.5, 0.5)'
}
color += this.startColor.value;
if (this.startOffset.value !== 0 || this.startOpacity.value !== 1) {
color += ':' + this.startOffset.value;
}
if (this.startOpacity.value !== 1) {
color += ':' + this.startOpacity.value;
}
color += '-' + this.endColor.value;
if (this.endOffset.value !== 1 || this.endOpacity.value !== 1) {
color += ':' + this.endOffset.value;
}
if (this.endOpacity.value !== 1) {
color += ':' + this.endOpacity.value;
}
this.gradientFill = color;
chart.series[0].style = {
fill: color
};
}
}
Result (live):
Generated fill string:
{{ gradientFill }}
Column
Bar
Area
SplineArea
Linear
Radial
Horizontal
Vertical
Start Color:
Start Offset:
Start Opacity:
End Color:
End Offset:
End Opacity:
Dynamic Charts
The FlexChart uses an ICollectionView internally, so any changes you make to
the data source are automatically reflected in the chart.
In this sample, we use a timer to add items to the data source, discarding old items
to keep the total count at 200. The result is a dynamic chart that scrolls as new
data arrives.
<wj-flex-chart [itemsSource]="trafficData"
[chartType]="'Area'"
[stacking]="'Stacked'"
[bindingX]="'time'">
<wj-flex-chart-axis [wjProperty]="'axisX'" [format]="'mm:ss'"></wj-flex-chart-axis>
<wj-flex-chart-series [name]="'Trucks'" [binding]="'trucks'"></wj-flex-chart-series>
</wj-flex-chart>
<dl class="dl-horizontal">
<dt>Update Speed</dt>
<dd>
<div class="btn-group">
<button type="button" class="btn btn-default" (click)="setInterval(200)">Slow</button>
<button type="button" class="btn btn-default" (click)="setInterval(100)">Medium</button>
<button type="button" class="btn btn-default" (click)="setInterval(50)">Fast</button>
<button type="button" class="btn btn-default" (click)="setInterval(0)">Stop</button>
</div>
</dd>
</dl>
export class AppCmp {
trafficData: wjcCore.ObservableArray;
// help
_toAddData = null;
_interval = null;
constructor() {
// data for FlexChart
this.trafficData = new wjcCore.ObservableArray();
this.setInterval(500);
}
setInterval = (interval) => {
if (this._toAddData) {
clearTimeout(this._toAddData);
this._toAddData = null;
}
this._interval = interval;
if (interval) {
this._toAddData = setTimeout(this._addTrafficItem);
}
}
private _addTrafficItem = () => {
var len = this.trafficData.length,
last = len ? this.trafficData[len - 1] : null,
trucks = last ? last.trucks : 0,
ships = last ? last.ships : 0,
planes = last ? last.planes : 0;
trucks = Math.max(0, trucks + Math.round(Math.random() * 50 - 25));
ships = Math.max(0, ships + Math.round(Math.random() * 10 - 5));
planes = Math.max(0, planes + Math.round(Math.random() * 10 - 5));
// add random data, limit array length
this.trafficData.push({ time: new Date(), trucks: trucks, ships: ships, planes: planes });
if (this.trafficData.length > 200) {
this.trafficData.splice(0, 1);
}
// keep adding
if (this._interval) {
this._toAddData = setTimeout(this._addTrafficItem, this._interval);
}
}
}
Result (live):
Update Speed
Slow
Medium
Fast
Stop