123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- /**
- * echarts组件类: 坐标轴
- *
- * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
- * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
- *
- * 直角坐标系中坐标轴数组,数组中每一项代表一条横轴(纵轴)坐标轴。
- * 标准(1.0)中规定最多同时存在2条横轴和2条纵轴
- * 单条横轴时可指定安放于grid的底部(默认)或顶部,2条同时存在时则默认第一条安放于底部,第二天安放于顶部
- * 单条纵轴时可指定安放于grid的左侧(默认)或右侧,2条同时存在时则默认第一条安放于左侧,第二天安放于右侧。
- * 坐标轴有两种类型,类目型和数值型(区别详见axis):
- * 横轴通常为类目型,但条形图时则横轴为数值型,散点图时则横纵均为数值型
- * 纵轴通常为数值型,但条形图时则纵轴为类目型。
- *
- */
- define(function (require) {
- var Base = require('./base');
- var LineShape = require('zrender/shape/Line');
- var ecConfig = require('../config');
- var ecData = require('../util/ecData');
- var zrUtil = require('zrender/tool/util');
- var zrColor = require('zrender/tool/color');
- /**
- * 构造函数
- * @param {Object} messageCenter echart消息中心
- * @param {ZRender} zr zrender实例
- * @param {Object} option 图表选项
- * @param {string=} option.xAxis.type 坐标轴类型,横轴默认为类目型'category'
- * @param {string=} option.yAxis.type 坐标轴类型,纵轴默认为类目型'value'
- * @param {Object} component 组件
- * @param {string} axisType 横走or纵轴
- */
- function Axis(ecTheme, messageCenter, zr, option, myChart, axisType) {
- Base.call(this, ecTheme, messageCenter, zr, option, myChart);
- this.axisType = axisType;
- this._axisList = [];
- this.refresh(option);
- }
- Axis.prototype = {
- type: ecConfig.COMPONENT_TYPE_AXIS,
- axisBase: {
- // 轴线
- _buildAxisLine: function () {
- var lineWidth = this.option.axisLine.lineStyle.width;
- var halfLineWidth = lineWidth / 2;
- var axShape = {
- _axisShape: 'axisLine',
- zlevel: this.getZlevelBase(),
- z: this.getZBase() + 3,
- hoverable: false
- };
- var grid = this.grid;
- switch (this.option.position) {
- case 'left' :
- axShape.style = {
- xStart: grid.getX() - halfLineWidth,
- yStart: grid.getYend(),
- xEnd: grid.getX() - halfLineWidth,
- yEnd: grid.getY(),
- lineCap: 'round'
- };
- break;
- case 'right' :
- axShape.style = {
- xStart: grid.getXend() + halfLineWidth,
- yStart: grid.getYend(),
- xEnd: grid.getXend() + halfLineWidth,
- yEnd: grid.getY(),
- lineCap: 'round'
- };
- break;
- case 'bottom' :
- axShape.style = {
- xStart: grid.getX(),
- yStart: grid.getYend() + halfLineWidth,
- xEnd: grid.getXend(),
- yEnd: grid.getYend() + halfLineWidth,
- lineCap: 'round'
- };
- break;
- case 'top' :
- axShape.style = {
- xStart: grid.getX(),
- yStart: grid.getY() - halfLineWidth,
- xEnd: grid.getXend(),
- yEnd: grid.getY() - halfLineWidth,
- lineCap: 'round'
- };
- break;
- }
- var style = axShape.style;
- if (this.option.name !== '') { // 别帮我代码规范
- style.text = this.option.name;
- style.textPosition = this.option.nameLocation;
- style.textFont = this.getFont(this.option.nameTextStyle);
- if (this.option.nameTextStyle.align) {
- style.textAlign = this.option.nameTextStyle.align;
- }
- if (this.option.nameTextStyle.baseline) {
- style.textBaseline = this.option.nameTextStyle.baseline;
- }
- if (this.option.nameTextStyle.color) {
- style.textColor = this.option.nameTextStyle.color;
- }
- }
- style.strokeColor = this.option.axisLine.lineStyle.color;
- style.lineWidth = lineWidth;
- // 亚像素优化
- if (this.isHorizontal()) {
- // 横向布局,优化y
- style.yStart
- = style.yEnd
- = this.subPixelOptimize(style.yEnd, lineWidth);
- }
- else {
- // 纵向布局,优化x
- style.xStart
- = style.xEnd
- = this.subPixelOptimize(style.xEnd, lineWidth);
- }
- style.lineType = this.option.axisLine.lineStyle.type;
- axShape = new LineShape(axShape);
- this.shapeList.push(axShape);
- },
- _axisLabelClickable: function(clickable, axShape) {
- if (clickable) {
- ecData.pack(
- axShape, undefined, -1, undefined, -1, axShape.style.text
- );
- axShape.hoverable = true;
- axShape.clickable = true;
- axShape.highlightStyle = {
- color: zrColor.lift(axShape.style.color, 1),
- brushType: 'fill'
- };
- return axShape;
- }
- else {
- return axShape;
- }
- },
- refixAxisShape: function(zeroX, zeroY) {
- if (!this.option.axisLine.onZero) {
- return;
- }
- var tickLength;
- if (this.isHorizontal() && zeroY != null) {
- // 横向布局调整纵向y
- for (var i = 0, l = this.shapeList.length; i < l; i++) {
- if (this.shapeList[i]._axisShape === 'axisLine') {
- this.shapeList[i].style.yStart
- = this.shapeList[i].style.yEnd
- = this.subPixelOptimize(
- zeroY, this.shapeList[i].stylelineWidth
- );
- this.zr.modShape(this.shapeList[i].id);
- }
- else if (this.shapeList[i]._axisShape === 'axisTick') {
- tickLength = this.shapeList[i].style.yEnd
- - this.shapeList[i].style.yStart;
- this.shapeList[i].style.yStart = zeroY - tickLength;
- this.shapeList[i].style.yEnd = zeroY;
- this.zr.modShape(this.shapeList[i].id);
- }
- }
- }
- if (!this.isHorizontal() && zeroX != null) {
- // 纵向布局调整横向x
- for (var i = 0, l = this.shapeList.length; i < l; i++) {
- if (this.shapeList[i]._axisShape === 'axisLine') {
- this.shapeList[i].style.xStart
- = this.shapeList[i].style.xEnd
- = this.subPixelOptimize(
- zeroX, this.shapeList[i].stylelineWidth
- );
- this.zr.modShape(this.shapeList[i].id);
- }
- else if (this.shapeList[i]._axisShape === 'axisTick') {
- tickLength = this.shapeList[i].style.xEnd
- - this.shapeList[i].style.xStart;
- this.shapeList[i].style.xStart = zeroX;
- this.shapeList[i].style.xEnd = zeroX + tickLength;
- this.zr.modShape(this.shapeList[i].id);
- }
- }
- }
- },
- getPosition: function () {
- return this.option.position;
- },
- isHorizontal: function() {
- return this.option.position === 'bottom' || this.option.position === 'top';
- }
- },
- /**
- * 参数修正&默认值赋值,重载基类方法
- * @param {Object} opt 参数
- */
- reformOption: function (opt) {
- // 不写或传了个空数值默认为数值轴
- if (!opt || (opt instanceof Array && opt.length === 0)) {
- opt = [ { type: ecConfig.COMPONENT_TYPE_AXIS_VALUE } ];
- }
- else if (!(opt instanceof Array)){
- opt = [opt];
- }
- // 最多两条,其他参数忽略
- if (opt.length > 2) {
- opt = [opt[0], opt[1]];
- }
- if (this.axisType === 'xAxis') {
- // 横轴位置默认配置
- if (!opt[0].position // 没配置或配置错
- || (opt[0].position != 'bottom' && opt[0].position != 'top')
- ) {
- opt[0].position = 'bottom';
- }
- if (opt.length > 1) {
- opt[1].position = opt[0].position === 'bottom' ? 'top' : 'bottom';
- }
- for (var i = 0, l = opt.length; i < l; i++) {
- // 坐标轴类型,横轴默认为类目型'category'
- opt[i].type = opt[i].type || 'category';
- // 标识轴类型&索引
- opt[i].xAxisIndex = i;
- opt[i].yAxisIndex = -1;
- }
- }
- else {
- // 纵轴位置默认配置
- if (!opt[0].position // 没配置或配置错
- || (opt[0].position != 'left' && opt[0].position != 'right')
- ) {
- opt[0].position = 'left';
- }
- if (opt.length > 1) {
- opt[1].position = opt[0].position === 'left' ? 'right' : 'left';
- }
- for (var i = 0, l = opt.length; i < l; i++) {
- // 坐标轴类型,纵轴默认为数值型'value'
- opt[i].type = opt[i].type || 'value';
- // 标识轴类型&索引
- opt[i].xAxisIndex = -1;
- opt[i].yAxisIndex = i;
- }
- }
- return opt;
- },
- /**
- * 刷新
- */
- refresh: function (newOption) {
- var axisOption;
- if (newOption) {
- this.option = newOption;
- if (this.axisType === 'xAxis') {
- this.option.xAxis = this.reformOption(newOption.xAxis);
- axisOption = this.option.xAxis;
- }
- else {
- this.option.yAxis = this.reformOption(newOption.yAxis);
- axisOption = this.option.yAxis;
- }
- this.series = newOption.series;
- }
- var CategoryAxis = require('./categoryAxis');
- var ValueAxis = require('./valueAxis');
- var len = Math.max((axisOption && axisOption.length || 0), this._axisList.length);
- for (var i = 0; i < len; i++) {
- if (this._axisList[i] // 已有实例
- && newOption // 非空刷新
- && (!axisOption[i] || this._axisList[i].type != axisOption[i].type) // 类型不匹配
- ) {
- this._axisList[i].dispose && this._axisList[i].dispose();
- this._axisList[i] = false;
- }
- if (this._axisList[i]) {
- this._axisList[i].refresh && this._axisList[i].refresh(
- axisOption ? axisOption[i] : false,
- this.series
- );
- }
- else if (axisOption && axisOption[i]) {
- this._axisList[i] = axisOption[i].type === 'category'
- ? new CategoryAxis(
- this.ecTheme, this.messageCenter, this.zr,
- axisOption[i], this.myChart, this.axisBase
- )
- : new ValueAxis(
- this.ecTheme, this.messageCenter, this.zr,
- axisOption[i], this.myChart, this.axisBase,
- this.series
- );
- }
- }
- },
- /**
- * 根据值换算位置
- * @param {number} idx 坐标轴索引0~1
- */
- getAxis: function (idx) {
- return this._axisList[idx];
- },
- getAxisCount: function () {
- return this._axisList.length;
- },
- clear: function () {
- for (var i = 0, l = this._axisList.length; i < l; i++) {
- this._axisList[i].dispose && this._axisList[i].dispose();
- }
- this._axisList = [];
- }
- };
- zrUtil.inherits(Axis, Base);
- require('../component').define('axis', Axis);
- return Axis;
- });
|