chart.js 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
  4. var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
  5. var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
  6. var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
  7. var _const = require("./const");
  8. function _createSuper(Derived) { return function () { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (_isNativeReflectConstruct()) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
  9. function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
  10. var Base = require('../base');
  11. var Plot = require('./plot');
  12. var Util = require('../util/common');
  13. var Coord = require('../coord/index');
  14. var Geom = require('../geom/base');
  15. var ScaleController = require('./controller/scale');
  16. var AxisController = require('./controller/axis');
  17. var Global = require('../global');
  18. var _require = require('../graphic/index'),
  19. Canvas = _require.Canvas;
  20. var Helper = require('../util/helper');
  21. function compare(a, b) {
  22. return a - b;
  23. }
  24. function _isScaleExist(scales, compareScale) {
  25. var flag = false;
  26. Util.each(scales, function (scale) {
  27. var scaleValues = [].concat(scale.values);
  28. var compareScaleValues = [].concat(compareScale.values);
  29. if (scale.type === compareScale.type && scale.field === compareScale.field && scaleValues.sort(compare).toString() === compareScaleValues.sort(compare).toString()) {
  30. flag = true;
  31. return;
  32. }
  33. });
  34. return flag;
  35. }
  36. var Chart = /*#__PURE__*/function (_Base) {
  37. (0, _inheritsLoose2["default"])(Chart, _Base);
  38. var _super = _createSuper(Chart);
  39. Chart.initPlugins = function initPlugins() {
  40. return {
  41. _plugins: [],
  42. _cacheId: 0,
  43. register: function register(plugins) {
  44. var p = this._plugins;
  45. [].concat(plugins).forEach(function (plugin) {
  46. if (p.indexOf(plugin) === -1) {
  47. p.push(plugin);
  48. }
  49. });
  50. this._cacheId++;
  51. },
  52. unregister: function unregister(plugins) {
  53. var p = this._plugins;
  54. [].concat(plugins).forEach(function (plugin) {
  55. var idx = p.indexOf(plugin);
  56. if (idx !== -1) {
  57. p.splice(idx, 1);
  58. }
  59. });
  60. this._cacheId++;
  61. },
  62. clear: function clear() {
  63. this._plugins = [];
  64. this._cacheId++;
  65. },
  66. count: function count() {
  67. return this._plugins.length;
  68. },
  69. getAll: function getAll() {
  70. return this._plugins;
  71. },
  72. notify: function notify(chart, hook, args) {
  73. var descriptors = this.descriptors(chart);
  74. var ilen = descriptors.length;
  75. var i;
  76. var descriptor;
  77. var plugin;
  78. var params;
  79. var method;
  80. for (i = 0; i < ilen; ++i) {
  81. descriptor = descriptors[i];
  82. plugin = descriptor.plugin;
  83. method = plugin[hook];
  84. if (typeof method === 'function') {
  85. params = [chart].concat(args || []);
  86. if (method.apply(plugin, params) === false) {
  87. return false;
  88. }
  89. }
  90. }
  91. return true;
  92. },
  93. descriptors: function descriptors(chart) {
  94. var cache = chart._plugins || (chart._plugins = {});
  95. if (cache.id === this._cacheId) {
  96. return cache.descriptors;
  97. }
  98. var plugins = [];
  99. var descriptors = [];
  100. this._plugins.concat(chart && chart.get('plugins') || []).forEach(function (plugin) {
  101. var idx = plugins.indexOf(plugin);
  102. if (idx !== -1) {
  103. return;
  104. }
  105. plugins.push(plugin);
  106. descriptors.push({
  107. plugin: plugin
  108. });
  109. });
  110. cache.descriptors = descriptors;
  111. cache.id = this._cacheId;
  112. return descriptors;
  113. }
  114. };
  115. };
  116. var _proto = Chart.prototype;
  117. _proto.getDefaultCfg = function getDefaultCfg() {
  118. return {
  119. /**
  120. * the id of canvas
  121. * @type {String}
  122. */
  123. id: null,
  124. rendered: false,
  125. /**
  126. * padding
  127. * @type {Array|Number}
  128. */
  129. padding: Global.padding,
  130. /**
  131. * data
  132. * @type {Array}
  133. */
  134. data: null,
  135. /**
  136. * scales of chart
  137. * @type {Object}
  138. */
  139. scales: {},
  140. /**
  141. * @private
  142. * geometry instances
  143. * @type {Array}
  144. */
  145. geoms: [],
  146. /**
  147. * scale configuration
  148. * @type {Object}
  149. */
  150. colDefs: null,
  151. pixelRatio: Global.pixelRatio,
  152. /**
  153. * filter options
  154. * @type {Object}
  155. */
  156. filters: null,
  157. appendPadding: Global.appendPadding
  158. };
  159. };
  160. _proto._syncYScales = function _syncYScales() {
  161. var syncY = this.get('syncY');
  162. if (!syncY) {
  163. return;
  164. }
  165. var geoms = this.get('geoms');
  166. var syncScales = [];
  167. var min = [];
  168. var max = [];
  169. Util.each(geoms, function (geom) {
  170. var yScale = geom.getYScale();
  171. if (yScale.isLinear) {
  172. syncScales.push(yScale);
  173. min.push(yScale.min);
  174. max.push(yScale.max);
  175. }
  176. });
  177. min = Math.min.apply(null, min);
  178. max = Math.max.apply(null, max);
  179. Util.each(syncScales, function (scale) {
  180. scale.change({
  181. min: min
  182. });
  183. scale.change({
  184. max: max
  185. });
  186. });
  187. };
  188. _proto._getFieldsForLegend = function _getFieldsForLegend() {
  189. var fields = [];
  190. var geoms = this.get('geoms');
  191. Util.each(geoms, function (geom) {
  192. var attrOptions = geom.get('attrOptions');
  193. var attrCfg = attrOptions.color;
  194. if (attrCfg && attrCfg.field && Util.isString(attrCfg.field)) {
  195. var arr = attrCfg.field.split('*');
  196. Util.each(arr, function (item) {
  197. if (fields.indexOf(item) === -1) {
  198. fields.push(item);
  199. }
  200. });
  201. }
  202. });
  203. return fields;
  204. };
  205. _proto._getScaleData = function _getScaleData(field) {
  206. var data = this.get('data');
  207. var filteredData = this.get('filteredData');
  208. if (filteredData.length) {
  209. var legendFields = this._getFieldsForLegend();
  210. if (legendFields.indexOf(field) === -1) {
  211. data = filteredData;
  212. }
  213. }
  214. return data;
  215. } // _updateScales() {
  216. // const scaleController = this.get('scaleController');
  217. // scaleController.updateScales();
  218. // this._adjustScale();
  219. // }
  220. ;
  221. _proto._adjustScale = function _adjustScale() {
  222. var self = this;
  223. var scaleController = self.get('scaleController'); // 看起来是为了让柱状图最小或最大都默认从0开始
  224. var geoms = this.get('geoms');
  225. for (var i = 0; i < geoms.length; i++) {
  226. var geom = geoms[i];
  227. if (geom.get('type') === 'interval') {
  228. var yScale = geom.getYScale();
  229. scaleController.adjustStartZero(yScale);
  230. }
  231. }
  232. };
  233. _proto._removeGeoms = function _removeGeoms() {
  234. var geoms = this.get('geoms');
  235. while (geoms.length > 0) {
  236. var geom = geoms.shift();
  237. geom.destroy();
  238. }
  239. };
  240. _proto._clearGeoms = function _clearGeoms() {
  241. var geoms = this.get('geoms');
  242. for (var i = 0, length = geoms.length; i < length; i++) {
  243. var geom = geoms[i];
  244. geom.clear();
  245. }
  246. };
  247. _proto._clearInner = function _clearInner() {
  248. this._clearGeoms();
  249. Chart.plugins.notify(this, 'clearInner');
  250. this.get('axisController') && this.get('axisController').clear();
  251. };
  252. _proto._initFilteredData = function _initFilteredData() {
  253. var filters = this.get('filters');
  254. var data = this.get('data') || [];
  255. if (filters) {
  256. data = data.filter(function (obj) {
  257. var rst = true;
  258. Util.each(filters, function (fn, k) {
  259. if (fn) {
  260. rst = fn(obj[k], obj);
  261. if (!rst) {
  262. return false;
  263. }
  264. }
  265. });
  266. return rst;
  267. });
  268. }
  269. this.set('filteredData', data);
  270. };
  271. _proto._changeGeomsData = function _changeGeomsData() {
  272. var geoms = this.get('geoms');
  273. var data = this.get('filteredData');
  274. for (var i = 0, length = geoms.length; i < length; i++) {
  275. var geom = geoms[i];
  276. geom.changeData(data);
  277. }
  278. };
  279. _proto._initGeom = function _initGeom(geom) {
  280. var coord = this.get('coord');
  281. var data = this.get('filteredData');
  282. var colDefs = this.get('colDefs');
  283. var middlePlot = this.get('middlePlot');
  284. geom.set('chart', this);
  285. geom.set('container', middlePlot.addGroup());
  286. geom.set('data', data);
  287. geom.set('coord', coord);
  288. geom.set('colDefs', colDefs);
  289. geom.init();
  290. this.emit(_const.EVENT_AFTER_GEOM_INIT, geom);
  291. };
  292. _proto._initGeoms = function _initGeoms() {
  293. var geoms = this.get('geoms');
  294. for (var i = 0, length = geoms.length; i < length; i++) {
  295. this._initGeom(geoms[i]);
  296. }
  297. };
  298. _proto._initCoord = function _initCoord() {
  299. var plot = this.get('plotRange');
  300. var coordCfg = Util.mix({
  301. type: 'cartesian'
  302. }, this.get('coordCfg'), {
  303. plot: plot
  304. });
  305. var type = coordCfg.type;
  306. var C = Coord[Util.upperFirst(type)];
  307. var coord = new C(coordCfg);
  308. this.set('coord', coord);
  309. };
  310. _proto._initLayout = function _initLayout() {
  311. var padding = this.get('_padding');
  312. if (!padding) {
  313. padding = this.get('margin') || this.get('padding');
  314. padding = Util.parsePadding(padding);
  315. }
  316. var top = padding[0] === 'auto' ? 0 : padding[0];
  317. var right = padding[1] === 'auto' ? 0 : padding[1];
  318. var bottom = padding[2] === 'auto' ? 0 : padding[2];
  319. var left = padding[3] === 'auto' ? 0 : padding[3];
  320. var width = this.get('width');
  321. var height = this.get('height');
  322. var start = {
  323. x: left,
  324. y: top
  325. };
  326. var end = {
  327. x: width - right,
  328. y: height - bottom
  329. };
  330. var plot = this.get('plot');
  331. if (plot) {
  332. plot.reset(start, end);
  333. return;
  334. }
  335. var newPlot = new Plot({
  336. start: start,
  337. end: end
  338. });
  339. this.set('plotRange', newPlot);
  340. this.set('plot', newPlot);
  341. };
  342. _proto._initCanvas = function _initCanvas() {
  343. var self = this;
  344. try {
  345. var canvas = new Canvas({
  346. el: self.get('el') || self.get('id'),
  347. context: self.get('context'),
  348. pixelRatio: self.get('pixelRatio'),
  349. width: self.get('width'),
  350. height: self.get('height'),
  351. fontFamily: Global.fontFamily
  352. });
  353. self.set('canvas', canvas);
  354. self.set('el', canvas.get('el'));
  355. self.set('width', canvas.get('width'));
  356. self.set('height', canvas.get('height'));
  357. } catch (error) {
  358. throw error;
  359. }
  360. Chart.plugins.notify(self, 'afterCanvasInit');
  361. };
  362. _proto._initLayers = function _initLayers() {
  363. var canvas = this.get('canvas');
  364. this.set('backPlot', canvas.addGroup());
  365. this.set('middlePlot', canvas.addGroup({
  366. zIndex: 10
  367. }));
  368. this.set('frontPlot', canvas.addGroup({
  369. zIndex: 20
  370. }));
  371. };
  372. _proto._initEvents = function _initEvents() {
  373. var _this2 = this;
  374. // 数据更新后的一些更新
  375. this.on(_const.EVENT_AFTER_DATA_CHANGE, function () {
  376. // 数据更新后,重新设置filterdata
  377. _this2._initFilteredData(); // 更新geoms里的数据
  378. _this2._changeGeomsData();
  379. _this2._adjustScale();
  380. }); // 大小变化后的一些更新
  381. this.on(_const.EVENT_AFTER_SIZE_CHANGE, function () {
  382. _this2._initLayout(); // layout变化后,坐标轴也需要做相应的变化
  383. var coord = _this2.get('coord');
  384. if (coord) {
  385. coord.reset(_this2.get('plot'));
  386. }
  387. });
  388. };
  389. _proto._initScaleController = function _initScaleController() {
  390. var scaleController = new ScaleController({
  391. chart: this
  392. }); // 让colDefs 和 scaleController.defs 用同一个对象,这样就不用考虑同步的问题
  393. this.set('colDefs', scaleController.defs); // 已经实例化的scales 也保持统一个对象
  394. this.set('scales', scaleController.scales);
  395. this.set('scaleController', scaleController);
  396. };
  397. _proto._clearScaleController = function _clearScaleController() {
  398. var scaleController = this.get('scaleController');
  399. scaleController.clear();
  400. };
  401. _proto._init = function _init() {
  402. var self = this;
  403. self._initCanvas();
  404. self._initLayout();
  405. self._initLayers();
  406. self._initEvents();
  407. self._initScaleController();
  408. self.set('axisController', new AxisController({
  409. frontPlot: self.get('frontPlot').addGroup({
  410. className: 'axisContainer'
  411. }),
  412. backPlot: self.get('backPlot').addGroup({
  413. className: 'axisContainer'
  414. }),
  415. chart: self
  416. }));
  417. Chart.plugins.notify(self, 'init');
  418. };
  419. function Chart(cfg) {
  420. var _this;
  421. _this = _Base.call(this, cfg) || this;
  422. var self = (0, _assertThisInitialized2["default"])(_this);
  423. Util.each(Geom, function (geomConstructor, className) {
  424. var methodName = Util.lowerFirst(className);
  425. self[methodName] = function (cfg) {
  426. var geom = new geomConstructor(cfg);
  427. self.addGeom(geom);
  428. return geom;
  429. };
  430. });
  431. self._init();
  432. return _this;
  433. }
  434. _proto.init = function init() {
  435. // 初始filterData
  436. this._initFilteredData(); // initialization coordinate instance
  437. this._initCoord();
  438. Chart.plugins.notify(this, 'beforeGeomInit'); // init all geometry instances
  439. this._initGeoms(); // 多 Y 轴的情况时,统一 Y 轴的数值范围。
  440. this._syncYScales(); // do some adjust for data
  441. this._adjustScale();
  442. this.emit(_const.EVENT_AFTER_INIT);
  443. }
  444. /**
  445. * set data and some scale configuration
  446. * @chainable
  447. * @param {Array} data the dataset to visualize
  448. * @param {Object} colDefs the configuration for scales
  449. * @return {Chart} return the chart instance
  450. */
  451. ;
  452. _proto.source = function source(data, colDefs) {
  453. this.set('data', data);
  454. if (colDefs) {
  455. this.scale(colDefs);
  456. }
  457. return this;
  458. };
  459. _proto.scale = function scale(field, cfg) {
  460. var scaleController = this.get('scaleController');
  461. scaleController.setFieldDef(field, cfg);
  462. return this;
  463. }
  464. /**
  465. * configure the axis
  466. * @chainable
  467. * @param {String|Boolean} field the field name of data
  468. * @param {Object} cfg configuration for axis
  469. * @return {Chart} return the chart instance
  470. */
  471. ;
  472. _proto.axis = function axis(field, cfg) {
  473. var axisController = this.get('axisController');
  474. if (!field) {
  475. axisController.axisCfg = null;
  476. } else {
  477. axisController.axisCfg = axisController.axisCfg || {};
  478. axisController.axisCfg[field] = cfg;
  479. }
  480. return this;
  481. }
  482. /**
  483. * configure the coordinate
  484. * @chainable
  485. * @param {String} type set the type of coodinate
  486. * @param {Object} cfg configuration for coordinate
  487. * @return {Chart} return the chart instance
  488. */
  489. ;
  490. _proto.coord = function coord(type, cfg) {
  491. var coordCfg;
  492. if (Util.isObject(type)) {
  493. coordCfg = type;
  494. } else {
  495. coordCfg = cfg || {};
  496. coordCfg.type = type || 'cartesian';
  497. }
  498. this.set('coordCfg', coordCfg);
  499. return this;
  500. };
  501. _proto.filter = function filter(field, condition) {
  502. var filters = this.get('filters') || {};
  503. filters[field] = condition;
  504. this.set('filters', filters); // 如果已经render过,则再重新触发一次change
  505. if (this.get('rendered')) {
  506. this.emit(_const.EVENT_AFTER_DATA_CHANGE, this.get('data'));
  507. }
  508. }
  509. /**
  510. * render the chart
  511. * @chainable
  512. * @return {Chart} return the chart instance
  513. */
  514. ;
  515. _proto.render = function render() {
  516. var rendered = this.get('rendered');
  517. var canvas = this.get('canvas');
  518. var geoms = this.get('geoms');
  519. if (!rendered) {
  520. this.init();
  521. this.set('rendered', true);
  522. }
  523. this.emit(_const.EVENT_BEFORE_RENDER);
  524. Chart.plugins.notify(this, 'beforeGeomDraw');
  525. this._renderAxis();
  526. var middlePlot = this.get('middlePlot');
  527. if (this.get('limitInPlot') && !middlePlot.attr('clip')) {
  528. var coord = this.get('coord');
  529. var clip = Helper.getClip(coord);
  530. clip.set('canvas', middlePlot.get('canvas'));
  531. middlePlot.attr('clip', clip);
  532. }
  533. for (var i = 0, length = geoms.length; i < length; i++) {
  534. var geom = geoms[i];
  535. geom.paint();
  536. }
  537. Chart.plugins.notify(this, 'afterGeomDraw');
  538. canvas.sort();
  539. this.get('frontPlot').sort();
  540. Chart.plugins.notify(this, 'beforeCanvasDraw');
  541. canvas.draw();
  542. this.emit(_const.EVENT_AFTER_RENDER);
  543. return this;
  544. }
  545. /**
  546. * clear the chart, include geometris and all the shapes
  547. * @chainable
  548. * @return {Chart} return the chart
  549. */
  550. ;
  551. _proto.clear = function clear() {
  552. Chart.plugins.notify(this, 'clear');
  553. this._clearInner();
  554. this._removeGeoms();
  555. this._clearScaleController();
  556. this.set('legendItems', null);
  557. this.set('filters', null);
  558. this.set('isUpdate', false);
  559. this.set('_padding', null);
  560. this.set('rendered', false);
  561. var canvas = this.get('canvas');
  562. canvas.draw();
  563. return this;
  564. };
  565. _proto.repaint = function repaint() {
  566. // 如果在没有render之前就repaint的,就直接return退出
  567. var rendered = this.get('rendered');
  568. if (!rendered) {
  569. return;
  570. }
  571. this.set('isUpdate', true);
  572. this.set('legendItems', null);
  573. Chart.plugins.notify(this, 'repaint');
  574. this._clearInner();
  575. this.render();
  576. };
  577. _proto.changeData = function changeData(data) {
  578. this.emit(_const.EVENT_BEFORE_DATA_CHANGE, data);
  579. this.set('data', data);
  580. Chart.plugins.notify(this, 'changeData');
  581. this.emit(_const.EVENT_AFTER_DATA_CHANGE, data);
  582. this.set('_padding', null);
  583. this.repaint();
  584. };
  585. _proto.changeSize = function changeSize(width, height) {
  586. if (width) {
  587. this.set('width', width);
  588. } else {
  589. width = this.get('width');
  590. }
  591. if (height) {
  592. this.set('height', height);
  593. } else {
  594. height = this.get('height');
  595. }
  596. var canvas = this.get('canvas');
  597. canvas.changeSize(width, height);
  598. this.emit(_const.EVENT_AFTER_SIZE_CHANGE, {
  599. width: width,
  600. height: height
  601. });
  602. this.repaint();
  603. return this;
  604. };
  605. _proto.destroy = function destroy() {
  606. this.clear();
  607. var canvas = this.get('canvas');
  608. canvas.destroy();
  609. Chart.plugins.notify(this, 'afterCanvasDestroyed');
  610. if (this._interactions) {
  611. Util.each(this._interactions, function (interaction) {
  612. interaction.destroy();
  613. });
  614. }
  615. _Base.prototype.destroy.call(this);
  616. }
  617. /**
  618. * calculate dataset's position on canvas
  619. * @param {Object} record the dataset
  620. * @return {Object} return the position
  621. */
  622. ;
  623. _proto.getPosition = function getPosition(record) {
  624. var self = this;
  625. var coord = self.get('coord');
  626. var xScale = self.getXScale();
  627. var yScale = self.getYScales()[0];
  628. var xField = xScale.field;
  629. var x = xScale.scale(record[xField]);
  630. var yField = yScale.field;
  631. var y = yScale.scale(record[yField]);
  632. return coord.convertPoint({
  633. x: x,
  634. y: y
  635. });
  636. }
  637. /**
  638. * get the data item of the point
  639. * @param {Object} point canvas position
  640. * @return {Object} return the data item
  641. */
  642. ;
  643. _proto.getRecord = function getRecord(point) {
  644. var self = this;
  645. var coord = self.get('coord');
  646. var xScale = self.getXScale();
  647. var yScale = self.getYScales()[0];
  648. var invertPoint = coord.invertPoint(point);
  649. var record = {};
  650. record[xScale.field] = xScale.invert(invertPoint.x);
  651. record[yScale.field] = yScale.invert(invertPoint.y);
  652. return record;
  653. }
  654. /**
  655. * get the dataset of the point
  656. * @param {Object} point canvas position
  657. * @return {Array} return the dataset
  658. **/
  659. ;
  660. _proto.getSnapRecords = function getSnapRecords(point) {
  661. var geom = this.get('geoms')[0];
  662. var data = [];
  663. if (geom) {
  664. // need to judge
  665. data = geom.getSnapRecords(point);
  666. }
  667. return data;
  668. }
  669. /**
  670. * creat scale instances
  671. * @param {String} field field name of data
  672. * @return {Scale} return the scale
  673. */
  674. ;
  675. _proto.createScale = function createScale(field) {
  676. var data = this._getScaleData(field);
  677. var scaleController = this.get('scaleController');
  678. return scaleController.createScale(field, data);
  679. }
  680. /**
  681. * @protected
  682. * add geometry instance to geoms
  683. * @param {Geom} geom geometry instance
  684. */
  685. ;
  686. _proto.addGeom = function addGeom(geom) {
  687. var rendered = this.get('rendered');
  688. var geoms = this.get('geoms');
  689. geoms.push(geom); // 如果图表已经渲染过了,则直接初始化geom
  690. if (rendered) {
  691. this._initGeom(geom);
  692. }
  693. }
  694. /**
  695. * get the scale of x axis
  696. * @return {Scale} return the scale
  697. */
  698. ;
  699. _proto.getXScale = function getXScale() {
  700. var self = this;
  701. var geoms = self.get('geoms');
  702. var xScale = geoms[0].getXScale();
  703. return xScale;
  704. }
  705. /**
  706. * get the scale of y axis
  707. * @return {Array} return the scale
  708. */
  709. ;
  710. _proto.getYScales = function getYScales() {
  711. var geoms = this.get('geoms');
  712. var rst = [];
  713. Util.each(geoms, function (geom) {
  714. var yScale = geom.getYScale();
  715. if (rst.indexOf(yScale) === -1) {
  716. rst.push(yScale);
  717. }
  718. });
  719. return rst;
  720. };
  721. _proto.getLegendItems = function getLegendItems() {
  722. if (this.get('legendItems')) {
  723. return this.get('legendItems');
  724. }
  725. var legendItems = {};
  726. var scales = [];
  727. var geoms = this.get('geoms');
  728. Util.each(geoms, function (geom) {
  729. var colorAttr = geom.getAttr('color');
  730. if (colorAttr) {
  731. var scale = colorAttr.getScale('color'); // 只支持分类图例
  732. if (scale.isCategory && !_isScaleExist(scales, scale)) {
  733. scales.push(scale);
  734. var field = scale.field;
  735. var ticks = scale.getTicks();
  736. var items = [];
  737. Util.each(ticks, function (tick) {
  738. var text = tick.text;
  739. var name = text;
  740. var scaleValue = tick.value;
  741. var value = scale.invert(scaleValue);
  742. var color = colorAttr.mapping(value).join('') || Global.defaultColor;
  743. var marker = {
  744. fill: color,
  745. radius: 3,
  746. symbol: 'circle',
  747. stroke: '#fff'
  748. };
  749. items.push({
  750. name: name,
  751. // for display
  752. dataValue: value,
  753. // the origin value
  754. checked: true,
  755. marker: marker
  756. });
  757. });
  758. legendItems[field] = items;
  759. }
  760. }
  761. });
  762. this.set('legendItems', legendItems);
  763. return legendItems;
  764. } // register the plugins
  765. ;
  766. _proto.registerPlugins = function registerPlugins(plugins) {
  767. var self = this;
  768. var chartPlugins = self.get('plugins') || [];
  769. if (!Util.isArray(chartPlugins)) {
  770. chartPlugins = [chartPlugins];
  771. }
  772. [].concat(plugins).forEach(function (plugin) {
  773. if (chartPlugins.indexOf(plugin) === -1) {
  774. plugin.init && plugin.init(self); // init
  775. chartPlugins.push(plugin);
  776. }
  777. });
  778. Chart.plugins._cacheId++;
  779. self.set('plugins', chartPlugins);
  780. };
  781. _proto._renderAxis = function _renderAxis() {
  782. var axisController = this.get('axisController');
  783. var xScale = this.getXScale();
  784. var yScales = this.getYScales();
  785. var coord = this.get('coord');
  786. Chart.plugins.notify(this, 'beforeRenderAxis');
  787. axisController.createAxis(coord, xScale, yScales);
  788. };
  789. _proto._isAutoPadding = function _isAutoPadding() {
  790. if (this.get('_padding')) {
  791. return false;
  792. }
  793. var padding = this.get('padding');
  794. if (Util.isArray(padding)) {
  795. return padding.indexOf('auto') !== -1;
  796. }
  797. return padding === 'auto';
  798. };
  799. _proto._updateLayout = function _updateLayout(padding) {
  800. var width = this.get('width');
  801. var height = this.get('height');
  802. var start = {
  803. x: padding[3],
  804. y: padding[0]
  805. };
  806. var end = {
  807. x: width - padding[1],
  808. y: height - padding[2]
  809. };
  810. var plot = this.get('plot');
  811. var coord = this.get('coord');
  812. plot.reset(start, end);
  813. coord.reset(plot);
  814. };
  815. return Chart;
  816. }(Base);
  817. Chart.plugins = Chart.initPlugins();
  818. module.exports = Chart;