Bar.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. /**
  2. * @requires SuperMap.Feature.Theme.js
  3. * @requires SuperMap.Feature.Theme.Graph.js
  4. *
  5. */
  6. /**
  7. * Class: SuperMap.Feature.Theme.Bar
  8. * 柱状图 。
  9. *
  10. * 图表 Bar 配置对象 chartsSetting(<SuperMap.Layer.Graph::chartsSetting>) 可设属性如下:
  11. *
  12. * Symbolizer properties:
  13. * width - {Number} 专题要素(图表)宽度,必设参数。
  14. * height - {Number} 专题要素(图表)高度,必设参数。
  15. * codomain - {Array{Number}} 图表允许展示的数据值域,长度为 2 的一维数组,第一个元素表示值域下限,第二个元素表示值域上限,必设参数。
  16. * XOffset - {Number} 专题要素(图表)在 X 方向上的偏移值,单位像素。
  17. * YOffset - {Number} 专题要素(图表)在 Y 方向上的偏移值,单位像素。
  18. * dataViewBoxParameter - {Array{Number}} 数据视图框 dataViewBox 参数,
  19. * 它是指图表框 chartBox (由图表位置、图表宽度、图表高度构成的图表范围框)在左、下,右,上四个方向上的内偏距值。
  20. * 当使用坐标轴时 dataViewBoxParameter 的默认值为:[45, 15, 15, 15];不使用坐标轴时 dataViewBoxParameter 的默认值为:[5, 5, 5, 5]。
  21. * decimalNumber - {Number} 数据值数组 dataValues 元素值小数位数,数据的小数位处理参数,取值范围:[0, 16]。如果不设置此参数,在取数据值时不对数据做小数位处理。
  22. *
  23. * useBackground - {Boolean} 是否使用图表背景框,默认使用。
  24. * backgroundStyle - {Object} 背景样式,此样式对象对象可设属性: <SuperMap.Feature.ShapeParameters.Rectangle::style>。
  25. * backgroundRadius - {Array} 背景框矩形圆角半径,可以用数组分别指定四个角的圆角半径,设:左上、右上、右下、左下角的半径依次为 r1、r2、r3、r4 ,
  26. * 则 backgroundRadius 为 [r1、r2、r3、r4 ],默认值[0, 0, 0, 0]。
  27. *
  28. * xShapeBlank - {Array{Number}} 水平方向上的图形空白间隔参数。
  29. * 长度为 3 的数组,第一元素表示第一个图形左端与数据视图框左端的空白间距,第二个元素表示图形间空白间距,
  30. * 第三个元素表示最后一个图形右端与数据视图框右端端的空白间距 。
  31. *
  32. * showShadow - {Boolean} 阴影开关 默认是打开
  33. * barShadowStyle - {Object} 阴影样式,如:{shadowBlur : 8, shadowOffsetX: 2 , shadowOffsetY : 2,shadowColor : "rgba(100,100,100,0.8)"}
  34. * barLinearGradient - {Array} 按字段设置柱条样式[渐变开始颜色,渐变终止颜色] 与 themeLayer.themeFields 中的字段一一对应)
  35. * 如:[["#00FF00","#00CD00"],["#00CCFF","#5E87A2"],["#00FF66","#669985"],["#CCFF00","#94A25E"],["#FF9900","#A2945E"]]
  36. *
  37. * useAxis - {Boolean} 是否使用坐标轴,默认使用坐标轴。
  38. * axisStyle - {Object} 坐标轴样式,此样式对象对象可设属性: <SuperMap.Feature.ShapeParameters.Line::style> 。
  39. * axisUseArrow - {Boolean} 坐标轴是否使用箭头,默认值:false,不使用箭头。
  40. * axisYTick - {Number} y 轴刻度数量,默认值:0 ,不使用刻度。
  41. * axisYLabels - {Array{String}} y 轴上的标签组内容,标签顺序沿着数据视图框左面条边自上而下,等距排布。例如:["1000", "750", "500", "250", "0"]。
  42. * axisYLabelsStyle - {Object} y 轴上的标签组样式,此样式对象对象可设属性: <SuperMap.Feature.ShapeParameters.Label::style> 。
  43. * axisYLabelsOffset - {Array{Number}} y 轴上的标签组偏移量。长度为 2 的数组,数组第一项表示 y 轴标签组横向上的偏移量,向左为正,默认值:0;
  44. * 数组第二项表示 y 轴标签组纵向上的偏移量,向下为正,默认值:0。
  45. * axisXLabels - {Array{String}} x 轴上的标签组内容,标签顺序沿着数据视图框下面条边自左向右排布,例如:["92年", "95年", "99年"]。
  46. * 标签排布规则:当标签数量与 xShapeInfo 中的属性 xShapeCenter 数量相同(即标签个数与数据个数相等时), 按照 xShapeCenter 提供的位置排布标签,
  47. * 否则沿数据视图框下面条边等距排布标签。
  48. * axisXLabelsStyle - {Object} x 轴上的标签组样式,此样式对象对象可设属性: <SuperMap.Feature.ShapeParameters.Label::style> 。
  49. * axisXLabelsOffset - {Array{Number}} x 轴上的标签组偏移量。长度为 2 的数组,数组第一项表示 x 轴标签组横向上的偏移量,向左为正,默认值:0;
  50. * 数组第二项表示 x 轴标签组纵向上的偏移量,向下为正,默认值:0。
  51. * useXReferenceLine - {Boolean) 是否使用水平参考线,如果为 true,在 axisYTick 大于 0 时有效,水平参考线是 y 轴刻度在数据视图框里的延伸。
  52. * xReferenceLineStyle - {Object) 水平参考线样式,此样式对象对象可设属性: <SuperMap.Feature.ShapeParameters.Line::style> 。
  53. *
  54. * barStyle - {Object} 柱状图柱条基础 style,此参数控制柱条基础样式,优先级低于 barStyleByFields 和 barStyleByCodomain。
  55. * 此样式对象对象可设属性: <SuperMap.Feature.ShapeParameters.Polygon::style> 。
  56. * barStyleByFields - {Array{Object}} 按专题字段 themeFields(<SuperMap.Layer.Graph::themeFields>)为柱条赋 style,此参数按字段控制柱条样式,
  57. * 优先级低于 barStyleByCodomain,高于 barStyle。此数组中的元素是样式对象,其可设属性: <SuperMap.Feature.ShapeParameters.Polygon::style> 。
  58. * 此参数中的 style 与 themeFields 中的字段一一对应 。例如: themeFields(<SuperMap.Layer.Graph::themeFields>) 为 ["POP_1992", "POP_1995", "POP_1999"],
  59. * barStyleByFields 为[style1, style2, style3],则在图表中,字段 POP_1992 对应的柱条使用 style1,字段 POP_1995 对应的柱条使用 style2 ,字段 POP_1999 对应的柱条使用 style3。
  60. * barStyleByCodomain - {Array{Object}} 按柱条代表的数据值所在值域范围控制柱条样式,优先级高于 barStyle 和 barStyleByFields。
  61. * (start code)
  62. * // barStyleByCodomain 的每个元素是个包含值域信息和与值域对应样式信息的对象,该对象(必须)有三个属性:
  63. * // start: 值域值下限(包含);
  64. * // end: 值域值上限(不包含);
  65. * // style: 数据可视化图形的 style,这个样式对象的可设属性: <SuperMap.Feature.ShapeParameters.Polygon::style> 。
  66. * // barStyleByCodomain 数组形如:
  67. * [
  68. * {
  69. * start:0,
  70. * end:250,
  71. * style:{
  72. * fillColor:"#00CD00"
  73. * }
  74. * },
  75. * {
  76. * start:250,
  77. * end:500,
  78. * style:{
  79. * fillColor:"#00EE00"
  80. * }
  81. * },
  82. * {
  83. * start:500,
  84. * end:750,
  85. * style:{
  86. * fillColor:"#00FF7F"
  87. * }
  88. * },
  89. * {
  90. * start:750,
  91. * end:1500,
  92. * style:{
  93. * fillColor:"#00FF00"
  94. * }
  95. * }
  96. * ]
  97. * (end)
  98. * barHoverStyle - {Object} 柱条 hover 状态时的样式,barHoverAble 为 true 时有效。
  99. * barHoverAble - {Object} 是否允许柱条使用 hover 状态,默认允许。同时设置 barHoverAble 和 barClickAble 为 false,可以直接屏蔽柱条对专题图层事件的响应。
  100. * barClickAble - {Object} 是否允许柱条被点击,默认允许。同时设置 barHoverAble 和 barClickAble 为 false,可以直接屏蔽柱条对专题图层事件的响应。
  101. *
  102. * Inherits:
  103. * - <SuperMap.Feature.Theme.Graph>
  104. */
  105. SuperMap.Feature.Theme.Bar = SuperMap.Class(SuperMap.Feature.Theme.Graph, {
  106. /**
  107. * Constructor: SuperMap.Feature.Theme.Bar
  108. * 创建一个柱状图表。
  109. *
  110. * Parameters:
  111. * data - {<SuperMap.Feature.Vector>} 用户数据,必设参数。
  112. * layer - {<SuperMap.Layer.Graph>} 此专题要素所在图层,必设参数。
  113. * fields - {Array{String}} data 属性中的参与此图表生成的属性字段名称,必设参数。
  114. * setting - {Object} 图表配置对象,必设参数。
  115. * lonlat - {<SuperMap.LonLat>} 专题要素地理位置。默认为 data 指代的地理要素 Bounds 中心。
  116. *
  117. * Returns:
  118. * {<SuperMap.Feature.Theme.Bar>} 返回一个柱状图表对象。
  119. */
  120. initialize: function(data, layer, fields, setting, lonlat) {
  121. SuperMap.Feature.Theme.Graph.prototype.initialize.apply(this, arguments);
  122. },
  123. /**
  124. * APIMethod: destroy
  125. * 销毁对象。调用 destroy 后此对象所以属性置为 null。
  126. */
  127. destroy: function() {
  128. SuperMap.Feature.Theme.Graph.prototype.destroy.apply(this, arguments);
  129. },
  130. /**
  131. * Method: assembleShapes
  132. * 图表图形装配函数
  133. */
  134. assembleShapes: function(){
  135. //默认渐变颜色数组
  136. var deafaultColors = [["#00FF00","#00CD00"],["#00CCFF","#5E87A2"],["#00FF66","#669985"],["#CCFF00","#94A25E"],["#FF9900","#A2945E"]];
  137. //默认阴影
  138. var deafaultShawdow = {showShadow: true ,
  139. shadowBlur : 8,
  140. shadowColor : "rgba(100,100,100,0.8)",
  141. shadowOffsetX: 2 ,
  142. shadowOffsetY : 2};
  143. // 图表配置对象
  144. var sets = this.setting;
  145. if(!sets.barLinearGradient) sets.barLinearGradient = deafaultColors;
  146. // 默认数据视图框
  147. if(!sets.dataViewBoxParameter){
  148. if(typeof(sets.useAxis) === "undefined" || sets.useAxis){
  149. sets.dataViewBoxParameter = [45, 15, 15, 15];
  150. }
  151. else{
  152. sets.dataViewBoxParameter = [5, 5, 5, 5];
  153. }
  154. }
  155. // 重要步骤:初始化参数
  156. if(!this.initBaseParameter()) return;
  157. // 值域
  158. var codomain = this.DVBCodomain;
  159. // 重要步骤:定义图表 Bar 数据视图框中单位值的含义
  160. this.DVBUnitValue = (codomain[1]-codomain[0])/this.DVBHeight;
  161. // 数据视图域
  162. var dvb = this.dataViewBox;
  163. // 用户数据值
  164. var fv = this.dataValues;
  165. if(fv.length < 1) return; // 没有数据
  166. // 数据溢出值域范围处理
  167. for(var i = 0, fvLen = fv.length; i < fvLen; i++){
  168. if(fv[i] < codomain[0] || fv[i] > codomain[1]) return;
  169. }
  170. // 获取 x 轴上的图形信息
  171. var xShapeInfo = this.calculateXShapeInfo();
  172. if(!xShapeInfo) return;
  173. // 每个柱条 x 位置
  174. var xsLoc = xShapeInfo.xPositions;
  175. // 柱条宽度
  176. var xsWdith = xShapeInfo.width;
  177. // 背景框,默认启用
  178. if(typeof(sets.useBackground) === "undefined" || sets.useBackground){
  179. // 将背景框图形添加到模型的 shapes 数组,注意添加顺序,后添加的图形在先添加的图形之上。
  180. this.shapes.push(SuperMap.Feature.ShapeFactory.Background(this.shapeFactory, this.chartBox, sets));
  181. }
  182. // 坐标轴, 默认启用
  183. if(typeof(sets.useAxis) === "undefined" || sets.useAxis){
  184. // 添加坐标轴图形数组
  185. this.shapes = this.shapes.concat(SuperMap.Feature.ShapeFactory.GraphAxis(this.shapeFactory, dvb, sets, xShapeInfo));
  186. }
  187. for(var i = 0; i < fv.length; i++){
  188. // 计算柱条 top 边的 y 轴坐标值
  189. var yPx = dvb[1] - (fv[i] - codomain[0])/this.DVBUnitValue;
  190. // 柱条节点数组
  191. var poiLists = [
  192. [xsLoc[i] - xsWdith/2, dvb[1]-1],
  193. [xsLoc[i] + xsWdith/2, dvb[1]-1],
  194. [xsLoc[i] + xsWdith/2, yPx],
  195. [xsLoc[i] - xsWdith/2, yPx]
  196. ];
  197. // 柱条参数对象(一个面参数对象)
  198. var barParams = new SuperMap.Feature.ShapeParameters.Polygon(poiLists);
  199. // 柱条 阴影 style
  200. if(typeof(sets.showShadow) === "undefined" || sets.showShadow){
  201. if(sets.barShadowStyle){
  202. var sss = sets.barShadowStyle;
  203. if(sss.shadowBlur) deafaultShawdow.shadowBlur = sss.shadowBlur;
  204. if(sss.shadowColor) deafaultShawdow.shadowColor = sss.shadowColor;
  205. if(sss.shadowOffsetX) deafaultShawdow.shadowOffsetX = sss.shadowOffsetX;
  206. if(sss.shadowOffsetY) deafaultShawdow.shadowOffsetY = sss.shadowOffsetY;
  207. }
  208. barParams.style = {};
  209. SuperMap.Util.copyAttributesWithClip(barParams.style, deafaultShawdow);
  210. }
  211. // 图形携带的数据信息
  212. barParams.refDataID = this.data.id;
  213. barParams.dataInfo = {
  214. field: this.fields[i],
  215. value: fv[i]
  216. };
  217. // 柱条 hover click
  218. if(typeof(sets.barHoverAble) !== "undefined"){
  219. barParams.hoverable = sets.barHoverAble;
  220. }
  221. if(typeof(sets.barClickAble) !== "undefined"){
  222. barParams.clickable = sets.barClickAble;
  223. }
  224. // 创建柱条并添加到图表图形数组中
  225. this.shapes.push(this.shapeFactory.createShape(barParams));
  226. }
  227. // 重要步骤:将图形转为由相对坐标表示的图形,以便在地图平移缩放过程中快速重绘图形
  228. // (统计专题图模块从结构上要求使用相对坐标,assembleShapes() 函数必须在图形装配完成后调用 shapesConvertToRelativeCoordinate() 函数)
  229. this.shapesConvertToRelativeCoordinate();
  230. },
  231. /**
  232. * Method: calculateXShapeInfo
  233. * 计算 X 轴方向上的图形信息,此信息是一个对象,包含两个属性,
  234. * 属性 xPositions 是一个一维数组,该数组元素表示图形在 x 轴方向上的像素坐标值,
  235. * 如果图形在 x 方向上有一定宽度,通常取图形在 x 方向上的中心点为图形在 x 方向上的坐标值。
  236. * width 表示图形的宽度(特别注意:点的宽度始终为 0,而不是其直径)。
  237. *
  238. * 本函数中图形配置对象 setting 可设属性:
  239. * Symbolizer properties:
  240. * xShapeBlank - {Array{Number}} 水平方向上的图形空白间隔参数。
  241. * 长度为 3 的数组,第一元素表示第一个图形左端与数据视图框左端的空白间距,第二个元素表示图形间空白间距,
  242. * 第三个元素表示最后一个图形右端与数据视图框右端端的空白间距 。
  243. *
  244. * Returns:
  245. * {Object} 如果计算失败,返回 null;如果计算成功,返回 X 轴方向上的图形信息,此信息是一个对象,包含以下两个属性:
  246. * Symbolizer properties:
  247. * xPositions - {Array{Number}} 表示图形在 x 轴方向上的像素坐标值,如果图形在 x 方向上有一定宽度,通常取图形在 x 方向上的中心点为图形在 x 方向上的坐标值。
  248. * width - {Number} 表示图形的宽度(特别注意:点的宽度始终为 0,而不是其直径)。
  249. *
  250. */
  251. calculateXShapeInfo: function(){
  252. var dvb = this.dataViewBox; // 数据视图框
  253. var sets = this.setting; // 图表配置对象
  254. var fvc = this.dataValues.length; // 数组值个数
  255. if(fvc < 1) return null;
  256. var xBlank; // x 轴空白间隔参数
  257. var xShapePositions = []; // x 轴上图形的位置
  258. var xShapeWidth = 0; // x 轴上图形宽度(自适应)
  259. var dvbWidth = this.DVBWidth; // 数据视图框宽度
  260. // x 轴空白间隔参数处理
  261. if(sets.xShapeBlank && sets.xShapeBlank.length && sets.xShapeBlank.length == 3){
  262. xBlank = sets.xShapeBlank;
  263. var xsLen = dvbWidth - (xBlank[0] + xBlank[2] + (fvc - 1)*xBlank[1]);
  264. if(xsLen <= fvc){ return null; }
  265. xShapeWidth = xsLen/fvc
  266. }
  267. else{
  268. // 默认使用等距离空白间隔,空白间隔为图形宽度
  269. xShapeWidth = dvbWidth/(2*fvc + 1);
  270. xBlank = [xShapeWidth, xShapeWidth, xShapeWidth];
  271. }
  272. // 图形 x 轴上的位置计算
  273. var xOffset = 0
  274. for(var i = 0; i < fvc; i++){
  275. if(i == 0){
  276. xOffset = xBlank[0] + xShapeWidth/2;
  277. }
  278. else{
  279. xOffset += (xShapeWidth + xBlank[1]);
  280. }
  281. xShapePositions.push(dvb[0] + xOffset);
  282. }
  283. return {
  284. "xPositions": xShapePositions,
  285. "width": xShapeWidth
  286. };
  287. },
  288. /**
  289. * Method: resetLinearGradient
  290. * 图表的相对坐标存在的时候,重新计算渐变的颜色
  291. * PS: (目前用于二维柱状图 所以子类实现此方法)
  292. */
  293. resetLinearGradient: function(){
  294. if(this.RelativeCoordinate){
  295. var shpelength = this.shapes.length;
  296. var barLinearGradient = this.setting.barLinearGradient;
  297. var index = -1;
  298. for(var i = 0; i < shpelength; i++){
  299. var shape = this.shapes[i];
  300. if(shape.CLASS_NAME === "SuperMap.LevelRenderer.Shape.SmicPolygon"){
  301. var style = shape.style;
  302. //计算出当前的绝对 x y
  303. var x1 = this.location[0] + style.pointList[0][0];
  304. var x2 = this.location[0] + style.pointList[1][0];
  305. //渐变颜色
  306. index++;
  307. //以防定义的颜色数组不够用
  308. if(index >= barLinearGradient.length) index = index % barLinearGradient.length;
  309. var color1 = barLinearGradient[index][0];
  310. var color2 = barLinearGradient[index][1];
  311. //颜色
  312. var zcolor = new SuperMap.LevelRenderer.Tool.Color();
  313. var linearGradient = zcolor.getLinearGradient(x1, 0, x2, 0,
  314. [[0, color1],[1,color2]]);
  315. //赋值
  316. shape.style.color = linearGradient;
  317. }
  318. }
  319. }},
  320. CLASS_NAME: "SuperMap.Feature.Theme.Bar"
  321. });