From 9a6ec62b9997c9bb3284fc3c07fdccbc14eba617 Mon Sep 17 00:00:00 2001 From: "xiaoqing.dongxq" Date: Fri, 26 Sep 2014 11:24:08 +0800 Subject: [PATCH] update docs --- README.md | 123 ++++++++- api/itemgroup.md | 26 ++ api/stacked.md | 23 ++ examples/area.md | 488 +++++++++++++++++++++++++++++++++++ examples/column.md | 602 +++++++++++++++++++++++++++++++++++++++++++ examples/line.md | 431 +++++++++++++++++++++++++++++++ examples/pie.md | 427 ++++++++++++++++++++++++++++++ examples/radar.md | 351 +++++++++++++++++++++++++ package.json | 2 +- src/base.js | 101 +++++--- src/cartesian.js | 48 +++- src/column.js | 19 +- src/itemgroup.js | 6 +- src/line.js | 49 ++-- src/pie.js | 14 +- src/stacked.js | 7 +- tests/column-spec.js | 97 +++++++ tests/line-spec.js | 6 +- tests/pie-spec.js | 2 +- wiki/01-base.md | 118 +++++++++ wiki/02-cartesian.md | 68 +++++ wiki/03-line.md | 274 ++++++++++++++++++++ wiki/04-area.md | 342 ++++++++++++++++++++++++ wiki/05-column.md | 60 +++++ wiki/06-pie.md | 210 +++++++++++++++ wiki/07-stacked.md | 74 ++++++ wiki/08-itemgroup.md | 13 + wiki/09-radar.md | 128 +++++++++ wiki/10-change.md | 13 + wiki/11-custom.md | 468 +++++++++++++++++++++++++++++++++ wiki/index.md | 47 ++++ 31 files changed, 4534 insertions(+), 103 deletions(-) create mode 100644 api/itemgroup.md create mode 100644 api/stacked.md create mode 100644 examples/area.md create mode 100644 examples/column.md create mode 100644 examples/line.md create mode 100644 examples/pie.md create mode 100644 examples/radar.md create mode 100644 wiki/01-base.md create mode 100644 wiki/02-cartesian.md create mode 100644 wiki/03-line.md create mode 100644 wiki/04-area.md create mode 100644 wiki/05-column.md create mode 100644 wiki/06-pie.md create mode 100644 wiki/07-stacked.md create mode 100644 wiki/08-itemgroup.md create mode 100644 wiki/09-radar.md create mode 100644 wiki/10-change.md create mode 100644 wiki/11-custom.md create mode 100644 wiki/index.md diff --git a/README.md b/README.md index 619c763..c290f3e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,18 @@ --- +图表序列,本模块包含常用的图表类型 + * 折线图 Series.Line + * 区域图 Series.Area + * 柱状图 Series.Column + * 饼图 Series.Pie + +文档 + + * [wiki 文档](wiki/) + +--- ## Install @@ -13,6 +24,114 @@ $ spm install achart-series --save ## Usage ```js -var achartSeries = require('achart-series'); -// use achartSeries +var Series = require('achart-series'); + ``` + + +## Series + + * 所有图表序列的基类,有图表序列的基本属性和方法 + +### 配置项 + + * autoPaint 是否自动绘制序列 + * data 渲染图表序列的数据 + * markers 显示的markers,如果为null则不显示 ,参考[markers文档](http://spmjs.io/docs/achart-markers/) + * labels 显示的文本,如果null则不显示文本,参考[labels文档](http://spmjs.io/docs/achart-labels/) + * animate 是否执行动画,分为初始动画和更改动画 + * duration 初始时执行动画的时间 + * enableMouseTracking 鼠标移动到数据序列图中是否触发事件,默认true + * stickyTracking 是否随着鼠标在画板上移动触发相应的事件,默认true + * xField 当数据传入是一个个的Object对象时,标示x轴的字段,不一定必须有x坐标轴 + * yField 当数据传入是一个个的Object对象时,标示y轴的字段,不一定必须有x坐标轴 + +### 方法 + + * paint() 绘制序列 + * repaint() 重绘 + * changeData(data,redraw) 重新设置数据,是否同时刷新 + * getPoints() 获取数据序列的点集合 + * getData(axisType) 获取坐标轴对应的数据 + * getTrackingInfo() 获取鼠标移动与该series的焦点信息 + +### 事件 + + * beforepaint 开始绘制 + * afterpaint 绘制完成后 + * datachange 数据发生改变 + * ev.data 标示发生改变的数据 + +## Cartesian + + * 坐标内的数据序列,折线图、柱状图等都是这个类的子类 + +### 配置项 + + * xAxis x坐标轴的配置项,创建后可以获取对应的x坐标轴 + * yAxis x坐标轴的配置项,创建后可以获取对应的y坐标轴 + * pointInterval 如果x坐标是数字类型,则通过点的间距来决定点代表的x的值,即 : index * pointInterval + * pointStart 如果横坐标是数字、时间类型,点的起始值 + * invert 坐标轴是否翻转 + +### 方法 + + * getBaseValue() 如果y轴存在0则是0对应的坐标轴,否则是最小的值对应的y轴坐标 + * isInCircle() 是否在雷达图中 + +## Line + + * 折线图,继承自[Cartesian](#cartesian),区域图从折线图中继承而来 + +### 配置项 + + * line 折线的配置信息,[line配置](http://spmjs.io/docs/achart-canvas/#shape-基类) + * lineActived 折线图激活时线的配置信息,[line配置](http://spmjs.io/docs/achart-canvas/#shape-基类) + * connectNulls 断点是否忽略,默认false + * smooth 是否将折线转换成平滑的曲线 + * tolerance 扩大折线相应鼠标的范围 + +## Area + + * 继承自[Line](#line),使用了[stacked(层叠) ](api/stacked.md)扩展 + +### 配置项 + + * area 区域的配置信息,[area配置](http://spmjs.io/docs/achart-canvas/#shape-基类) + +## Column + + * 柱状图,继承自[Cartesian](#cartesian),[stacked(层叠) ](api/stacked),[itemgroup(包含子项) ](api/itemgroup.md)扩展 + +配置项和方法都继承自父类和扩展 + + * [Cartesian](#cartesian) + * [stacked(层叠) ](api/stacked) + * [itemgroup(包含子项) ](api/itemgroup.md) + +## Pie + + * 饼图继承自[Series](#series),使用[stacked(层叠) ](api/stacked),[itemgroup(包含子项) ](api/itemgroup.md)扩展 + +### 配置信息 + + * size 大小,用百分比的字符串标示,默认'80%' + * innerSize 内部大小,如果有值则是一个环图 + * center 饼图的圆心位置,默认['50%','50%'],也可以是数字,是相对于画布的位置 + * colors 饼图子项对应的颜色 + * colorHighlight 将自动获取的颜色提升亮度,0-1,默认为0 + * radius 半径,如果没设置,通过size计算得出 + * innerRadius 内部半径,如果没设置,通过innerSize设置 + * startAngle 开始的角度,默认为-90 + * endAngle 结束的角度,默认为 270 + * labelHeight 文本的高度,防止出现文本层叠,默认 16 + * labelLine 文本的连接线 + + + +### 继承的方法和配置项 + + * [stacked(层叠) ](api/stacked) + * [itemgroup(包含子项) ](api/itemgroup.md) + + diff --git a/api/itemgroup.md b/api/itemgroup.md new file mode 100644 index 0000000..2c813bf --- /dev/null +++ b/api/itemgroup.md @@ -0,0 +1,26 @@ +# ItemGroup API + +--- + +图表序列中包含子项的扩展,例如柱状图、饼图 + +--- + +## 配置型 + + * item 子项的配置信息 + * allowPointSelect 是否允许点(子项)选中 + * cancelSelect 选中子项后,再次点击是否取消选中 + +## 公用方法 + + * setSelected(item) 选中子项 + * clearSelected(item) 清除子项选中 + * isSelected(item) 是否选中 + * getSelected(item) 获取选中的子项 + * getItems() 获取子项 + +## 提供扩展覆盖的方法 + + * setItemSelected(item,selected) 添加、移除选项的选中状态 + diff --git a/api/stacked.md b/api/stacked.md new file mode 100644 index 0000000..2318300 --- /dev/null +++ b/api/stacked.md @@ -0,0 +1,23 @@ +# Stacked API + +--- + +处理图表序列层叠的扩展,例如柱状图和区域图的层叠 + +--- + +## 配置项 + + * stackType + * - none : 不进行层叠 + * - normal : 一般的层叠方式,后面的数据序列的y值在前一个数据序列基础上显示 + * - percent : 按照百分比进行层叠展示 + +## 共有方法 + + * isStacked() 是否发生层叠 + +## 提供给类调用的方法(protected) + + * processStackedPoint(point) 将点处理成层叠的点 + diff --git a/examples/area.md b/examples/area.md new file mode 100644 index 0000000..1c6b2f2 --- /dev/null +++ b/examples/area.md @@ -0,0 +1,488 @@ +# Area + +--- + +区域图demo + +--- +## Area + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'a1', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : -5, + max : 40, + position:'left', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var series = canvas.addGroup(Series.Area,{ + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + color : '#2f7ed8', + line : { + 'stroke-width': 1, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + lineActived : { + 'stroke-width': 2 + }, + animate : false, + area : { + stroke : 'none', + fill : 'rgb(124, 181, 236)', + 'fill-opacity' : 0.5 + }, + markers : { + marker : { + + symbol : 'circle', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] + }); +}); +```` + +## break point + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'a2', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : -5, + max : 40, + position:'left', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + //不连接断点 + var series = canvas.addGroup(Series.Area,{ + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + color : '#2f7ed8', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + lineActived : { + 'stroke-width': 3 + }, + animate : false, + markers : { + marker : { + + symbol : 'circle', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [7.0, 6.9, 9.5, 14.5, null, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] + }); + + //断点进行连接 + var series1 = canvas.addGroup(Series.Area,{ + xAxis : xAxis, + yAxis : yAxis, + color : '#910000', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + animate : true, + connectNulls : true, + markers : { + marker : { + fill : '#910000', + stroke: '#910000', + symbol : 'diamond', + radius : 4 + } + }, + data: [-0.9, 0.6, 3.5, 8.4, null, 17.0, 18.6, null, 14.3, 9.0, 3.9, 1.0] + + }); + +}); +```` + + +## stacked area + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'a3', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : -10, + max : 90, + position:'left', + tickInterval : 10, + labels : { + label : { + x : -12 + } + } + }); + var group = canvas.addGroup(Plot.Item,{ + zIndex : 5 + }); + var series = group.addGroup(Series.Area,{ + xAxis : xAxis, + yAxis : yAxis, + color : '#2f7ed8', + stackType : 'normal', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + lineActived : { + 'stroke-width': 3 + }, + animate : false, + markers : { + marker : { + + symbol : 'circle', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] + }); + + var series1 = group.addGroup(Series.Area,{ + xAxis : xAxis, + yAxis : yAxis, + color: '#910000', + stackType : 'normal', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + markers : { + marker : { + fill : '#910000', + stroke: '#910000', + symbol : 'diamond', + radius : 4 + } + }, + data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5] + }); + + var series2 = group.addGroup(Series.Area,{ + xAxis : xAxis, + yAxis : yAxis, + color: '#8bbc21', + stackType : 'normal', + line : { + + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + animate : true, + markers : { + marker : { + fill : '#8bbc21', + stroke: '#8bbc21', + symbol : 'square', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0] + }); + + canvas.sort(); + +}); +```` + +## percent stacked area + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'a4', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : -10, + max : 90, + position:'left', + tickInterval : 10, + labels : { + label : { + x : -12 + } + } + }); + var group = canvas.addGroup(Plot.Item,{ + zIndex : 5 + }); + + var data0 = [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6], + data1 = [0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5], + data2 = [0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0]; + group.getStackedData = function(){ + var + rst = []; + for(var i = 0 ; i < data0.length; i ++){ + rst.push(data0[i] + data1[i] + data2[i]); + } + return rst; + } + var series = group.addGroup(Series.Area,{ + xAxis : xAxis, + yAxis : yAxis, + color : '#2f7ed8', + stackType : 'percent', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + lineActived : { + 'stroke-width': 3 + }, + animate : false, + markers : { + marker : { + + symbol : 'circle', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data:data0 + }); + + var series1 = group.addGroup(Series.Area,{ + xAxis : xAxis, + yAxis : yAxis, + color: '#910000', + stackType : 'percent', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + markers : { + marker : { + fill : '#910000', + stroke: '#910000', + symbol : 'diamond', + radius : 4 + } + }, + data: data1 + }); + + var series2 = group.addGroup(Series.Area,{ + xAxis : xAxis, + yAxis : yAxis, + color: '#8bbc21', + stackType : 'percent', + line : { + + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + animate : true, + markers : { + marker : { + fill : '#8bbc21', + stroke: '#8bbc21', + symbol : 'square', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: data2 + }); + + canvas.sort(); + +}); +```` \ No newline at end of file diff --git a/examples/column.md b/examples/column.md new file mode 100644 index 0000000..a1d3b12 --- /dev/null +++ b/examples/column.md @@ -0,0 +1,602 @@ +# Column + +---- + +柱状图示例 + +---- + +## single column + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'c1', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : 0, + max : 40, + position:'left', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var group = canvas.addGroup(); + + var series = group.addGroup(Series.Column,{ + autoPaint : false, + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + color : '#2f7ed8', + animate : false, + data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] + }); + + series.paint(); +}); + +```` + +## multiple column + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'c2', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : 0, + max : 40, + position:'left', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var group = canvas.addGroup(); + + var series = group.addGroup(Series.Column,{ + autoPaint : false, + xAxis : xAxis, + yAxis : yAxis, + color : '#2f7ed8', + animate : false, + data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] + }); + + var series1 = group.addGroup(Series.Column,{ + autoPaint : false, + xAxis : xAxis, + yAxis : yAxis, + color : '#6ebb46', + animate : false, + data: [0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5] + }); + + series.paint(); + series1.paint(); +}); + +```` + +## stacked column +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'c3', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : 0, + max : 60, + position:'left', + tickInterval : 10, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var group = canvas.addGroup(); + var data0 = [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6], + data1 = [0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]; + group.getStackedData = function(){ + var + rst = []; + for(var i = 0 ; i < data0.length; i ++){ + rst.push(data0[i] + data1[i]); + } + return rst; + } + var series = group.addGroup(Series.Column,{ + autoPaint : false, + xAxis : xAxis, + yAxis : yAxis, + color : '#2f7ed8', + stackType : 'normal', + animate : false, + data: data0 + }); + + var series1 = group.addGroup(Series.Column,{ + autoPaint : false, + xAxis : xAxis, + yAxis : yAxis, + color : '#6ebb46', + stackType : 'normal', + animate : false, + data: data1 + }); + + series.paint(); + series1.paint(); +}); + +```` + +## percent stacked column +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'c31', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : 0, + max : 100, + position:'left', + tickInterval : 20, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var group = canvas.addGroup(); + var data0 = [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6], + data1 = [0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]; + group.getStackedData = function(){ + var + rst = []; + for(var i = 0 ; i < data0.length; i ++){ + rst.push(data0[i] + data1[i]); + } + return rst; + } + var series = group.addGroup(Series.Column,{ + autoPaint : false, + xAxis : xAxis, + yAxis : yAxis, + color : '#2f7ed8', + stackType : 'percent', + animate : false, + data: data0 + }); + + var series1 = group.addGroup(Series.Column,{ + autoPaint : false, + xAxis : xAxis, + yAxis : yAxis, + color : '#6ebb46', + stackType : 'percent', + animate : false, + data: data1 + }); + + series.paint(); + series1.paint(); +}); + +```` + +## time axis + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'c4', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Time,{ + plotRange : plotRange, + startDate : new Date(2010,01,01).getTime(), + endDate : new Date(2010,01,02).getTime(), + tickInterval : 2 * 3600 * 1000, + labels : { + label : { + y : 12 + } + }, + tickOffset : 10, + formatter : function(value){ + return new Date(value).getHours(); + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : 0, + max : 35, + + position:'left', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var group = canvas.addGroup(); + + var series = group.addGroup(Series.Column,{ + autoPaint : false, + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + color : '#2f7ed8', + pointStart : new Date(2010,01,01).getTime(), + pointInterval : 3600 * 1000, + allowPointSelect : true, + labels : { + label : { + rotate : -90, + y : 10, + 'fill' : '#fff', + 'text-anchor' : 'end', + 'textShadow': '0 0 3px black', + 'font-size' : '14px' + } + }, + animate : false, + data: [34.4, 21.8, {y : 20.1,attrs : {fill : '#ff0000'}}, 20, 19.6, 19.5, 19.1, 18.4, 18, + 17.3, 16.8, 15, 14.7, 14.5, 13.3, 12.8, 12.4, 11.8,18,20,16, + 11.7, 11.2] + }); + + series.paint(); +}); + +```` + +## bar + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'c5', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 2, + x : -10, + "text-anchor" : 'end' + } + }, + position : 'left' + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : 0, + max : 40, + position:'bottom', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var group = canvas.addGroup(); + + var series = group.addGroup(Series.Column,{ + autoPaint : false, + xAxis : xAxis, + yAxis : yAxis, + invert : true, + labels : { + label : { + y : 0, + x : 15, + 'text-anchor' : 'start' + } + }, + color : '#2f7ed8', + animate : false, + data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] + }); + + series.paint(); +}); + +```` + +## stacked bar +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'c51', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 2, + x : -10, + "text-anchor" : 'end' + } + }, + position : 'left' + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : 0, + max : 60, + position:'bottom', + tickInterval : 10, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var group = canvas.addGroup(); + var data0 = [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6], + data1 = [0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]; + group.getStackedData = function(){ + var + rst = []; + for(var i = 0 ; i < data0.length; i ++){ + rst.push(data0[i] + data1[i]); + } + return rst; + } + var series = group.addGroup(Series.Column,{ + autoPaint : false, + xAxis : xAxis, + yAxis : yAxis, + color : '#2f7ed8', + invert : true, + stackType : 'normal', + animate : false, + data: data0 + }); + + var series1 = group.addGroup(Series.Column,{ + autoPaint : false, + xAxis : xAxis, + yAxis : yAxis, + invert : true, + color : '#6ebb46', + stackType : 'normal', + animate : false, + data: data1 + }); + + series.paint(); + series1.paint(); +}); + +```` + diff --git a/examples/line.md b/examples/line.md new file mode 100644 index 0000000..e46d80d --- /dev/null +++ b/examples/line.md @@ -0,0 +1,431 @@ +# Line + +--- + +折线图示例 + +--- + +## 折线图构成 + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'l1', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : -5, + max : 40, + position:'left', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var series = canvas.addGroup(Series.Line,{ + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + color : '#2f7ed8', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + lineActived : { + 'stroke-width': 3 + }, + animate : false, + markers : { + marker : { + + symbol : 'circle', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] + }); + + var traceLine = series.get('trackerShape'); + traceLine.attr('stroke-opacity',0.5); +}); +```` + +## Data Format + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'l2', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : -5, + max : 40, + position:'left', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var series = canvas.addGroup(Series.Line,{ + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + color : '#2f7ed8', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + lineActived : { + 'stroke-width': 3 + }, + animate : false, + markers : { + marker : { + + symbol : 'circle', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] + }); + + var series1 = canvas.addGroup(Series.Line,{ + xAxis : xAxis, + yAxis : yAxis, + line : { + stroke: '#910000', + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + smooth : true, + animate : true, + markers : { + marker : { + fill : '#910000', + stroke: '#910000', + symbol : 'diamond', + radius : 4 + } + }, + data: [['一月',-0.2], ['二月',0.8], ['三月',5.7], ['四月',11.3], ['五月',17.0], {y: 22.0,marker : {symbol : 'circle'}}, ['七月',24.8], ['八月',24.1], ['九月',20.1], ['十月',14.1], 8.6, 2.5] + }); + + var series2 = canvas.addGroup(Series.Line,{ + xAxis : xAxis, + yAxis : yAxis, + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + labels : { + label : { + y : -15 + } + }, + animate : false, + color : '#8bbc21', + markers : { + marker : { + symbol : 'square', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [{y:-0.9}, {x : '二月',y : 0.6}, {x : '三月',y : 3.5}, {x : '四月',y : 8.4}, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0] + }); +}); +```` + +## smooth + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'l3', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : -5, + max : 40, + position:'left', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var series = canvas.addGroup(Series.Line,{ + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + color : '#2f7ed8', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + lineActived : { + 'stroke-width': 3 + }, + animate : false, + smooth : true, + markers : { + marker : { + + symbol : 'circle', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] + }); + +}); +```` + +## break point + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'l4', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : -5, + max : 40, + position:'left', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + //不连接断点 + var series = canvas.addGroup(Series.Line,{ + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + color : '#2f7ed8', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + lineActived : { + 'stroke-width': 3 + }, + animate : false, + markers : { + marker : { + + symbol : 'circle', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [7.0, 6.9, 9.5, 14.5, null, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] + }); + //断点进行连接 + var series1 = canvas.addGroup(Series.Line,{ + xAxis : xAxis, + yAxis : yAxis, + line : { + stroke: '#910000', + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + animate : true, + connectNulls : true, + markers : { + marker : { + fill : '#910000', + stroke: '#910000', + symbol : 'diamond', + radius : 4 + } + }, + data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, null, 14.3, 9.0, 3.9, 1.0] + + }); + +}); +```` \ No newline at end of file diff --git a/examples/pie.md b/examples/pie.md new file mode 100644 index 0000000..bef0332 --- /dev/null +++ b/examples/pie.md @@ -0,0 +1,427 @@ +# Pie + +--- + +饼图的demo + +--- + +## Pie + + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-canvas','achart-plot'], function(Series,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'p1', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 400},{x : 850, y : 50}); + + var group = canvas.addGroup(); + + group.set('plotRange',plotRange); + + var pie = group.addGroup(Series.Pie,{ + autoPaint : false, + allowPointSelect : true, + labels : { + distance : 40, + label : { + + }, + renderer : function(value,item){ + return value + ' ' + (item.point.percent * 100).toFixed(2) + '%'; + } + }, + name: 'Browser share', + animate : false, + colors : [ '#5e90c9','#1c2d3f','#a9d052','#a12d2d','#43bbb4','#5a2a94','#fabe3c','#2279dc','#e360e5','#48000c'], + data: [ + ['Firefox', 45.0], + ['IE', 26.8], + { + name: 'Chrome', + y: 12.8, + sliced: true, + selected: true + }, + ['Safari', 8.5], + ['Opera', 6.2], + ['Others', 0.7] + ] + }); + + pie.paint(); + +}); +```` + +## inner text + + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-canvas','achart-plot'], function(Series,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'p2', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 400},{x : 850, y : 50}); + + var group = canvas.addGroup(); + + group.set('plotRange',plotRange); + + var pie = group.addGroup(Series.Pie,{ + autoPaint : false, + allowPointSelect : true, + labels : { + distance : -20, + label : { + fill : '#fff' + }, + renderer : function(value,item){ + return value + ' ' + (item.point.percent * 100).toFixed(2) + '%'; + } + }, + name: 'Browser share', + animate : false, + colors : [ '#5e90c9','#1c2d3f','#a9d052','#a12d2d','#43bbb4','#5a2a94','#fabe3c','#2279dc','#e360e5','#48000c'], + data: [ + ['Firefox', 45.0], + ['IE', 26.8], + { + name: 'Chrome', + y: 12.8, + sliced: true, + selected: true + }, + ['Safari', 8.5], + ['Opera', 6.2], + ['Others', 0.7] + ] + }); + + pie.paint(); + +}); +```` + + +## multiple text + + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-canvas','achart-plot'], function(Series,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'p3', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 400},{x : 850, y : 50}); + + var group = canvas.addGroup(); + + group.set('plotRange',plotRange); + + var pie = group.addGroup(Series.Pie,{ + autoPaint : false, + allowPointSelect : true, + labels : { + distance : 40, + label : { + + }, + renderer : function(value,item){ + return value + ' ' + (item.point.percent * 100).toFixed(2) + '%'; + } + }, + name: 'Browser share', + animate : false, + colors : [ '#5e90c9','#1c2d3f','#a9d052','#a12d2d','#43bbb4','#5a2a94','#fabe3c','#2279dc','#e360e5','#48000c'], + data: [ + ['Firefox', 45.0], + ['test',1], + ['test',1], + ['test',1], + ['test',1], + ['IE', 26.8], + { + name: 'Chrome', + y: 12.8, + sliced: true + }, + ['Safari', 8.5], + ['test',1], + ['test',1], + ['test',1], + ['test',1], + ['Opera', 6.2], + ['test',1], + ['test',1], + ['test',1], + ['test',1], + ['Others', 0.7] + ] + }); + + pie.paint(); + +}); +```` + + +## ring + + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-canvas','achart-plot'], function(Series,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'p4', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 400},{x : 850, y : 50}); + + var group = canvas.addGroup(); + + group.set('plotRange',plotRange); + + var pie = group.addGroup(Series.Pie,{ + autoPaint : false, + allowPointSelect : true, + labels : { + distance : 40, + label : { + + }, + renderer : function(value,item){ + return value + ' ' + (item.point.percent * 100).toFixed(2) + '%'; + } + }, + innerSize : '60%', + name: 'Browser share', + animate : false, + colors : [ '#5e90c9','#1c2d3f','#a9d052','#a12d2d','#43bbb4','#5a2a94','#fabe3c','#2279dc','#e360e5','#48000c'], + data: [ + ['Firefox', 45.0], + ['IE', 26.8], + { + name: 'Chrome', + y: 12.8, + sliced: true, + selected: true + }, + ['Safari', 8.5], + ['Opera', 6.2], + ['Others', 0.7] + ] + }); + + pie.paint(); + +}); +```` + +## nest Ring + + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-canvas','achart-plot'], function(Series,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'p5', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 400},{x : 850, y : 50}); + + var group = canvas.addGroup(); + + group.set('plotRange',plotRange); + + var colors = [ '#5e90c9','#1c2d3f','#a9d052','#a12d2d','#43bbb4','#5a2a94','#fabe3c','#2279dc','#e360e5','#48000c']; + + var pie = group.addGroup(Series.Pie,{ + autoPaint : false, + allowPointSelect : false, + animate : false, + colors : colors, + radius : 100, + innerRadius : 80, + name: 'outter', + startAngle : -198, // 360 * 60% / 2 + 90 + endAngle : 162, // + data: [ + {name : 'outter', y : 60}, + {name : '',y : 40,attrs : {fill : '#efefef'},placeHolder : true} + ] + }); + + var pie1 = group.addGroup(Series.Pie,{ + autoPaint : false, + allowPointSelect : false, + animate : false, + name: 'middle', + radius : 80, + innerRadius : 60, + startAngle : -144,//360 * 30% / 2 + 90 + endAngle : 226, + data: [ + {name : 'middle', y : 30,attrs : {fill : 'rgb(85, 194, 187)'}}, + {name : '',y : 70,attrs : {fill : '#efefef'},placeHolder : true} + ] + + }); + + var pie2 = group.addGroup(Series.Pie,{ + autoPaint : false, + allowPointSelect : false, + animate : false, + name: 'inner', + radius : 60, + innerRadius : 40, + startAngle : -180,//360 * 50% / 2 + 90 + endAngle : 180, + data: [ + {name : 'inner', y : 50,attrs : {fill : 'rgb(161, 45, 45)'}}, + {name : '',y : 50,attrs : {fill : '#efefef'},placeHolder : true} + ] + + }); + + pie.paint(); + pie1.paint(); + pie2.paint(); + +}); +```` + +## pie stauts + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-canvas','achart-plot'], function(Series,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'p6', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 400},{x : 850, y : 50}); + + var group = canvas.addGroup(); + + group.set('plotRange',plotRange); + + var pie = group.addGroup(Series.Pie,{ + autoPaint : false, + allowPointSelect : true, + events : { + itemclick : function(ev){ + console.log('click'); + }, + itemselected : function(ev){ + console.log('selected'); + }, + itemunselected : function(ev){ + console.log('unselected'); + }, + itemactived : function(ev){ + console.log('actived'); + }, + itemunactived : function(ev){ + console.log('unactived'); + } + }, + labels : { + distance : 40, + label : { + + }, + renderer : function(value,item){ + return value + ' ' + (item.point.percent * 100).toFixed(2) + '%'; + } + }, + name: 'Browser share', + animate : false, + colors : [ '#5e90c9','#1c2d3f','#a9d052','#a12d2d','#43bbb4','#5a2a94','#fabe3c','#2279dc','#e360e5','#48000c'], + data: [ + ['Firefox', 45.0], + ['IE', 26.8], + { + name: 'Chrome', + y: 12.8, + sliced: true, + selected: true + }, + ['Safari', 8.5], + ['Opera', 6.2], + ['Others', 0.7] + ] + }); + + pie.paint(); + + + +}); +```` diff --git a/examples/radar.md b/examples/radar.md new file mode 100644 index 0000000..7a19202 --- /dev/null +++ b/examples/radar.md @@ -0,0 +1,351 @@ +# Radar + +--- + +雷达图示例 + +--- + + +## Line + + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'r1', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Circle,{ + plotRange : plotRange, + ticks : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Radius,{ + plotRange : plotRange, + line : null, + tickLine : null, + circle : xAxis, + grid : { + type : 'circle', + line : { + stroke : '#c0c0c0' + } + }, + min : -5, + max : 40, + position:'left', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var series = canvas.addGroup(Series.Line,{ + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + color : '#2f7ed8', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + lineActived : { + 'stroke-width': 3 + }, + animate : false, + smooth : true, + markers : { + marker : { + + symbol : 'circle', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] + }); + +}); +```` + +## area + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'r2', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Circle,{ + plotRange : plotRange, + tickInterval : 45, + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Radius,{ + plotRange : plotRange, + line : null, + tickLine : null, + circle : xAxis, + grid : { + type : 'circle', + line : { + stroke : '#c0c0c0' + } + }, + min : 0, + max : 10, + position:'left', + tickInterval : 2, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var series = canvas.addGroup(Series.Area,{ + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + color : '#2f7ed8', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + lineActived : { + 'stroke-width': 3 + }, + animate : false, + markers : { + marker : { + + symbol : 'circle', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [8, 4, 6, 5, 7, 3, 4, 1] + }); + +}); +```` + +## column + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'r4', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Circle,{ + plotRange : plotRange, + tickInterval : 45, + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Radius,{ + plotRange : plotRange, + line : null, + tickLine : null, + circle : xAxis, + grid : { + type : 'circle', + line : { + stroke : '#c0c0c0' + } + }, + min : 0, + max : 10, + position:'left', + tickInterval : 2, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + var group = canvas.addGroup(); + var series = group.addGroup(Series.Column,{ + xAxis : xAxis, + yAxis : yAxis, + autoPaint :false, + color : '#2f7ed8', + animate : false, + + data: [8, 4, 6, 5, 7, 3, 4, 1] + }); + + var series1 = group.addGroup(Series.Column,{ + xAxis : xAxis, + yAxis : yAxis, + autoPaint :false, + color : '#6ebb46', + animate : false, + + data: [1,2,4,3,6,8,5,7] + }); + series.paint(); + series1.paint(); + +}); +```` + +## column stacked + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'r5', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Circle,{ + plotRange : plotRange, + tickInterval : 45, + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Radius,{ + plotRange : plotRange, + line : null, + tickLine : null, + circle : xAxis, + grid : { + type : 'circle', + line : { + stroke : '#c0c0c0' + } + }, + min : 0, + max : 15, + position:'left', + tickInterval : 3, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + var group = canvas.addGroup(); + var series = group.addGroup(Series.Column,{ + xAxis : xAxis, + yAxis : yAxis, + autoPaint :false, + color : '#2f7ed8', + stackType : 'normal', + animate : false, + + data: [8, 4, 6, 5, 7, 3, 4, 1] + }); + + var series1 = group.addGroup(Series.Column,{ + xAxis : xAxis, + yAxis : yAxis, + autoPaint :false, + color : '#6ebb46', + animate : false, + stackType : 'normal', + data: [1,2,4,3,6,8,5,7] + }); + series.paint(); + series1.paint(); + +}); +```` + + + + diff --git a/package.json b/package.json index 3c7af8c..0e82a5d 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,6 @@ "event-simulate" : "1.0.0", "jquery" : "1.9.1" }, - "tests": "tests/*-spec.js" + "tests": "tests/line-spec.js" } } diff --git a/src/base.js b/src/base.js index aca7a8e..e0ffc9e 100644 --- a/src/base.js +++ b/src/base.js @@ -101,6 +101,21 @@ Series.ATTRS = { */ groupName : 'series' + /** + * @event beforepaint + * 数据序列开始渲染,仅第一次渲染时 + */ + + /** + * @event afterpaint + * 数据序列渲染完成,仅第一次渲染时 + */ + + /** + * @event datachange + * 数据序列数据发生改变 + */ + }; Util.augment(Series,{ @@ -110,7 +125,7 @@ Util.augment(Series,{ Series.superclass.renderUI.call(_self); - _self.processColor(); + _self.processColor(this.get('color')); _self.renderLabels(); _self.renderMarkers(); if(_self.get('autoPaint')){ @@ -123,10 +138,10 @@ Util.augment(Series,{ Series.superclass.bindUI.call(_self); if(_self.get('enableMouseTracking')){ - _self.onMouseOver(); + _self.bindMouseOver(); var parent = _self.get('parent'); - /**/_self.on('mouseover',function(){ + _self.on('mouseover',function(){ if(parent.setActivedItem){ if(!parent.isItemActived(_self)){ parent.setActivedItem(_self); @@ -135,12 +150,13 @@ Util.augment(Series,{ }); } if(!_self.get('stickyTracking')){ - _self.onMouseOut(); + _self.bindMouseOut(); } }, /** * 更改数据 * @param {Array} data 数据 + * @param {Boolean} redraw 是否重绘序列 */ changeData : function(data,redraw){ var _self = this, @@ -156,6 +172,7 @@ Util.augment(Series,{ _self.repaint(); } } + _self.fire('datachange',{data : data}); }, /** * 添加数据 @@ -185,7 +202,7 @@ Util.augment(Series,{ _self.set('points',null); _self.shiftPoint(); _self.repaint(); - + _self.fire('datachange',{data : data}); },800); } @@ -228,14 +245,14 @@ Util.augment(Series,{ * @protected * 鼠标进入事件 */ - onMouseOver : function(ev){ + bindMouseOver : function(ev){ }, /** * @protected * 鼠标移出 */ - onMouseOut : function(ev){ + bindMouseOut : function(ev){ }, /** @@ -248,7 +265,7 @@ Util.augment(Series,{ * @protected * 处理颜色 */ - processColor : function(){ + processColor : function(color){ }, /** @@ -292,11 +309,16 @@ Util.augment(Series,{ } point.obj = item; }else if(Util.isArray(item)){ - point = _self.getPointByValue(item[0],item[1]); + if(_self.hasXValueInArray()){ + point = _self.getPointByValue(item[0],item[1]); + }else{ + point = _self.getPointByIndex(item[0],index); + } point.arr = item; }else{ point = _self.getPointByIndex(item,index); } + point.name = _self.get('name'); _self.processPoint(point,index); points.push(point); }); @@ -305,17 +327,17 @@ Util.augment(Series,{ }, /** * @protected - * 处理节点,并且添加附加信息 + * 传入的数据中是否存在x轴的值,如果不存在则使用index计算 + * @return {Boolean} */ - processPoint : function(point,index){ - + hasXValueInArray : function(){ + return true; }, /** - * 根据对象获取值 * @protected - * @return {Object} 点的信息 + * 处理节点,并且添加附加信息 */ - getPointByObject : function(item){ + processPoint : function(point,index){ }, /** @@ -377,7 +399,7 @@ Util.augment(Series,{ * @protected * 画对应的图形 */ - draw : function(points){ + draw : function(points,callback){ }, /** @@ -391,8 +413,10 @@ Util.augment(Series,{ return; } _self.set('painting',true);//正在绘制,防止再绘制过程中触发重绘 + _self.fire('beforepaint'); _self.draw(points,function(){ _self.sort(); + _self.fire('afterpaint'); }); _self.set('isPaint',true); _self.set('painting',false); @@ -423,15 +447,17 @@ Util.augment(Series,{ } _self.changeShapes(points); Util.each(points,function(point){ - if(labels){ - var item = {}; - item.text = point.value; - item.x = point.x; - item.y = point.y; - labels.items.push(item); - } - if(markers){ - markers.items.push(point); + if(point.value != null){ + if(labels){ + var item = {}; + item.text = point.value; + item.x = point.x; + item.y = point.y; + labels.items.push(item); + } + if(markers){ + markers.items.push(point); + } } }); @@ -449,20 +475,20 @@ Util.augment(Series,{ * @protected * 添加marker配置项 */ - addMarker : function(offset){ + addMarker : function(point){ var _self = this, markersGroup = _self.get('markersGroup'), marker = {}, rst; if(markersGroup){ - marker.x = offset.x; - marker.y = offset.y; - if(offset.obj && offset.obj.marker){ - Util.mix(marker,offset.obj.marker); + marker.x = point.x; + marker.y = point.y; + if(point.obj && point.obj.marker){ + Util.mix(marker,point.obj.marker); } rst = markersGroup.addMarker(marker); - rst.set('point',offset); + rst.set('point',point); } return rst; }, @@ -488,6 +514,11 @@ Util.augment(Series,{ if(markers){ markersGroup = _self.get('markersGroup'); markersGroup.change(markers.items); + var children = markersGroup.get('children'); + + Util.each(children,function(item,index){ + item.set('point',markers.items[index]); + }); } }, _changeLabels : function(){ @@ -500,14 +531,6 @@ Util.augment(Series,{ markersGroup = _self.get('markersGroup'); markersGroup && markersGroup.remove(); - }, - //获取激活的属性 - getActiveAtrrs : function(){ - - }, - //获取解除激活的属性 - getUnActiveAttrs : function(){ - }, /** * @protected diff --git a/src/cartesian.js b/src/cartesian.js index aadb86f..23616ea 100644 --- a/src/cartesian.js +++ b/src/cartesian.js @@ -122,23 +122,20 @@ Util.augment(Cartesian,{ Cartesian.superclass.changeData.call(this,data,redraw); }, /** - * * @protected - * @return {Object} 点的集合 + * 传入的数据中是否存在x轴的值,如果不存在则使用index计算 + * @return {Boolean} */ - /*getPointByObject : function(item,index){ + hasXValueInArray : function(){ var _self = this, - xField = _self.get('xField'), - yField = _self.get('yField'), - point = _self.getPoint(item[xField],item[yField]); - - point.value = item[yField]; - point.xValue = item[xField]; - point.yValue = _self.parseYValue(item[yField]); - point.obj = item; //如果是记录 - - return point; - },*/ + xAxis = _self.get('xAxis'), + type = xAxis.get('type'); + //如果是时间、数字坐标轴,同时设置了点的间距,不需要数组中存在 x值 + if((type == 'number' || type == 'time') && _self.get('pointInterval')){ + return false; + } + return true; + }, /** * @protected * 根据指定的值获取点的信息 @@ -156,6 +153,29 @@ Util.augment(Cartesian,{ parseYValue : function(value){ return value; }, + /** + * 执行平铺动画,从左到右,从上到下显示图表序列 + * @param {Function} fn 执行的函数 + * @param {Function} callback 回调 + */ + animateClip : function(fn,callback){ + var _self = this, + canvas = _self.get('canvas'), + invert = _self.get('invert'), + width = canvas.get('width'), + duration = _self.get('duration'), + height = canvas.get('height'), + clip = invert ? '0,0,' + width + ',0' : '0,0,0,' + height; + + _self.attr('clip-rect',clip); + fn && fn(); + _self.animate({ + 'clip-rect' : '0,0,' + width + ','+height + },duration,function(){ + callback && callback(); + _self.attr('clip-rect',''); + }); + }, /** * @protected * 判断是否近似相等 diff --git a/src/column.js b/src/column.js index 10eb3ab..00a44e1 100644 --- a/src/column.js +++ b/src/column.js @@ -74,7 +74,7 @@ Column.ATTRS = { * 是否允许取消选中,选中状态下,继续点击则会取消选中 * @type {Boolean} */ - cancelSelect : 'false', + cancelSelect : false, /** * 发生层叠时,层叠之间的间距 * @type {Object} @@ -165,7 +165,7 @@ Util.augment(Column,{ var _self = this, curIndex, xAxis = _self.get('xAxis'), - tickLength = xAxis.getTickAvgLength(), + tickLength = _self._getAvgLength(), count, margin = 10, width, @@ -182,6 +182,21 @@ Util.augment(Column,{ _self.set('columnOffset',offset) }, + _getAvgLength : function(){ + var _self = this, + xAxis = _self.get('xAxis'), + type = xAxis.get('type'), + avgLength, + data = _self.get('data'); + + if(type != 'time' && type != 'number'){ + avgLength = xAxis.getTickAvgLength(); + }else{ + var length = xAxis.getLength(); + avgLength = length / data.length; + } + return avgLength; + }, //获取index相关信息 _getIndexInfo : function(){ var _self = this, diff --git a/src/itemgroup.js b/src/itemgroup.js index d2369f8..21fac97 100644 --- a/src/itemgroup.js +++ b/src/itemgroup.js @@ -111,7 +111,7 @@ Util.augment(Group,{ _self.setSelected(shape); } } - _self.fire('itemclick',shape); + _self.fire('itemclick',{item : shape,point : shape.get('point')}); _self.fireUpGroup('click',shape); } }); @@ -185,7 +185,7 @@ Util.augment(Group,{ * 触发选中事件 */ onSelected : function(item){ - this.fire('itemselected',{item:item}); + this.fire('itemselected',{item:item,point : item.get('point')}); this.fireUpGroup('selected',item); }, /** @@ -193,7 +193,7 @@ Util.augment(Group,{ * 触发移除选中 */ onUnSelected : function(item){ - this.fire('itemunselected',{item:item}); + this.fire('itemunselected',{item:item,point : item.get('point')}); this.fireUpGroup('unselected',item); }, /** diff --git a/src/line.js b/src/line.js index f90d72f..74b1472 100644 --- a/src/line.js +++ b/src/line.js @@ -143,6 +143,18 @@ Util.augment(Line,{ path = ''; if(!animate){ + drawLine(); + }else{ + lineShape = _self._createLine(path); + if(_self.isInCircle()){ + _self.circleAnimate(points,lineShape); + }else{ + _self.animateClip(drawLine,after); + } + + } + + function drawLine(){ path = _self.points2path(points); lineShape = _self._createLine(path); Util.each(points,function(point){ @@ -151,41 +163,7 @@ Util.augment(Line,{ _self.drawInner(points); after(); - }else{ - lineShape = _self._createLine(path); - if(_self.isInCircle()){ - _self.circleAnimate(points,lineShape); - }else{ - var cur = 0, - sub = [], - count = points.length; - - //动画生成线和对应的点 - Util.animStep(duration,function(factor){ - var pre = cur; - cur = parseInt((factor) * count,10); - if(cur > count - 1){ - cur = count - 1; - } - - if(cur != pre){ - sub = points.slice(0,cur + 1); - path = _self.points2path(sub); - lineShape.attr('path',path); - _self.drawInner(sub); - for(var i = pre; i< cur; i++){ - _self._drawPoint(points[i]); - } - - } - if(factor == 1){ - _self._drawPoint(points[cur]); - } - },after); - } - } - //_self.set('lineShape',lineShape); /** * @private */ @@ -230,6 +208,9 @@ Util.augment(Line,{ //绘制节点相关的label,marker _drawPoint : function(point){ var _self = this; + if(point.value == null){ + return; + } if(_self.get('markers') && !_self.get('markersGroup').get('single')){ //如果只有一个marker暂时不生成 _self.addMarker(point); } diff --git a/src/pie.js b/src/pie.js index 1b68556..77c33ec 100644 --- a/src/pie.js +++ b/src/pie.js @@ -53,10 +53,10 @@ function resetItem(item,h,endAngle,r,center,isStart,lineHeight){ //增加5像素,用于连接线 item.x = center.x + (r + 5) * Math.cos(item.angle * RAD); item.y = center.y + (r + 5) * Math.sin(item.angle * RAD); - if(innerAngle == 0){ + //if(innerAngle == 0){ //item.y = item.y - lineHeight; - item["text-anchor"] = "middle"; - } + //item["text-anchor"] = "middle"; + //} } function alignLables(center,r,arr,endAngle,factor,lineHeight){ @@ -207,11 +207,17 @@ Pie.ATTRS = { */ labelHeight : 16, + /** + * 是否显示文本的连接线 + * @type {Boolean} + */ labelLine : true, item : { 'stroke': '#fff' }, + + cancelSelect : true, xField : 'name', stickyTracking : false, @@ -371,7 +377,7 @@ Util.augment(Pie,{ }, //鼠标移动 - onMouseOver : function(){ + bindMouseOver : function(){ var _self = this; _self.on('mouseover',function(ev){ diff --git a/src/stacked.js b/src/stacked.js index 12561c6..713c4dc 100644 --- a/src/stacked.js +++ b/src/stacked.js @@ -27,7 +27,12 @@ Stacked.ATTRS = { }; Util.augment(Stacked,{ - + /** + * @protected + * 处理层叠的点 + * @param {Object} point 处理的点 + * @param {Number} index 索引 + */ processStackedPoint : function(point,index){ var _self = this, pre = _self.getVisiblePrev(), diff --git a/tests/column-spec.js b/tests/column-spec.js index f7b803b..1a88a1c 100644 --- a/tests/column-spec.js +++ b/tests/column-spec.js @@ -384,3 +384,100 @@ describe('测试层叠区域图',function(){ }); }); + +describe('test time axis',function(){ + var canvas = new Canvas({ + id : 'c1', + width : 900, + height : 500 + }); + + + + var plotRange = { + start : {x : 50,y : 400}, + end : {x : 850, y : 50} + }, + xAxis = canvas.addGroup(Axis.Time,{ + plotRange : plotRange, + startDate : 1264982400000, + endDate : 1265068800000, + tickInterval : 2 * 3600 * 1000, + labels : { + label : { + y : 12 + } + }, + tickOffset : 10, + formatter : function(val){ + return new Date(val).getHours(); + } + }); + + var yAxis = canvas.addGroup(NAxis,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + title : { + text : 'xsxxxxx', + font : '16px bold', + fill : 'blue', + rotate : 90, + x : -30 + }, + min : -5, + max : 40, + position:'left', + tickInterval : 5, + + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var group = canvas.addGroup(); + + var series = group.addGroup(Series,{ + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + autoPaint : false, + color : '#2f7ed8', + name: 'Africa', + pointInterval : 3600 * 1000, + pointStart : 1264982400000, + data: [34.4, 21.8, {y : 20.1,attrs : {fill : '#ff0000'}}, 20, 19.6, 19.5, 19.1, 18.4, 18, + 17.3, 16.8, 15, 14.7, 14.5, 13.3, 12.8, 12.4, 11.8,18,20,16, + 11.7, 11.2], + allowPointSelect : true, + labels : { + label : { + rotate : -90, + y : 10, + 'fill' : '#fff', + 'text-anchor' : 'end', + 'textShadow': '0 0 3px black', + 'font-size' : '14px' + } + } + }); + + series.paint(); + + it('test column width',function(){ + + }); +}); diff --git a/tests/line-spec.js b/tests/line-spec.js index 4042997..08fdde1 100644 --- a/tests/line-spec.js +++ b/tests/line-spec.js @@ -327,7 +327,7 @@ describe('测试序列生成',function(){ },800); }); }); - + }); @@ -630,4 +630,6 @@ describe('time axis',function(){ -}); \ No newline at end of file +}); +/* +*/ \ No newline at end of file diff --git a/tests/pie-spec.js b/tests/pie-spec.js index ec35abf..9c024f1 100644 --- a/tests/pie-spec.js +++ b/tests/pie-spec.js @@ -122,7 +122,7 @@ describe('测试序列生成',function(){ setTimeout(function(){ var info = pie.getTrackingInfo(); - expect(info.name).to.be(first.get('name')); + //expect(info.name).to.be(first.get('name')); expect(first.get('actived')).to.be(true); expect(callback.called).to.be(true); diff --git a/wiki/01-base.md b/wiki/01-base.md new file mode 100644 index 0000000..9082f64 --- /dev/null +++ b/wiki/01-base.md @@ -0,0 +1,118 @@ +# 图表序列基类 + +--- + +图表序列的基本功能 + +--- + + +## 目录 + + * 简介 + * 图表序列的基本功能 + * 绘制和重绘 + * Markers 和 Labels + * 转换数据 + * 更改数据序列 + * 相应的事件 + * 如何继承 + +### 简介 + + * 图表序列的基类Series是所有图表序列的基类,它提供了一系列的配置项和方法 + * Seires 继承自[Plot.Item](http://spmjs.io/docs/achart-plot/wiki/item.html),可以很方便的获取默认配置项和事件处理 + +### 图表序列的基本功能 + + * 图表序列将数据转换成图形元素 + * 响应交互事件 + * 获取画布上的点跟图表序列的关联信息 + * 跟随数据变化 + +### 绘制和重绘 + + * Series 通过paint()方法绘制序列,提供了一个 draw(points,callback) 的protected 函数用于子类覆写 + * Series 通过rePaint()方法重绘图形 + +#### 处理颜色 + + * 图表序列往往多个一起显示,各个序列有不同的颜色 + * Series 提供了一个 protected 的方法 processColor(color)来更改跟颜色相关的配置项 + +### Markers 和 Labels + + * Series中的数据对应的点上有时候需要标记[(marker)](http://spmjs.io/docs/achart-markers/)和显示文本[(label)](http://spmjs.io/docs/achart-labels/) + * 如果markers = null 则不显示,否则在内部创建一个 [Markers对象](http://spmjs.io/docs/achart-markers/) + * 如果labels = null 则不显示,否则在内部创建一个[Labels对象](http://spmjs.io/docs/achart-labels/) + +### 转换数据 + + * 图表序列(Series)接收的数据是一个数组,每条记录的格式有一下几种 + + * 单个数值的数组,例如 [1,2,3,4] + * 多维数据的数组,例如 [[0,0],[1,1],[2,3]],[[1,2,3],[4,5,6]] + * 对象的数组,例如 [{x : 1,y:2},{x : 2,y : 5}] + + * 图表序列处理上面各种数据格式都有对应的protected方法,供子类继承 + + * getPointByIndex(value,index) 处理单个数值,根据数值在数组中的索引获取对应的点 + * getPointByValue(xValue,yValue) 将对应的x值和y值传入函数,如果数据源是数组,则在返回的点上附加 point.arr = arr;如果数据源是对象则 point.obj = obj; + + * 转换完毕的数据可以通过 getPoints()方法获取到 + +### 更改数据 + + * Series 调用changeData(data,redraw) 方法重置数据序列的数据,并决定是否重绘 + * 更改数据时,Series 本身独有的图形需要跟随变化,对应的Markers和Labels也要跟随发生改变 + * 更改数据时会调用 changeShapes(points) 方法,所以继承的类需要覆写此方法 + +### 事件处理 + + * stickyTracking 属性关系着鼠标在画布上移动时,图表序列是否相应 + * enableMouseTracking 决定鼠标移动到当前图表序列上时是否触发事件 + +#### 事件protected的方法 + + * onMouseOver(ev) + * onMouseOut(ev) + + +### 如何继承 + + 1. 覆写绘制序列的函数 + + * draw(points,callback) 绘制函数,绘制完成后调用callback方法 + * processColor(color) 如果需要处理颜色覆写此方法 + + 2. 覆写转换数据的方法 + + * getPointByIndex(value,index) 处理单个数值,根据数值在数组中的索引获取对应的点 + * getPointByValue(xValue,yValue) 将对应的x值和y值传入函数,如果数据源是数组,则在返回的点上附加 point.arr = arr;如果数据源是对象则 point.obj = obj; + * processPoint(point) 如果需要特别处理转换的点,覆写此函数 + + 3. 覆写图形更改的方法 + + * changeShapes(points) 数据发生改变时触发 + + 4. 覆写状态相关的方法 + + * setActiveStatus(actived) actived 状态发生改变时使用 + + 5. 如果处理鼠标事件覆写 + + * bindMouseOver() + * bindMouseOut() + +#### 必须覆写的方法 + + * draw(points,callback) 绘制内部图形 + * changeShapes(points) 图形发生改变时 + * getPointByIndex(value,index) 处理最基本的数据类型 data : [1,2,3,4] + + + + + + + diff --git a/wiki/02-cartesian.md b/wiki/02-cartesian.md new file mode 100644 index 0000000..0d81188 --- /dev/null +++ b/wiki/02-cartesian.md @@ -0,0 +1,68 @@ +# 坐标系 + +--- + +x,y轴上的坐标系 + +--- + +# 目录 + + * 简介 + * x轴,y轴 + * 转换数据 + * 雷达图中的坐标轴 + * 继承此类 + +## 简介 + + * 坐标系中的数据序列 Series.Cartesian 有x轴和y轴 2个坐标轴,这2个坐标轴决定一个点在图形上的位置,是一切使用坐标系序列的父类 + * 折线图、柱状图、区域图等都是继承自 Series.Cartesian + +### x轴和y轴 + + * 坐标系中的x轴用来计算数据x轴的位置,可以通过数值的索引、指定的 xField或者数组的第一个元素 + * 坐标系中的y轴用来计算数据y轴的位置,一般是数据的值、指定的yField或者数组的第二个元素 + * 当x轴是 Axis.Circle (type = 'circle') ,y轴是 Axis.Radius (type = 'radius')时,坐标系从笛卡尔坐标系转换成极坐标 + +### 转换数据 + + * Series.Cartesian 为了处理数据,已经覆写下面的函数 + * getPointByIndex(value,index) 处理单个数值,根据数值在数组中的索引获取对应的点 + * getPointByValue(xValue,yValue) 将对应的x值和y值传入函数,如果数据源是数组,则在返回的点上附加 point.arr = arr;如果数据源是对象则 point.obj = obj; + * Series.Cartesian 也处理了在雷达图(极坐标)中的数据转换 + +### 雷达图中的坐标轴 + + * 当x轴是 Axis.Circle (type = 'circle') ,y轴是 Axis.Radius (type = 'radius')时,坐标系从笛卡尔坐标系转换成极坐标,对应的图表就是雷达图 + * 通过 isInCircle() 判断图表序列是否在雷达图(极坐标)中,渲染图表元素时做一些特殊处理 + +### 如何继承此类 + + * 所有在坐标系内的图表序列都可以继承这个类,步骤如下: + + 1. 覆写绘制序列的函数 + * draw(points,callback) 绘制函数,绘制完成后调用callback方法 + * processColor(color) 如果需要处理颜色覆写此方法 + 2. 覆写图形更改的方法 + + * changeShapes(points) 数据发生改变时触发 + + 3. 如果鼠标移动到序列上有actived状态,覆写状态相关的方法 + * setActiveStatus(actived) actived 状态发生改变时使用 + + 4. 如果处理鼠标事件覆写 + * bindMouseOver() + * bindMouseOut() + + * 对比[图表序列基类](1-base.html#如何继承)的继承步骤,继承Series.Cartesian简单了不少,必须覆写的方法只有 + + * draw(points,callback) + * changeShapes(points) + + * 继承Series.Cartesian的具体实例可以查看[折线图](3-line.md)和[柱状图](4-column.md),以及提供的demo + + + + + diff --git a/wiki/03-line.md b/wiki/03-line.md new file mode 100644 index 0000000..8e31c0b --- /dev/null +++ b/wiki/03-line.md @@ -0,0 +1,274 @@ +# 折线图 + +--- + +折线图 + +--- + +## 目录 + + * 简介 + * 折线图的构成 + * 数据处理 + * 曲线 + * 断点 + * 雷达图中的折线 + + +### 简介 + + * 折线图(Series.Line)是最常用的图表序列,是在坐标轴显示一系列的数据,并用线连接起来 + * 折线图必须在坐标轴中,无论是笛卡尔坐标还是极坐标,都是通过x轴,Y轴将数据转换成画布上的坐标,进行渲染 + +### 折线图的构成 + + * line 折线代表的图形,是一个path + * tracker 折线图背后隐藏的线,用于捕捉鼠标事件 + * markers 折线数据用marker标示出来 + * labels 折线数据用文本标示 + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'l1', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : -5, + max : 40, + position:'left', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var series = canvas.addGroup(Series.Line,{ + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + color : '#2f7ed8', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + lineActived : { + 'stroke-width': 3 + }, + animate : false, + markers : { + marker : { + + symbol : 'circle', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] + }); + + var traceLine = series.get('trackerShape'); + traceLine.attr('stroke-opacity',0.5); +}); +```` + +### 数据处理 + + * 折线图Series.Line继承 Series.Cartesian 所以不需要覆写处理数据的函数,因为折线图支持3种类型的数据格式 + + * 单个值是数字的格式,如 : data : [1,2,3,4] + * 单个值是数组的格式,如: data : [[10,100],[20,200]] + * 单个值是对象的格式,如: data : [{x:10,y:100},{x:10,y:100}] + + * 查看示例: [折线图数据类型示例](../examples/line.html#data-format),注意事项 + + * 3中格式可以混合使用,可以单个值的类型中夹杂数组和对象,如: [1,2,{x:4,y : 3},[5,6]] + * 对象中可以省略掉x 如: [1,2,{y : 3}] + * 对象中可以附加当前点的marker信息 : 如: [1,2,{y : 3,marker:{ symbol : 'circle'}}] + * x,y的属性名可以通过xField和yField配置 + ```js + //如果图表序列的配置项如下: + { + ... + xFiled : 'month', + yValue : 'tokyo' + ... + } + //则数据如下 + [{month : '一月',tokyo : 20},{month : '二月',tokyo : 30}] + ``` + * 同一个数据源可以用于多个数据序列: + + ```js + + var data = [{month : '一月',tokyo : 20,beijing:12},{month : '二月',tokyo : 30,beijing:32}]; + + //第一个图表序列配置项 + { + ... + xFiled : 'month', + yValue : 'tokyo' + ... + } + + //第二个 + { + ... + xFiled : 'month', + yValue : 'beijing' + ... + } + + ``` +### 曲线 + + * 折线图转换成曲线,增加配置项 smooth : true,[Demo示例](../examples/line.html#smooth) + * 折线转换成曲线是使用贝塞尔曲线替换一般的直线连接,会出现一些问题,例如 最小值是0,但是曲线会出现小于0的点,会造成歧义 + +### 断点 + + * 折线图中有些分类或者时间点上没有数据,此时传入null,在绘制图表序列时有2种方案: + + 1. 忽略掉null的点,直接连接将非null的点进行连接,connectNulls : true + 2. null的点不绘制,出现有断点的折线,这是折线提供的默认配置,connectNulls : false + + * 通过存在[断点的折线的demo](../examples/line.html#break-point)来了解具体的表现 + + +### 雷达图中显示折线 + + * 折线图显示在雷达图中,不需要额外的配置,仅需要将x轴设置成 Axis.Circle,y轴设置成 Axis.Radius即可 + * 雷达图中显示折线的demo如下: + + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'l3', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Circle,{ + plotRange : plotRange, + ticks : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Radius,{ + plotRange : plotRange, + line : null, + tickLine : null, + circle : xAxis, + grid : { + type : 'circle', + line : { + stroke : '#c0c0c0' + } + }, + min : -5, + max : 40, + position:'left', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var series = canvas.addGroup(Series.Line,{ + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + color : '#2f7ed8', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + lineActived : { + 'stroke-width': 3 + }, + animate : false, + smooth : true, + markers : { + marker : { + + symbol : 'circle', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] + }); + +}); +```` + diff --git a/wiki/04-area.md b/wiki/04-area.md new file mode 100644 index 0000000..db5cdd7 --- /dev/null +++ b/wiki/04-area.md @@ -0,0 +1,342 @@ +# 区域图 + +---- + +区域图 + +---- + +## 目录 + + * 简介 + * 区域 + * 区域图中的断点 + * 层叠区域图 + * 雷达图中的区域图 + +### 简介 + + * 区域图继承自折线图,除了包含折线图的line、marker和label外增加了一个阴影区域 area + * 用户的数据跟y轴上的0点位置或者最小值形成阴影区域,这个值我们称之基准值(baseValue)ss + * 当y坐标轴上存在0时,以0代表的坐标作为阴影区域的下坐标,即基准值是0 + * 当y坐标轴上不存在0时,以最小值作为阴影区域的下坐标,基准值是y轴的最小值 + +### 区域 + + * 区域图上的区域是将数据跟基准值形成的区域,是一个或者多个密封的path(存在断点时) + + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'a1', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : -5, + max : 40, + position:'left', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var series = canvas.addGroup(Series.Area,{ + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + color : '#2f7ed8', + line : { + 'stroke-width': 1, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + lineActived : { + 'stroke-width': 2 + }, + animate : false, + area : { + stroke : 'none', + fill : 'rgb(124, 181, 236)', + 'fill-opacity' : 0.5 + }, + markers : { + marker : { + + symbol : 'circle', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] + }); +}); +```` + +### 断点 + + * 如果数据中存在null,有2种处理方案: + * connectNulls : true 则忽略掉断点,直接连接断点2端的点 + * connectNulls : false 断点不进行连接,区域图被空白分割成多个区域 + * 下面的示例里面都存在断点,但是connectNulls的配置项不同,表现也不同 + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'a2', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Category,{ + plotRange : plotRange, + categories : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : -5, + max : 40, + position:'left', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + //不连接断点 + var series = canvas.addGroup(Series.Area,{ + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + color : '#2f7ed8', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + lineActived : { + 'stroke-width': 3 + }, + animate : false, + markers : { + marker : { + + symbol : 'circle', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [7.0, 6.9, 9.5, 14.5, null, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] + }); + + //断点进行连接 + var series1 = canvas.addGroup(Series.Area,{ + xAxis : xAxis, + yAxis : yAxis, + color : '#910000', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + animate : true, + connectNulls : true, + markers : { + marker : { + fill : '#910000', + stroke: '#910000', + symbol : 'diamond', + radius : 4 + } + }, + data: [-0.9, 0.6, 3.5, 8.4, null, 17.0, 18.6, null, 14.3, 9.0, 3.9, 1.0] + + }); + +}); +```` + +### 层叠的区域图 + + * 区域图有的场景下需要层叠展示,一个区域图展示在另一个区域图的上面,层叠图分为2种 + + * 和的累计,y坐标轴按照多个区域图的和进行计算 + * 百分比层叠,即所有区域图按照百分比占用y轴的的区域,整个y轴是100% + + * 通过下面的demo来熟悉这2种层叠图 + + * [一般层叠](../examples.html#stacked-area) + * [百分比层叠](../examples.html#percent-stacked-area) + + +### 雷达图中的区域图 + + * 雷达图中显示区域图,仅需要将x轴设置成 Axis.Circle,y轴设置成 Axis.Radius即可 + * 层叠区域图也可以显示在雷达图中 + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'r2', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Circle,{ + plotRange : plotRange, + tickInterval : 45, + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Radius,{ + plotRange : plotRange, + line : null, + tickLine : null, + circle : xAxis, + grid : { + type : 'circle', + line : { + stroke : '#c0c0c0' + } + }, + min : 0, + max : 10, + position:'left', + tickInterval : 2, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var series = canvas.addGroup(Series.Area,{ + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + color : '#2f7ed8', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + lineActived : { + 'stroke-width': 3 + }, + animate : false, + markers : { + marker : { + + symbol : 'circle', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [8, 4, 6, 5, 7, 3, 4, 1] + }); + +}); +```` + + + + diff --git a/wiki/05-column.md b/wiki/05-column.md new file mode 100644 index 0000000..e5e733b --- /dev/null +++ b/wiki/05-column.md @@ -0,0 +1,60 @@ +# 柱状图 + +---- + +柱状图 + +---- + +## 目录 + * 简介 + * 柱状图和坐标轴 + * 柱状图状态 + * 转置(bar) + * 雷达图中的柱状图 + +### 简介 + + * 柱状图使用柱状图形显示数据的起伏状态,可以很容易的跟折线图、区域图进行转换 + +### 柱状图和坐标轴 + + * 使用分类坐标轴作为x轴的柱状图,此时柱状图显示在分类中间,如果有多个柱状图,则自动计算各个柱状图的宽度 + * 使用时间坐标轴的作为x轴的柱状图,如果是均匀时间分布,则根据时间点的间隔计算宽度,否则根据平均宽度计算 + +### 柱状图的状态 + + * 柱状图有选中状态,当设置 allowPointSelect: true时点击柱状图选中,否则点击不响应。cancelSelect 决定再次点击时是否取消选中 + +#### 查看示例 + * [单个柱状图示例](../examples/column.html#single-column) + * [多个柱状图示例](../examples/column.html#multiple-column) + * [时间坐标轴柱状图](../examples/column.html#time-axis) + +### 图形转置 + + * 将柱状图的设置invert:true,将x轴,y轴的位置互换(position),即可以实现条形图(Bar) + * [条形图示例](../examples/column.html#bar) + + +### 柱状图层叠 + + * 柱状图的 stackType决定柱状图的层叠,默认情况下,stackType : 'none',不进行任何层叠处理 + * 设置stackType : 'normal',在柱状图中进行数据累加的层叠 + * 设置stackType : 'percent' 在柱状图中进行百分比的层叠 + +#### 查看示例 + * [层叠柱状图](../examples/column.html#stacked-column) + * [百分比层叠柱状图](../examples/column.html#percent-stacked-column) + * [层叠条形图示例](../examples/column.html#stacked-bar) + +### 雷达图中的柱状图 + * 雷达图中显示柱状图,仅需要将x轴设置成 Axis.Circle,y轴设置成 Axis.Radius即可 + * 层叠柱状图也可以显示在雷达图中 + +#### 示例 + * [雷达图中的柱状图示例](../examples/radar.html#column) + + + + diff --git a/wiki/06-pie.md b/wiki/06-pie.md new file mode 100644 index 0000000..f64f747 --- /dev/null +++ b/wiki/06-pie.md @@ -0,0 +1,210 @@ +# 饼图 + +--- + +饼图、环图 + +--- + +## 目录 + + * 简介 + * 饼图的一些概念 + * 饼图的文本 + * 环图 + * 环图嵌套 + * 饼图的状态 + * 更改数据 + +### 简介 + + * 饼图用于数据的对比,可以有多种展现方式: + * 一般的饼图 + * 半圆形饼图,将起始点和结束点设置成半圆 ,endAngle - startAngle = 180 + * 环形,提供2个半径,radius 和 innerRadius + * 嵌套饼图 + * 起始点不相等的嵌套环图 + + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-canvas','achart-plot'], function(Series,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'p1', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 400},{x : 850, y : 50}); + + var group = canvas.addGroup(); + + group.set('plotRange',plotRange); + + var pie = group.addGroup(Series.Pie,{ + autoPaint : false, + allowPointSelect : true, + labels : { + distance : 40, + label : { + + }, + renderer : function(value,item){ + return value + ' ' + (item.point.percent * 100).toFixed(2) + '%'; + } + }, + name: 'Browser share', + animate : false, + colors : [ '#5e90c9','#1c2d3f','#a9d052','#a12d2d','#43bbb4','#5a2a94','#fabe3c','#2279dc','#e360e5','#48000c'], + data: [ + ['Firefox', 45.0], + ['IE', 26.8], + { + name: 'Chrome', + y: 12.8, + sliced: true, + selected: true + }, + ['Safari', 8.5], + ['Opera', 6.2], + ['Others', 0.7] + ] + }); + + pie.paint(); + +}); +```` + +### 饼图的概念 + + * 饼图由以下部分构成 + * 每个饼图子项的圆弧 + * 每个圆弧对应一个文本、如果文本在外面存在连接线 + * 饼图的位置由 center(默认['50%','50%']) 标示 + * 饼图的半径(radius) 根据 size(默认 '80%' )自动计算,内部半径(innerRadius)由 innerSize自动计算 + +### 饼图的文本 + + * 饼图的文本可以显示在图形的外侧,会自动进行排版,如果文本过多会进行一些处理 + * 饼图的文本也可以显示在文本内部,自动计算文本的旋转值 + +#### 文本示例 + + * [内部显示文本示例](../examples/pie.html#inner-text) + * [多文本示例](../examples/pie.html#multiple-text) + +### 环图 + + * 设置innerSize 或者 innerRadius 会形成环图,innerSize 可以数字也可以是带有%号的文本,会自动计算 + + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-canvas','achart-plot'], function(Series,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'p4', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 400},{x : 850, y : 50}); + + var group = canvas.addGroup(); + + group.set('plotRange',plotRange); + + var pie = group.addGroup(Series.Pie,{ + autoPaint : false, + allowPointSelect : true, + labels : { + distance : 40, + label : { + + }, + renderer : function(value,item){ + return value + ' ' + (item.point.percent * 100).toFixed(2) + '%'; + } + }, + innerSize : '60%', + name: 'Browser share', + animate : false, + colors : [ '#5e90c9','#1c2d3f','#a9d052','#a12d2d','#43bbb4','#5a2a94','#fabe3c','#2279dc','#e360e5','#48000c'], + data: [ + ['Firefox', 45.0], + ['IE', 26.8], + { + name: 'Chrome', + y: 12.8, + sliced: true, + selected: true + }, + ['Safari', 8.5], + ['Opera', 6.2], + ['Others', 0.7] + ] + }); + + pie.paint(); + +}); +```` + +### 环图嵌套 + + * 通过radius,innerRadius的设置可以达到环图嵌套的效果 + * 通过设置startAngle和endAngle可以实现一些特殊的效果 + * 可以在饼图的子项中设置 placeHolder: true,作为占位而不显示,也不会有状态变化 + +#### 示例 + + * [嵌套示例](../examples/pie.html#nest-ring) + +### 饼图的状态 + + * 饼图的hover 和 out有对应的的样式变化 + * 饼图的seleced 由属性 allowPointSelect 决定,当 cancelSelect=false时,再次点击不取消selected状态 + + ```js + + events : { + itemclick : function(ev){ + console.log('click'); + }, + itemselected : function(ev){ + console.log('selected'); + }, + itemunselected : function(ev){ + console.log('unselected'); + }, + itemactived : function(ev){ + console.log('actived'); + }, + itemunactived : function(ev){ + console.log('unactived'); + } + } + + ``` + +### 更改数据 + + * 饼图直接调用changeData(data,redraw) 方法,整个饼图会发生改变 + + diff --git a/wiki/07-stacked.md b/wiki/07-stacked.md new file mode 100644 index 0000000..7514485 --- /dev/null +++ b/wiki/07-stacked.md @@ -0,0 +1,74 @@ +# 序列层叠 + +--- + +处理区域图、柱状图的层叠的扩展 + +--- + +## 目录 + + * 简介 + * 层叠类型 + * 提供的方法 + * 使用此扩展 + +## 简介 + + * 柱状图、区域图会发生层叠,层叠的方式有2种 + + * 累加层叠,在x轴同一位置的点进行累加,后一个序列在前一个序列的基础上增加y坐标 + * 百分比层叠,在x轴同一位置的个序列点的占比,进行层叠 + + * 由于柱状图、区域图的层叠行为完全一致,很多逻辑也相同,但是这2种序列没有继承关系,所以将序列层叠功能实现成扩展 + + +### 层叠类型 + + * stackType :none ,表示无层叠 + * stackType : 'normal' 标示累加层叠 + * stackType : 'percent' 标示百分比层叠 + +### 提供的方法 + + * isStacked() 数据序列是否层叠 + * processStackedPoint(point,index) 提供的受保护的方法 + +### 使用此扩展 + + * 创建图表序列,从现有的数据序列基础上继承出新的图表序列 + * 调用 Util.mixin([Stacked]),使用此扩展 + * 覆写 processPoint(point,index) 方法,判断是是否是层叠序列,调用processStackedPoint(point,index) 方法 + * 渲染内部图形时,存在point.lowY 图形的下坐标,可以绘制层叠效果 + + ```js + + var C = function(cfg){ + C.superclass.constructor.call(this,cfg); + }; + + Util.extend(C,Axis.Cartesian); + + Util.mixin(C,[Stacked]); + + Util.augment(C,{ + + ... + + processPoint : function(point,index){ + var _self = this; + if(_self.isStacked()){ + _self.processStackedPoint(point,index); + } + } + + ... + }); + + ``` + +### 示例 + + * [区域图层叠](../examples/area.html#stacked-area) + * [柱状图层叠](../examples/column.html#stacked-column) + * [雷达图层叠](../examples/radar.html#column-stacked) diff --git a/wiki/08-itemgroup.md b/wiki/08-itemgroup.md new file mode 100644 index 0000000..a25557e --- /dev/null +++ b/wiki/08-itemgroup.md @@ -0,0 +1,13 @@ +# 序列子项 + +--- + +图表序列中的子项,例如柱状图中的单个项,饼图中的一个弧形 + +--- + +## 目录 + + * 简介 + * 提供的功能 + * 如何使用 \ No newline at end of file diff --git a/wiki/09-radar.md b/wiki/09-radar.md new file mode 100644 index 0000000..30c0a83 --- /dev/null +++ b/wiki/09-radar.md @@ -0,0 +1,128 @@ +# 雷达图 + +--- + +各种图形在雷达图中的表现 + +--- + +## 目录 + + * 简介 + * 如何实现雷达图 + * 雷达图的栅格 + * 数据序列如何适应雷达图 + +### 简介 + + * 雷达图使用极坐标系,雷达图不是一个数据序列,仅仅是x轴使用 [圆形坐标轴(Axis.Circle)](http://spmjs.io/docs/achart-axis/wiki/5-circle.html),y轴使用[Axis.Radius](http://spmjs.io/docs/achart-axis/wiki/5-circle.html#半径坐标轴) + * 折线图、柱状图、区域图都可以显示在雷达图中,层叠的柱状图、区域图也可以正常在雷达图中显示 + +### 如何实现雷达图 + + * 使用Axis.Circle创建x坐标轴,使用Axis.Radius 创建y坐标轴 + * 折线图、柱状图、区域图按照正常方式创建,无任何其他配置信息 + + +````html +
+ +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot'], function(Series,Axis,Canvas,Plot) { + + var canvas = new Canvas({ + id : 'r1', + width : 800, + height : 500 + }); + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Circle,{ + plotRange : plotRange, + ticks : ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], + labels : { + label : { + y : 12 + } + } + }); + + var yAxis = canvas.addGroup(Axis.Radius,{ + plotRange : plotRange, + line : null, + tickLine : null, + circle : xAxis, + grid : { + type : 'circle', + line : { + stroke : '#c0c0c0' + } + }, + min : -5, + max : 40, + position:'left', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + canvas.sort(); + + var series = canvas.addGroup(Series.Line,{ + xAxis : xAxis, + yAxis : yAxis, + labels : { + label : { + y : -15 + } + }, + color : '#2f7ed8', + line : { + 'stroke-width': 2, + 'stroke-linejoin': 'round', + 'stroke-linecap': 'round' + }, + lineActived : { + 'stroke-width': 3 + }, + animate : false, + smooth : true, + markers : { + marker : { + + symbol : 'circle', + radius : 4 + }, + actived : { + radius : 6, + stroke: '#fff' + } + }, + data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] + }); + +}); +```` + +### 雷达图的栅格 + + * x轴(圆形坐标轴)的栅格是从圆心出发,连接到圆上的直线 + * y轴(半径坐标轴)的栅格是与x轴的圆形轴线相同圆心的同心圆,也可以是多边形 + * y轴的栅格的类型由 type属性控制,有2种格式: circle和polygon + +### 图表序列对雷达图的支持 + + * 折线图仅需要将原有的path 增加 'z',变成闭环的折线 + * 区域图连接到x轴上的点,改成全部连接到圆心即可 + * 柱状图 将矩形改成圆弧即可 + + + diff --git a/wiki/10-change.md b/wiki/10-change.md new file mode 100644 index 0000000..89a8b70 --- /dev/null +++ b/wiki/10-change.md @@ -0,0 +1,13 @@ +# 更改数据 + +--- + +更改图表序列数据 + +--- + +## 目录 + + * 简介 + * 更改数据 + * 添加数据 \ No newline at end of file diff --git a/wiki/11-custom.md b/wiki/11-custom.md new file mode 100644 index 0000000..58aa15a --- /dev/null +++ b/wiki/11-custom.md @@ -0,0 +1,468 @@ +# 实现一个图表序列 + +--- + +详细的讲述了实现图表序列的步骤和方法 + +--- + +## 目录 + + * 简介 + * 实现一个图表序列 + * 使用坐标轴的图表序列 + * 更多 + +### 简介 + + * 图表序列的基类和现有的图表序列已经实现了大量功能,如果用户需要自定义的数据序列时,可以使用现有的图表序列进行扩展 + + * 如果不使用坐标轴,则继承Series类 + * 使用坐标轴,则继承Series.Cartesian(使用坐标系的图表序列) + * 如果图表序列需要层叠功能,引入[Series.Stacked扩展](07-stacked.md) + * 如果图表序列内部有多个子项,同时子项存在选中(selected)功能,则可以引入[Series.ItemGroup扩展](08-itemgroup.md) + +### 一般的图表序列 + + * 一般的图表序列从图表序列基类Series继承,步骤如下: + + 1. 覆写绘制序列的函数 + + * draw(points,callback) 绘制函数,绘制完成后调用callback方法 + * processColor(color) 如果需要处理颜色覆写此方法 + + 2. 覆写转换数据的方法 + + * getPointByIndex(value,index) 处理单个数值,根据数值在数组中的索引获取对应的点 + * getPointByValue(xValue,yValue) 将对应的x值和y值传入函数,如果数据源是数组,则在返回的点上附加 point.arr = arr;如果数据源是对象则 point.obj = obj; + * processPoint(point,index) 如果需要特别处理转换的点,覆写此函数 + + 3. 覆写图形更改的方法 + + * changeShapes(points) 数据发生改变时触发 + + 4. 覆写状态相关的方法 + + * setActiveStatus(actived) actived 状态发生改变时使用 + + 5. 如果处理鼠标事件覆写 + + * bindMouseOver() + * bindMouseOut() + + * 必须覆写的方法 + + * draw(points,callback) 绘制内部图形 + * changeShapes(points) 图形发生改变时 + * getPointByIndex(value,index) 处理最基本的数据类型 data : [1,2,3,4] + +#### 示例 + + * 下面是一个漏斗图的示例 + +````html + +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot','achart-util'], function(Series,Axis,Canvas,Plot,Util) { + + var Funnel = function(cfg){ + Funnel.superclass.constructor.call(this,cfg); + }; + + Util.extend(Funnel,Series); + + Funnel.ATTRS = { + colors : ['#ff6600','#b01111','#ac5724','#572d8a'], + xField : 'name', + yField : 'value', + width : null, + item : { + stroke : '#fff' + } + }; + + Util.augment(Funnel,{ + renderUI : function(){ + this._sortData(this.get('data')); + Funnel.superclass.renderUI.call(this); + + }, + //处理节点前,对数据进行排序 + _sortData : function(data){ + data.sort(function(obj1,obj2){ + return obj2.value - obj1.value; + }); + }, + getPointByValue : function(name,value) { + return {xValue : name,value : value}; + }, + + processPoint : function(point,index){ + var _self = this, + width = _self.get('width'), + startPoint = _self._getStartPoint(), + centerX = (startPoint.x + width/2), + avgHeight = _self._getAvgHeight(), + curY = startPoint.y + avgHeight * index, + centerY = curY + avgHeight/2; + + point.x = centerX; + point.y = centerY; + + point.beginY = curY; + point.endY = curY + avgHeight; + + }, + draw : function(points,callback){ + var _self = this; + + Util.each(points,function(point,index){ + _self._drawPoint(point,index); + }); + + callback && callback(); + }, + _getAvgHeight : function(){ + return this.get('width')/this.get('data').length; + }, + _drawPoint : function(point,index){ + var _self = this, + cfg = _self._getItemCfg(point,index); + + cfg.path = _self._getItemPath(point,index); + _self.addShape('path',cfg); + + if(_self.get('labels')){ + _self.addLabel(point.xValue,point); + } + }, + //省略逻辑直接设置20,20,否则需要根据plotRange计算 + _getStartPoint : function(){ + return {x : 20,y:20}; + }, + //获取最大的值 + _getMaxValue : function(){ + return this.get('data')[0].value; + }, + //获取节点的path + _getItemPath : function(point,index){ + var _self = this, + max = _self._getMaxValue(), + width = _self.get('width'), + points = _self.getPoints(), + nextValue = points[index + 1] ? points[index + 1].value : 0; + + var tl = point.x - (point.value/max) * width/2; + tr = point.x + (point.value/max) * width/2, + bl = point.x - (nextValue/max) * width/2, + br = point.x + (nextValue/max) * width/2; + + return [['M',tl,point.beginY],['L',tr,point.beginY],['L',br,point.endY],['L',bl,point.endY],['z']]; + }, + _getItemCfg : function(point,index){ + var _self = this, + colors = _self.get('colors'), + item = _self.get('item'), + rst = {}; + + Util.mix(rst,item); + rst.fill = colors[index%colors.length]; + return rst; + } + + }); + + var canvas = new Canvas({ + id : 'c1', + width : 800, + height : 500 + }); + + canvas.addGroup(Funnel,{ + width : 400, + labels : { + label : { + 'font-size' : '16px', + fill : '#fff' + } + }, + data : [ + {value:60, name:'访问'}, + {value:40, name:'咨询'}, + {value:20, name:'订单'}, + {value:80, name:'点击'}, + {value:100, name:'展现'} + ] + }); + + +}); + +```` + +#### 几点说明 + + * 处理漏斗图的节点前,需要对数据进行排序,所以在renderUI 里面进行了处理 + * 覆写了 getPointByValue,draw,processPoint方法 + * 更改数据、鼠标事件的方法未覆写,用户可以自己实现 + * 功能更加全面的漏斗图会在后面的acharts版本中提供 + +### 使用坐标轴的图表序列 + + * 使用坐标轴的图表序列,一般继承自Series.Cartesian,步骤如下: + + 1. 覆写绘制序列的函数 + * draw(points,callback) 绘制函数,绘制完成后调用callback方法,如果需要平铺效果,可以在内部调用 animateClip(fn,callback) + * processColor(color) 如果需要处理颜色覆写此方法 + 2. 覆写图形更改的方法 + + * changeShapes(points) 数据发生改变时触发 + + 3. 如果鼠标移动到序列上有actived状态,覆写状态相关的方法 + * setActiveStatus(actived) actived 状态发生改变时使用 + + 4. 如果处理鼠标事件覆写 + * bindMouseOver() + * bindMouseOut() + + + + * 对比[图表序列基类](1-base.html#如何继承)的继承步骤,继承Series.Cartesian简单了不少,必须覆写的方法只有 + + * draw(points,callback) + * changeShapes(points) + + +#### 示例 + + * 本示例是个简单的范围图,可以显示同一点的最大值和最小值,例如可以显示一段时间的最高温度和最低温度 + + + +````html + +
+ +```` + +````javascript + +seajs.use(['index','achart-axis','achart-canvas','achart-plot','achart-util'], function(Series,Axis,Canvas,Plot,Util) { + + var Range = function(cfg){ + Range.superclass.constructor.call(this,cfg); + }; + + Util.extend(Range,Series.Cartesian); + + Range.ATTRS = { + area : { + + }, + line : { + + } + }; + + Util.augment(Range,{ + //处理颜色 + processColor : function(color){ + var _self =this, + line = _self.get('line'), + area = _self.get('area'); + if(!line.stroke){ + line.stroke = color; + } + if(!area.fill){ + area.fill = color; + } + }, + //覆写draw方法 + draw : function(points,callback){ + var _self = this; + + _self.animateClip(function(){ + _self._drawLine(points); + _self._drawArea(points); + },callback); + + }, + //处理节点 + processPoint : function(point,index){ + + var _self = this, + yAxis = _self.get('yAxis'), + arr = point.arr; + point.lowY = point.y; + point.highY = yAxis.getOffset(arr[arr.length - 1]); + }, + //绘制line + _drawLine : function(points){ + var _self = this, + line = _self.get('line'), + cfg = Util.mix({},line); + + cfg.path = _self.point2path(points); + lineShape = _self.addShape('path',cfg); + + _self.set('lineShape',lineShape); + }, + //绘制area + _drawArea : function(points){ + var _self = this, + area = _self.get('area'), + cfg = Util.mix({},area); + + cfg.path = _self.point2Area(points); + var areaShape = _self.addShape('path',cfg); + _self.set('areaShape',areaShape); + }, + //获取线的path + point2path : function(points){ + var path = [], + count = points.length; + + path.push(['M',points[0].x,points[0].highY]); + for(var i = 1; i < count;i++){ + var item = ['L',points[i].x,points[i].highY]; + path.push(item); + } + + path.push(['M',points[count-1].x,points[count-1].lowY]); + + for(var i = count - 2;i >=0 ;i--){ + var item = ['L',points[i].x,points[i].lowY]; + path.push(item); + } + return path; + }, + //获取区域的path + point2Area : function(points){ + var _self = this, + path = _self.point2path(points); + + path[points.length][0]='L'; + + path.push(['z']); + return path; + }, + //更改数据时 + changeShapes : function(points){ + var _self = this, + lineShape = _self.get('lineShape'), + areaShape = _self.get('areaShape'), + linePath = _self.point2path(points), + areaPath = _self.point2Area(points); + + lineShape.attr('path',linePath); + areaShape.attr('path',areaPath); + } + + }); + + var canvas = new Canvas({ + id : 'c2', + width : 800, + height : 500 + }); + + + var plotRange = new Plot.Range({x : 50,y : 450},{x : 750, y : 50}), + xAxis = canvas.addGroup(Axis.Time,{ + plotRange : plotRange, + startDate : 1230771600000, + endDate : 1232672400000, + tickInterval :2 * 24 * 3600 * 1000, + labels : { + label : { + y : 12 + } + }, + tickOffset : 10, + formatter : function(value){ + var date = new Date(value) + return date.getFullYear() + '-'+ (date.getMonth() + 1) + '-' + date.getDate(); + } + }); + + var yAxis = canvas.addGroup(Axis.Number,{ + plotRange : plotRange, + line : null, + tickLine : null, + grid : { + line : { + stroke : '#c0c0c0' + } + }, + min : -10, + max : 10, + + position:'left', + tickInterval : 5, + labels : { + label : { + x : -12 + } + } + }); + + var range = canvas.addGroup(Range,{ + xAxis : xAxis, + yAxis : yAxis, + color : '#fc694b', + pointStart : 1230771600000, + pointInterval : 1* 24 * 3600 * 1000, + area : { + stroke : 'none', + + 'fill-opacity' : 0.5 + }, + data : [ + + [ -5.8, 0.1], + [ -4.1, 1.4], + [ -0.5, 4.1], + [ -8.9, -0.7], + [ -9.7, -3.7], + [ -3.4, 3.2], + [ -3.9, -0.2], + [ -2.4, 6.7], + [ 3.8, 6.9], + [ 3.1, 6.8], + [ 0.0, 7.6], + [ 5.6, 9.4], + [ 3.6, 6.5], + [ -3.6, 3.8], + [ -6.0, -1.5], + [ -3.8, 2.4], + [ 1.5, 4.2], + [ 0.0, 4.5], + [ -1.1, 3.6], + [ 0.5, 5.1], + [ 0.0, 2.5], + [-0.6, 2.1] + ] + + }); + +}); + +```` + +#### 几点说明 + + * Range 继承自Series.Cartesian,如果在Chart中使用此种图表,只需要注册 Series.Range = Range即可 + * Range 假设的数据格式是 [date.getTime(),min,max],或者是 [min,max] 格式的数据,所以默认生成的point 的格式 + * point.x 是对应的x坐标轴的位置 + * point.y 是最小值的y轴的坐标 + * point.value 是最小值min + * 数据中无date.getTime() 时,Range对象必须配置pointStart和pointInterval + + * processPoint 在point上注册了2个属性lowY 和highY,标示最小点的y轴坐标,和最大点的y轴坐标 + * animateClip 函数会执行一个从左到右的平铺动画 + diff --git a/wiki/index.md b/wiki/index.md new file mode 100644 index 0000000..5b39f76 --- /dev/null +++ b/wiki/index.md @@ -0,0 +1,47 @@ +# 简介 + +--- + +图表序列的简介 + +--- + + +## 目录 + + * 为什么提供 + * 实现了什么 + * 如何使用 + +### 为什么 + + * 在项目中有很多图表类型,折线图、柱状图、饼图等等,这些图表有相同的地方也有不同的地方。将每种图表类型实现成一个类的过程中,我们可以将共性的东西抽取成扩展,将不同的地方在各个类中特殊实现。 + * 所有类型的图表都是将数据转换成对应的图形,并响应鼠标事件,改变数据时图表随着改变。 + * 有些图表类型需要坐标轴的支持,通过坐标轴将数据转换成画布上的图形,所以通过数据自动生成坐标轴的功能也是必须的。 + +### 实现了什么 + + * 图表序列将数据转换成画布上的图形 + * 图表序列显示数据的标示(marker)和文本(label) + * 并对鼠标等事件作出响应,如mouseover,mouseout,mousemove等事件 + * 改变数据时重新绘制对应的图形 + * 初始绘制和改变过程中的动画 + +### 如何使用 + + * 图表序列的配置项比较繁琐,特别是使用了坐标轴的序列类型,所以在后面的模块里对图表序列的使用做了封装,也可以直接使用皮肤,减少繁琐的配置项 + * 本章的demo中仅仅为了说明如何创建图表序列和图表序列的功能 + +### 更多 + + * [基础图表序列](1-base.md) + * [笛卡尔积序列](2-cartesian.md) + * [折线图](3-line.md) + * [区域图](4-area.md) + * [柱状图](5-column.md) + * [饼图](6-pie.md) + * [序列层叠](7-stacked.md) + * [序列子项](8-itemgroup.md) + * [雷达图](9-radar.md) + * [实现自己的序列图](10-custom.md) + \ No newline at end of file