Cartesian.html 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>The source code</title>
  6. <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7. <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8. <style type="text/css">
  9. .highlight { display: block; background-color: #ddd; }
  10. </style>
  11. <script type="text/javascript">
  12. function highlight() {
  13. document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
  14. }
  15. </script>
  16. </head>
  17. <body onload="prettyPrint(); highlight();">
  18. <pre class="prettyprint lang-js"><span id='Ext-chart-series-Cartesian'>/**
  19. </span> * @class Ext.chart.series.Cartesian
  20. *
  21. * Common base class for series implementations which plot values using x/y coordinates.
  22. */
  23. Ext.define('Ext.chart.series.Cartesian', {
  24. /* Begin Definitions */
  25. extend: 'Ext.chart.series.Series',
  26. alternateClassName: ['Ext.chart.CartesianSeries', 'Ext.chart.CartesianChart'],
  27. /* End Definitions */
  28. <span id='Ext-chart-series-Cartesian-property-xField'> /**
  29. </span> * The field used to access the x axis value from the items from the data
  30. * source.
  31. *
  32. * @cfg xField
  33. * @type String
  34. */
  35. xField: null,
  36. <span id='Ext-chart-series-Cartesian-property-yField'> /**
  37. </span> * The field used to access the y-axis value from the items from the data
  38. * source.
  39. *
  40. * @cfg yField
  41. * @type String
  42. */
  43. yField: null,
  44. <span id='Ext-chart-series-Cartesian-cfg-axis'> /**
  45. </span> * @cfg {String/String[]} axis
  46. * The position of the axis to bind the values to. Possible values are 'left', 'bottom', 'top' and 'right'.
  47. * You must explicitly set this value to bind the values of the line series to the ones in the axis, otherwise a
  48. * relative scale will be used. For example, if you're using a Scatter or Line series and you'd like to have the
  49. * values in the chart relative to the bottom and left axes then `axis` should be `['left', 'bottom']`.
  50. */
  51. axis: 'left',
  52. getLegendLabels: function() {
  53. var me = this,
  54. labels = [],
  55. fields, i, ln,
  56. combinations = me.combinations,
  57. title,
  58. combo, label0, label1;
  59. fields = [].concat(me.yField);
  60. for (i = 0, ln = fields.length; i &lt; ln; i++) {
  61. title = me.title;
  62. // Use the 'title' config if present, otherwise use the raw yField name
  63. labels.push((Ext.isArray(title) ? title[i] : title) || fields[i]);
  64. }
  65. // Handle yFields combined via legend drag-drop
  66. // TODO need to check to see if this is supported in extjs 4 branch
  67. if (combinations) {
  68. combinations = Ext.Array.from(combinations);
  69. for (i = 0, ln = combinations.length; i &lt; ln; i++) {
  70. combo = combinations[i];
  71. label0 = labels[combo[0]];
  72. label1 = labels[combo[1]];
  73. labels[combo[1]] = label0 + ' &amp; ' + label1;
  74. labels.splice(combo[0], 1);
  75. }
  76. }
  77. return labels;
  78. },
  79. <span id='Ext-chart-series-Cartesian-method-eachYValue'> /**
  80. </span> * @protected Iterates over a given record's values for each of this series's yFields,
  81. * executing a given function for each value. Any yFields that have been combined
  82. * via legend drag-drop will be treated as a single value.
  83. * @param {Ext.data.Model} record
  84. * @param {Function} fn
  85. * @param {Object} scope
  86. */
  87. eachYValue: function(record, fn, scope) {
  88. var me = this,
  89. yValueAccessors = me.getYValueAccessors(),
  90. i, ln, accessor;
  91. for (i = 0, ln = yValueAccessors.length; i &lt; ln; i++) {
  92. accessor = yValueAccessors[i];
  93. fn.call(scope, accessor(record), i);
  94. }
  95. },
  96. <span id='Ext-chart-series-Cartesian-method-getYValueCount'> /**
  97. </span> * @protected Returns the number of yField values, taking into account fields combined
  98. * via legend drag-drop.
  99. * @return {Number}
  100. */
  101. getYValueCount: function() {
  102. return this.getYValueAccessors().length;
  103. },
  104. combine: function(index1, index2) {
  105. var me = this,
  106. accessors = me.getYValueAccessors(),
  107. accessor1 = accessors[index1],
  108. accessor2 = accessors[index2];
  109. // Combine the yValue accessors for the two indexes into a single accessor that returns their sum
  110. accessors[index2] = function(record) {
  111. return accessor1(record) + accessor2(record);
  112. };
  113. accessors.splice(index1, 1);
  114. me.callParent([index1, index2]);
  115. },
  116. clearCombinations: function() {
  117. // Clear combined accessors, they'll get regenerated on next call to getYValueAccessors
  118. delete this.yValueAccessors;
  119. this.callParent();
  120. },
  121. <span id='Ext-chart-series-Cartesian-method-getYValueAccessors'> /**
  122. </span> * @protected Returns an array of functions, each of which returns the value of the yField
  123. * corresponding to function's index in the array, for a given record (each function takes the
  124. * record as its only argument.) If yFields have been combined by the user via legend drag-drop,
  125. * this list of accessors will be kept in sync with those combinations.
  126. * @return {Array} array of accessor functions
  127. */
  128. getYValueAccessors: function() {
  129. var me = this,
  130. accessors = me.yValueAccessors,
  131. yFields, yField, i, ln;
  132. if (!accessors) {
  133. accessors = me.yValueAccessors = [];
  134. yFields = [].concat(me.yField);
  135. for (i = 0, ln = yFields.length; i &lt; ln; i++) {
  136. yField = yFields[i];
  137. accessors.push(function(record) {
  138. return record.get(yField);
  139. });
  140. }
  141. }
  142. return accessors;
  143. },
  144. <span id='Ext-chart-series-Cartesian-method-getMinMaxXValues'> /**
  145. </span> * Calculate the min and max values for this series's xField.
  146. * @return {Array} [min, max]
  147. */
  148. getMinMaxXValues: function() {
  149. var me = this,
  150. chart = me.chart,
  151. store = chart.getChartStore(),
  152. data = store.data.items,
  153. i, ln, record,
  154. min, max,
  155. xField = me.xField,
  156. xValue;
  157. if (me.getRecordCount() &gt; 0) {
  158. min = Infinity;
  159. max = -min;
  160. for (i = 0, ln = data.length; i &lt; ln; i++) {
  161. record = data[i];
  162. xValue = record.get(xField);
  163. if (xValue &gt; max) {
  164. max = xValue;
  165. }
  166. if (xValue &lt; min) {
  167. min = xValue;
  168. }
  169. }
  170. } else {
  171. min = max = 0;
  172. }
  173. return [min, max];
  174. },
  175. <span id='Ext-chart-series-Cartesian-method-getMinMaxYValues'> /**
  176. </span> * Calculate the min and max values for this series's yField(s). Takes into account yField
  177. * combinations, exclusions, and stacking.
  178. * @return {Array} [min, max]
  179. */
  180. getMinMaxYValues: function() {
  181. var me = this,
  182. chart = me.chart,
  183. store = chart.getChartStore(),
  184. data = store.data.items,
  185. i, ln, record,
  186. stacked = me.stacked,
  187. min, max,
  188. positiveTotal, negativeTotal;
  189. function eachYValueStacked(yValue, i) {
  190. if (!me.isExcluded(i)) {
  191. if (yValue &lt; 0) {
  192. negativeTotal += yValue;
  193. } else {
  194. positiveTotal += yValue;
  195. }
  196. }
  197. }
  198. function eachYValue(yValue, i) {
  199. if (!me.isExcluded(i)) {
  200. if (yValue &gt; max) {
  201. max = yValue;
  202. }
  203. if (yValue &lt; min) {
  204. min = yValue;
  205. }
  206. }
  207. }
  208. if (me.getRecordCount() &gt; 0) {
  209. min = Infinity;
  210. max = -min;
  211. for (i = 0, ln = data.length; i &lt; ln; i++) {
  212. record = data[i];
  213. if (stacked) {
  214. positiveTotal = 0;
  215. negativeTotal = 0;
  216. me.eachYValue(record, eachYValueStacked);
  217. if (positiveTotal &gt; max) {
  218. max = positiveTotal;
  219. }
  220. if (negativeTotal &lt; min) {
  221. min = negativeTotal;
  222. }
  223. } else {
  224. me.eachYValue(record, eachYValue);
  225. }
  226. }
  227. } else {
  228. min = max = 0;
  229. }
  230. return [min, max];
  231. },
  232. getAxesForXAndYFields: function() {
  233. var me = this,
  234. axes = me.chart.axes,
  235. axis = [].concat(me.axis),
  236. yFields = {}, yFieldList = [].concat(me.yField),
  237. xFields = {}, xFieldList = [].concat(me.xField),
  238. fields, xAxis, yAxis, i, ln, flipXY;
  239. flipXY = me.type === 'bar' &amp;&amp; me.column === false;
  240. if(flipXY) {
  241. fields = yFieldList;
  242. yFieldList = xFieldList;
  243. xFieldList = fields;
  244. }
  245. if (Ext.Array.indexOf(axis, 'top') &gt; -1) {
  246. xAxis = 'top';
  247. } else if (Ext.Array.indexOf(axis, 'bottom') &gt; -1) {
  248. xAxis = 'bottom';
  249. } else {
  250. if (axes.get('top') &amp;&amp; axes.get('bottom')) {
  251. for (i = 0, ln = xFieldList.length; i &lt; ln; i++) {
  252. xFields[xFieldList[i]] = true;
  253. }
  254. fields = [].concat(axes.get('bottom').fields);
  255. for (i = 0, ln = fields.length; i &lt; ln; i++) {
  256. if (xFields[fields[i]]) {
  257. xAxis = 'bottom';
  258. break
  259. }
  260. }
  261. fields = [].concat(axes.get('top').fields);
  262. for (i = 0, ln = fields.length; i &lt; ln; i++) {
  263. if (xFields[fields[i]]) {
  264. xAxis = 'top';
  265. break
  266. }
  267. }
  268. } else if (axes.get('top')) {
  269. xAxis = 'top';
  270. } else if (axes.get('bottom')) {
  271. xAxis = 'bottom';
  272. }
  273. }
  274. if (Ext.Array.indexOf(axis, 'left') &gt; -1) {
  275. yAxis = 'left';
  276. } else if (Ext.Array.indexOf(axis, 'right') &gt; -1) {
  277. yAxis = 'right';
  278. } else {
  279. if (axes.get('left') &amp;&amp; axes.get('right')) {
  280. for (i = 0, ln = yFieldList.length; i &lt; ln; i++) {
  281. yFields[yFieldList[i]] = true;
  282. }
  283. fields = [].concat(axes.get('right').fields);
  284. for (i = 0, ln = fields.length; i &lt; ln; i++) {
  285. if (yFields[fields[i]]) {
  286. break
  287. }
  288. }
  289. fields = [].concat(axes.get('left').fields);
  290. for (i = 0, ln = fields.length; i &lt; ln; i++) {
  291. if (yFields[fields[i]]) {
  292. yAxis = 'left';
  293. break
  294. }
  295. }
  296. } else if (axes.get('left')) {
  297. yAxis = 'left';
  298. } else if (axes.get('right')) {
  299. yAxis = 'right';
  300. }
  301. }
  302. return flipXY ? {
  303. xAxis: yAxis,
  304. yAxis: xAxis
  305. }: {
  306. xAxis: xAxis,
  307. yAxis: yAxis
  308. };
  309. }
  310. });
  311. </pre>
  312. </body>
  313. </html>