UNPKG

chartx3d

Version:

Data Visualization Chart Library

360 lines (284 loc) 12.1 kB
import { Component, _ } from '../Component'; import { AxisLine } from './axisLine'; import { Vector3, TextTexture } from 'mmgl/src/index'; import { TickLines } from './tickLines'; import { TickTexts } from './tickTexts'; import { numAddSymbol } from '../../../utils/tools'; class XAxis extends Component { constructor(_cartesionUI) { super(_cartesionUI._coordSystem); this.name='XAxis'; let opt = this._opt = this._coordSystem.coord.xAxis; this._cartesionUI = _cartesionUI; this.width = 0; this.height = 0; this.title = { content: "", shapeType: "text", fontColor: '#999', fontSize: 12, offset: 2, textAlign: "center", textBaseline: "middle", strokeStyle: null, lineHeight: 0 }; this._title = null; //this.title对应的文本对象 this.enabled = true; this.axisLine = { enabled: 1, //是否有轴线 lineWidth: 1, strokeStyle: '#333' }; this.tickLine = { enabled: 1, lineWidth: 1, //线宽像素 lineLength: 20, //线长(空间单位) strokeStyle: '#333', offset: 0, //空间单位 }; this.label = { enabled: 1, fontColor: '#333', fontSize: 12, rotation: 0, format: null, offset: { x: 20, y: 0, z: 40 }, textAlign: "center", //水平方向对齐: left right center verticalAlign: 'bottom', //垂直方向对齐 top bottom middle lineHeight: 1, evade: true //是否开启逃避检测,目前的逃避只是隐藏 }; if (opt.isH && (!opt.label || opt.label.rotaion === undefined)) { //如果是横向直角坐标系图 this.label.rotation = 90; }; this.maxTxtH = 0; this.pos = { x: 0, y: 0 }; // this.dataOrg = []; //源数据 this.dataSection = []; //默认就等于源数据,也可以用户自定义传入来指定 this.layoutData = []; //{x:100, value:'1000',visible:true} this.sprite = null; //过滤器,可以用来过滤哪些yaxis 的 节点是否显示已经颜色之类的 //@params params包括 dataSection , 索引index,txt(canvax element) ,line(canvax element) 等属性 this.filter = null; //function(params){}; this.isH = false; //是否为横向转向的x轴 this.animation = false; //layoutType == "proportion"的时候才有效 this.maxVal = null; this.minVal = null; this.ceilWidth = 0; //x方向一维均分长度, layoutType == peak 的时候要用到 this.layoutType = "rule"; // rule(均分,起点在0) , peak(均分,起点在均分单位的中心), proportion(实际数据真实位置,数据一定是number) //如果用户有手动的 trimLayout ,那么就全部visible为true,然后调用用户自己的过滤程序 //trimLayout就事把arr种的每个元素的visible设置为true和false的过程 //function this.trimLayout = null; this.posParseToInt = false; //比如在柱状图中,有得时候需要高精度的能间隔1px的柱子,那么x轴的计算也必须要都是整除的 _.extend(true, this, opt); // this.label.enabled = this.enabled && this.label.enabled; // this.tickLine.enabled = this.enabled && this.tickLine.enabled; // this.axisLine.enabled = this.enabled && this.axisLine.enabled; this.axisAttribute = this._coordSystem.xAxisAttribute; this.init(opt, this.axisAttribute); //xAxis的field只有一个值, //this.field = _.flatten([this._coord.xAxisAttribute.field])[0]; this.group.visible = !!this.enabled; } init(opt, data) { let me = this; // this.rulesGroup = this._root.app.addGroup({ name: 'rulesSprite' }); // this.group.add(this.rulesGroup); this._initData(data); this._onChangeBind = () => { me._initModules(); }; this._root.orbitControls.on('change', this._onChangeBind); me._initModules(); } _initData(data) { var me = this; if (data && data.field) { this.field = data.field; } this.dataSection = data.dataSection; me._formatTextSection = []; me._textElements = []; _.each(me.dataSection, function (val, i) { me._formatTextSection[i] = me._getFormatText(val, i); }); if (this.label.rotation != 0) { //如果是旋转的文本,那么以右边为旋转中心点 this.label.textAlign = "right"; }; //取第一个数据来判断xaxis的刻度值类型是否为 number !("minVal" in this._opt) && (this.minVal = _.min(this.dataSection)); if (isNaN(this.minVal) || this.minVal == Infinity) { this.minVal = 0; }; !("maxVal" in this._opt) && (this.maxVal = _.max(this.dataSection)); if (isNaN(this.maxVal) || this.maxVal == Infinity) { this.maxVal = 1; }; this._getName(); } _getFormatText(val, i) { var res; if (_.isFunction(this.label.format)) { res = this.label.format.apply(this, arguments); } else { res = val } if (_.isArray(res)) { res = numAddSymbol(res); } if (!res) { res = val; }; return res; } _initModules() { //todo 这个方法后续重构 //初始化轴线 const _axisDir = new Vector3(1, 0, 0); const _coordSystem = this._coordSystem; let coordBoundBox = _coordSystem.getBoundbox(); let _size = new Vector3(); //空间盒子的大小 coordBoundBox.getSize(_size); let { x: width, y: height, z: depth } = _size; let origin = _coordSystem.getOrigin(); let _tickLineDir = new Vector3(0, 0, 1); let _faceInfo = this._cartesionUI.getFaceInfo(); let _verticalAlign = this.label.verticalAlign; let _offsetZ = this.label.offset.z + this.axisLine.lineWidth + this.tickLine.lineLength + this.tickLine.offset; if (_faceInfo.bottom.visible) { if (_faceInfo.back.visible) { origin = _coordSystem.getOrigin(); _tickLineDir = new Vector3(0, 0, 1); } else { origin = new Vector3(0, 0, -depth); _tickLineDir = new Vector3(0, 0, -1); _offsetZ *= -1; } _verticalAlign = 'bottom'; } else { //top 可见 if (_faceInfo.back.visible) { origin = new Vector3(0, height, 0); _tickLineDir = new Vector3(0, 0, 1); } else { origin = new Vector3(0, height, -depth) _tickLineDir = new Vector3(0, 0, -1); _offsetZ *= -1; } _verticalAlign = 'top'; } if (this._axisLine) { if (this._axisLine.getOrigin().equals(origin)) { return; } this._axisLine.setOrigin(origin); this._axisLine.update(); //二次绘制 this._tickLine.setDir(_tickLineDir); this._tickLine.initData(this._axisLine, this.axisAttribute, _coordSystem.getXAxisPosition); this._tickLine.update(); this._tickText.setDir(_tickLineDir); this._tickText.offset.setZ(_offsetZ); this._tickText.initData(this._axisLine, this.axisAttribute, _coordSystem.getXAxisPosition); this._tickText.setVerticalAlign(_verticalAlign); } else { this._axisLine = new AxisLine(_coordSystem, this.axisLine); this._axisLine.setDir(_axisDir); this._axisLine.setOrigin(origin); this._axisLine.setLength(this.axisAttribute.axisLength); this._axisLine.setGroupName('xAxisLine') this._axisLine.drawStart(); this.group.add(this._axisLine.group); //初始化tickLine this._tickLine = new TickLines(_coordSystem, this.tickLine); this._tickLine.setDir(_tickLineDir); this._tickLine.initData(this._axisLine, this.axisAttribute, _coordSystem.getXAxisPosition); this._tickLine.drawStart(); this.group.add(this._tickLine.group); //初始化tickText this._tickText = new TickTexts(_coordSystem, this.label); this._tickText.offset.z += this.axisLine.lineWidth + this.tickLine.lineWidth + this.tickLine.offset; this._tickText.setVerticalAlign(_verticalAlign); this._tickText.setDir(_tickLineDir); this._tickText.initData(this._axisLine, this.axisAttribute, _coordSystem.getXAxisPosition); //this._tickText.initData(this._axisLine,this.axisAttribute); this._tickText.drawStart(this._formatTextSection); this._root.labelGroup.add(this._tickText.group) //this.group.add(this._tickText.group); this._tickText.labels.forEach((label, a) => { _.isFunction(this.filter) && this.filter({ layoutData: this.axisAttribute.dataSectionLayout, index: a, label: label, line: this._tickLine.lines[a] }); }) } } _getName() { // if ( this.title.content ) { // if( !this._title ){ // this._title = new Canvax.Display.Text(this.title.content, { // context: { // fontSize: this.title.fontSize, // textAlign: this.title.textAlign, //"center",//this.isH ? "center" : "left", // textBaseline: this.title.textBaseline,//"middle", //this.isH ? "top" : "middle", // fillStyle: this.title.fontColor, // strokeStyle: this.title.strokeStyle, // lineWidth : this.title.lineWidth, // rotation: this.isH ? -180 : 0 // } // }); // } else { // this._title.resetText( this.title.content ); // } // } } // evade() { // //label个数 // let num = this.axisAttribute.dataSectionLayout.length; // //轴长 // let labels = this._tickText.labels; // let orgPoint1 = this._tickText.getTextPos(labels[0].userData.text); // let orgPoint2 = this._tickText.getTextPos(labels[labels.length - 1].userData.text); // let point1 = this._coordSystem.positionToScreen(orgPoint1.clone()); // let point2 = this._coordSystem.positionToScreen(orgPoint2.clone()); // //屏幕空间下的轴长 // let lengthInScreen = point2.distanceTo(point1); // console.log(lengthInScreen); // debugger // } draw() { this._axisLine.draw(); this._tickLine.draw(); this._tickText.draw(); //console.log('x axis 2 pos: ',this._root.currCoord.getXAxisPosition(2)); } dispose() { this._axisLine.dispose(); this._tickLine.dispose(); this._tickText.dispose(); this._root.orbitControls.off('change', this._onChangeBind); this._onChangeBind = null; } resetData() { this._initData(this.axisAttribute); //this.getOrigin(); this._axisLine.resetData(); this._tickLine.resetData(this._axisLine, this.axisAttribute); this._tickText.resetData(this._axisLine, this.axisAttribute, this._formatTextSection); } } export { XAxis };