入门
在AngularJS应用中开始使用FlexChart的步骤:
- 为AngularJS,Wijmo和Wijmo的AngularJS指令添加引用。
-
在应用模块中包含Wijmo 5指令:
var app = angular.module('app', ['wj']);
- 添加一个控制器来提供数据和逻辑
- 向当前页面添加一个FlexChart,并且将它与数据绑定。
- 添加一些CSS来个性化图表的外观。
<html>
<head>
<link rel="stylesheet" href="css/bootstrap.css"/>
<link rel="stylesheet" href="css/wijmo.css"/>
<link href="css/app.css" rel="stylesheet"/>
<script src="scripts/angular.js"></script>
<script src="scripts/wijmo.js"></script>
<script src="scripts/wijmo.chart.js"></script>
<script src="scripts/wijmo.angular.js"></script>
<script src="scripts/app.js"></script>
</head>
<body ng-app="app" ng-controller="appCtrl">
<!-- this is the chart -->
<wj-flex-chart
items-source="data"
binding-x="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>
</body>
</html>
// declare app module
var app = angular.module('app', ['wj']);
// app controller provides data
app.controller('appCtrl', function appCtrl($scope) {
// generate some random data
var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','),
data = [];
for (var 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
});
}
// add data array to scope
$scope.data = data;
});
/* 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;
}
结果:
图表类型
FlexChart控件有三个属性允许你来自定义图表的类型:
-
chartType:对于所有系列对象选择默认的图表类型。个别系列对象可以覆盖它。
-
stacking: 确定系列对象是否独立地绘制,堆积或百分比堆积。
-
rotated: 翻转X轴和Y轴,导致X变为垂直,Y变为水平。
以下这个示例允许你查看当你改变这些属性的效果:
<wj-flex-chart
items-source="data"
chart-type="{{chartProps.chartType}}"
stacking="{{chartProps.stacking}}"
rotated="{{chartProps.rotated}}"
binding-x="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="chartProps.chartType" header="图表类型" >
<wj-menu-item value="0">Column</wj-menu-item>
<wj-menu-item value="1">Bar</wj-menu-item>
<wj-menu-item value="2">Scatter</wj-menu-item>
<wj-menu-item value="3">Line</wj-menu-item>
<wj-menu-item value="4">LineSymbols</wj-menu-item>
<wj-menu-item value="5">Area</wj-menu-item>
<wj-menu-item value="9">Spline</wj-menu-item>
<wj-menu-item value="10">SplineSymbols</wj-menu-item>
<wj-menu-item value="11">SplineArea</wj-menu-item>
</wj-menu>
<wj-menu value="chartProps.stacking" header="堆积" >
<wj-menu-item value="0">无</wj-menu-item>
<wj-menu-item value="1">堆积</wj-menu-item>
<wj-menu-item value="2">百分比堆积</wj-menu-item>
</wj-menu>
<wj-menu value="chartProps.rotated" header="是否旋转" >
<wj-menu-item value="false">False</wj-menu-item>
<wj-menu-item value="true">True</wj-menu-item>
</wj-menu>
// add chart properties to scope
$scope.chartProps = {
chartType: wijmo.chart.ChartType.Column,
stacking: wijmo.chart.Stacking.None,
rotated: false
};
结果:
Column
Bar
Scatter
Line
LineSymbols
Area
Spline
SplineSymbols
SplineArea
无
堆积
百分比堆积
False
True
漏斗图
以下示例说明了如何创建和自定漏斗图:
<wj-flex-chart control="funnelChart"
items-source="funnelData"
chart-type="Funnel"
binding-x="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>
<div id="funnelNeckWidth"></div>
<wj-input-number control="inputNeckWidth"
value="neckWidth"
min="0"
max="1"
step=".1">
</wj-input-number>
</dd>
</dl>
<dl class="dl-horizontal">
<dt>Neck Height</dt>
<dd>
<div id="funnelNeckHeight"></div>
<wj-input-number control="inputNeckHeight"
value="neckHeight"
min="0"
max="1"
step=".1">
</wj-input-number>
</dd>
</dl>
<dl class="dl-horizontal">
<dt></dt>
<dd>
<wj-menu header="Funnel Type: <b>{{ funnelType }}</b>"
item-clicked="funnelTypeChanged(s, e)">
<wj-menu-item value="'default'">Default</wj-menu-item>
<wj-menu-item value="'rectangle'">Rectangle</wj-menu-item>
</wj-menu>
</dd>
</dl>
$scope.funnelChart = null;
$scope.inputNeckWidth = null;
$scope.inputNeckHeight = null;
$scope.neckWidth = 0.2;
$scope.neckHeight = 0.2;
$scope.funnelType = 'default';
$scope.$watch('funnelChart', function () {
var funnelChart = $scope.funnelChart;
if (funnelChart != null) {
funnelChart.options = {
funnel: {
neckWidth: 0.2,
neckHeight: 0.2,
type: 'default'
}
};
funnelChart.dataLabel.content = '{y}';
}
});
$scope.$watch('neckWidth', function () {
var neckWidth = $scope.inputNeckWidth,
val = $scope.neckWidth;
if (neckWidth != null) {
if (val < neckWidth.min || val > neckWidth.max) {
return;
}
$scope.funnelChart.options.funnel.neckWidth = val;
$scope.funnelChart.refresh(true);
}
});
$scope.$watch('neckHeight', function () {
var neckHeight = $scope.inputNeckHeight,
val = $scope.neckHeight;
if (neckHeight != null) {
if (val < neckHeight.min || val > neckHeight.max) {
return;
}
$scope.funnelChart.options.funnel.neckHeight = val;
$scope.funnelChart.refresh(true);
}
});
$scope.funnelTypeChanged = function (sender) {
$scope.funnelChart.options.funnel.type = sender.selectedValue;
$scope.funnelChart.refresh(true);
};
Result (live):
- 领宽
-
- 领高
-
-
Default
Rectangle
混合图表类型
你可以对每个图表系列使用不同的图表类型,这是通过对它这个系列本身设置chartType属性。
这会覆盖图表的默认图表类型。
在以下的示例,这个图表的chartType属性被设为Column,
但是Downloads系列使用了LineAndSymbol类型覆盖它:
<wj-flex-chart
items-source="data"
chart-type="Column"
binding-x="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" chart-type="LineSymbols"></wj-flex-chart-series>
</wj-flex-chart>
结果:
图例和标题
使用legend属性来自定义图表图例的外观,
使用header,footer和坐标的title属性来向你的图表添加标题。
你可以使用CSS来确定图例和标题的样式。下面的CSS标签显示用于自定义图例和标题的外观的规则。
注意它们是SVG元素,所以你必须使用”fill”这样的CSS属性而不是”color”。
<wj-flex-chart
items-source="data"
binding-x="country"
header="{{chartProps.header}}"
footer="{{chartProps.footer}}">
<wj-flex-chart-legend
position="{{chartProps.legendPosition}}">
</wj-flex-chart-legend>
<wj-flex-chart-axis
wj-property="axisX"
title="{{chartProps.titleX}}">
</wj-flex-chart-axis>
<wj-flex-chart-axis
wj-property="axisY"
title="{{chartProps.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>页眉</dt><dd><input ng-model="chartProps.header" class="form-control"/></dd>
<dt>页尾</dt><dd><input ng-model="chartProps.footer" class="form-control"/></dd>
<dt>X轴标题</dt><dd><input ng-model="chartProps.titleX" class="form-control"/></dd>
<dt>Y轴标题</dt><dd><input ng-model="chartProps.titleY" class="form-control"/></dd>
<dt></dt>
<dd>
<wj-menu value="chartProps.legendPosition" header="图例" >
<wj-menu-item value="0">无</wj-menu-item>
<wj-menu-item value="1">左</wj-menu-item>
<wj-menu-item value="2">上</wj-menu-item>
<wj-menu-item value="3">右</wj-menu-item>
<wj-menu-item value="4">下</wj-menu-item>
</wj-menu>
</dd>
</dl>
// add chart properties to scope
$scope.chartProps = {
chartType: wijmo.chart.ChartType.Column,
legendPosition: wijmo.chart.Position.Right,
stacking: wijmo.chart.Stacking.None,
rotated: false,
header: 'Sample Chart',
footer: 'copyright (c) ComponentOne',
titleX: 'country',
titleY: 'amount'
};
.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;
}
FlexChart对工具提示有内置的支持。
默认情况下,当用户触摸或者悬停鼠标到一个数据点时,控件会显示工具提示。
工具提示的内容是使用一个可能包含下列参数的模板生成:
- seriesName: 包含图表元素的系列名称
- pointIndex: 系列中图表元素的参数
- x: 图表元素的x值
- y: 图表元素的y值
默认情况下,tooltip模板被设为<b>{seriesName}</b><br/>{x} {y}
,你可以在上面的图表看到它是如何工作的。
在这个示例中,我们设tooltip模板为<b>{seriesName}</b> <img src='resources/{x}.png'/><br/>{y}
,
它使用国家的国旗代替了国家的名字。
你可以通过设置模板为空字符串来禁用图表tooltips。
<wj-flex-chart
items-source="data"
tooltip-content="<img src='resources/{x}.png'/> <b>{seriesName}</b><br/>{y}"
binding-x="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>
结果:
样式系列
FlexChart为每个基于默认调色板的系列自动选取颜色,你可以通过设置palette属性来重写它。
但你也可以重写默认的属性,通过设置任意一个系列的style属性为一个对象,
它制定了SVG样式属性,包括fill, stroke, strokeThickness等等。
Series.style属性对在Wijmo中通过CSS设置样式的一般规则来说,是一个例外。
这个例外反映一个事实,许多图表有动态系列,这是不可能提前布置样式的。
比如,一个股票图表可能会展示用户在运行程序时才选中的系列。
这个示例中的图表使用了style和symbolStyle属性来为每个系列选择样式属性:
<wj-flex-chart
items-source="data"
binding-x="country">
<wj-flex-chart-series
name="Sales" binding="sales"
ng-attr-style="{fill:'green', stroke:'darkgreen', 'stroke-width': '1'}"></wj-flex-chart-series>
<wj-flex-chart-series
name="Expenses" binding="expenses"
ng-attr-style="{fill:'red', stroke:'darkred', 'stroke-width': '1'}"></wj-flex-chart-series>
<wj-flex-chart-series
name="Downloads" binding="downloads" chart-type="'LineSymbols'"
ng-attr-style="{ stroke:'orange', 'stroke-width': '5'}"
ng-attr-symbol-style="{fill:'gold', stroke:'gold' }"></wj-flex-chart-series>
</wj-flex-chart>
结果:
自定义轴
使用axis属性来自定义图表的坐标轴,包括范围(最小值和最大值)、便签格式、刻度间隔和网格线。
Axis类有布尔属性,允许你打开或关闭功能(如axisLine, labels, majorTickMarks和majorGrid)。
你可以使用CSS来设置这些已经打开的功能的样式。
<wj-flex-chart
items-source="data"
binding-x="country">
<wj-flex-chart-axis
wj-property="axisX"
axis-line="true"
major-grid="true">
</wj-flex-chart-axis>
<wj-flex-chart-axis
wj-property="axisY"
format="c0"
max="10000"
major-unit="2000"
axis-line="true"
major-grid="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>
结果:
主题
FlexChart的外观是在CSS中定义的。除了默认的主题,我们有十几个专业设计的主题。
它们自定义了所有Wijmo控件的外观来达到一致的,有吸引力的效果。
为了自定义图表的外观,检查你想要提供样式的元素并创建一些CSS规则来应用到这些元素中。
例如,如果你在IE或者谷歌浏览器上右击X轴上的一个标签,你会发现它是一个拥有”wj-label”类的元素,
它被包含在拥有”wj-flexchart”类的顶层控件元素中。这个示例中第一条CSS规则使用这条信息来自定义X标签。
规则选择器添加了额外的要求,父类元素必须拥有"wj-flexchart"类和"custom-flex-chart"类。
如果没有的话,这个规则会用于这个页面所有的图表。
<wj-flex-chart
class="custom-flex-chart"
items-source="data"
binding-x="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.wj-flexchart .wj-axis-x .wj-label {
font-family: Courier New, Courier, monospace;
font-weight: bold;
}
.custom-flex-chart.wj-flexchart .wj-legend .wj-label {
font-family: Courier New, Courier, monospace;
font-weight: bold;
}
.custom-flex-chart.wj-flexchart .wj-legend > rect {
fill: #f8f8f8;
stroke: #c0c0c0;
}
.custom-flex-chart.wj-flexchart .wj-plot-area > rect {
fill: #f8f8f8;
stroke: #c0c0c0;
}
结果:
选择模式
FlexChart允许你通过单击或者触摸选择系列或数据点。使用selectionMode属性来指定是否允许选择系列,
是否选择数据点或者无法选择(选择默认是关闭的)
设置selectionMode属性为Series或者Point会导致用户在单击鼠标的时候,
FlexChart自动更新Selection属性,
并且将"wj-state-selected"类应用到选中的图表元素中。
Selection属性返回当前选中的系列。要得到当前选中的数据点,
得到当前选定的项并在选中的系列中使用Series.collectionView.currentItem属性,正如示例所示。
<wj-flex-chart
items-source="data"
binding-x="country"
tooltip-content=""
chart-type="{{chartProps.chartType}}"
selection-mode="{{chartProps.selectionMode}}"
selection="chartProps.selection">
<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>
<div ng-hide="chartProps.selectionMode == 0 || chartProps.selection == null">
<h4>
Current Selection</h4>
<p>
Series: <b>{{chartProps.selection.name}}</b></p>
<dl class="dl-horizontal" ng-hide="chartProps.selectionMode != 2 || chartProps.selection.collectionView.currentItem == null">
<dt>Country</dt><dd>{{chartProps.selection.collectionView.currentItem.country}}</dd>
<dt>Sales</dt><dd>{{chartProps.selection.collectionView.currentItem.sales | number:2}}</dd>
<dt>Expenses</dt><dd>{{chartProps.selection.collectionView.currentItem.expenses | number:2}}</dd>
<dt>Downloads</dt><dd>{{chartProps.selection.collectionView.currentItem.downloads | number:0}}</dd>
</dl>
</div>
// add chart properties to scope
$scope.chartProps = {
chartType: wijmo.chart.ChartType.Column,
stacking: wijmo.chart.Stacking.None,
legendPosition: wijmo.chart.Position.Right,
rotated: false,
header: 'Sample Chart',
footer: 'copyright (c) ComponentOne',
titleX: 'country',
titleY: 'amount',
selectionMode: wijmo.chart.SelectionMode.Series,
selection: null
};
结果:
None
Series
Point
Column
Bar
Scatter
Line
LineSymbols
Area
Spline
SplineSymbols
SplineArea
当前选择
Series: {{chartProps.selection.name}}
- Country
- {{chartProps.selection.collectionView.currentItem.country}}
- Sales
- {{chartProps.selection.collectionView.currentItem.sales | number:2}}
- Expenses
- {{chartProps.selection.collectionView.currentItem.expenses | number:2}}
- Downloads
- {{chartProps.selection.collectionView.currentItem.downloads | number:0}}
切换系列
Series类有一个visibility属性,让你决定一个系列是否应该展现在图表和图例中,
或者只在图例中,或者完全隐藏。
这个示例演示你应该如何使用visibility属性来通过两种方法切换系列的可见性:
-
单击图例入口:
图表指令会设置图表的legendToggle属性为真,
当它的图例入口被单击的时候就会切换一个系列的visibility属性
-
使用checkbox:
这个页面使用Angular指令来将输入控件和每个系列的visibility属性绑定。
动态图表
FlexChart内部使用了ICollectionView,因此你对数据源做的任何更改都会自动反映在图表中。
在这个示例中,我们使用一个计时器来向数据源中增加项目,丢弃旧项目以保持总数为200。
结果就是一个动态的图表,当新数据到来时图表向右滚动。
<wj-flex-chart
items-source="trafficData"
chart-type="Area"
stacking="Stacked"
binding-x="time">
<wj-flex-chart-axis wj-property="axisX" format="mm:ss"></wj-flex-chart-axis>
<wj-flex-chart-series name="Trucks" binding="trucks"></wj-flex-chart-series>
<wj-flex-chart-series name="Ships" binding="ships"></wj-flex-chart-series>
<wj-flex-chart-series name="Planes" binding="planes"></wj-flex-chart-series>
</wj-flex-chart>
<div class="btn-group">
<button type="button" class="btn btn-default" ng-click="setInterval(200)">慢速</button>
<button type="button" class="btn btn-default" ng-click="setInterval(100)">中等</button>
<button type="button" class="btn btn-default" ng-click="setInterval(50)">快速</button>
<button type="button" class="btn btn-default" ng-click="setInterval(0)">停止</button>
</div>
// dynamic data
var toAddData;
$scope.trafficData = new wijmo.collections.ObservableArray();
$scope.setInterval = function (interval) {
if (toAddData) {
clearTimeout(toAddData);
toAddData = null;
}
$scope.interval = interval;
if (interval) {
toAddData = setTimeout(addTrafficItem);
}
};
$scope.setInterval(500);
function addTrafficItem() {
// add random data, limit array length
...
// keep adding
...
}