UNPKG

chartx3d

Version:

Data Visualization Chart Library

430 lines (349 loc) 14.8 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 ZAxis extends Component { constructor(_cartesionUI) { super(_cartesionUI._coordSystem); this.name='ZAxis'; let opt = this._opt = this._coordSystem.coord.zAxis; this._cartesionUI = _cartesionUI; this._coord = this._coordSystem.coord || {}; 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.tickLine = { enabled: 1, lineWidth: 1, //线宽像素 lineLength: 20, //线长(空间单位) strokeStyle: '#333', offset: 0, //空间单位 }; this.axisLine = { enabled: 1, //是否有轴线 lineWidth: 1, strokeStyle: '#333' }; this.label = { enabled: 1, fontColor: '#333', fontSize: 12, rotation: 0, format: null, offset: { x: 40, y: 0, z: 0 }, textAlign: "left", //水平方向对齐: left right center verticalAlign: 'middle', //垂直方向对齐 top bottom middle lineHeight: 1, // evade: true //是否开启逃避检测,目前的逃避只是隐藏 }; if (opt.isH && (!opt.label || opt.label.rotaion === undefined)) { //如果是横向直角坐标系图 this.label.rotation = 90; }; // this.depth = 500; 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 = "peak"; // rule(均分,起点在0) , peak(均分,起点在均分单位的中心), proportion(实际数据真实位置,数据一定是number) //如果用户有手动的 trimLayout ,那么就全部visible为true,然后调用用户自己的过滤程序 //trimLayout就事把arr种的每个元素的visible设置为true和false的过程 //function this.trimLayout = null; // if (!opt._coord.zAxisAttribute.section.length) { // this.depth = 50; // } 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.zAxisAttribute; this.init(opt, this.axisAttribute); 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.getDataSection(); let zCustomSection = data._opt.dataSection||[]; me._formatTextSection = []; me._textElements = []; _.each(me.dataSection, function (val, i) { val = zCustomSection[i]||val; 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(); this._setZAxisWidth(); } _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() { //初始化轴线 const _axisDir = new Vector3(0, 0, -1); 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 = new Vector3(width, 0, 0); let _tickLineDir = new Vector3(1, 0, 0); let _faceInfo = this._cartesionUI.getFaceInfo(); let _textAlign = this.label.textAlign; let _offsetX = this.label.offset.x + this.axisLine.lineWidth + this.tickLine.lineLength + this.tickLine.offset; if (_faceInfo.bottom.visible) { if (_faceInfo.left.visible) { origin = new Vector3(width, 0, 0); _tickLineDir = new Vector3(1, 0, 0); } else { origin = new Vector3(0, 0, 0); _tickLineDir = new Vector3(-1, 0, 0); } if (_faceInfo.front.visible) { if (_faceInfo.left.visible) { _textAlign = 'right'; } else { _textAlign = 'left'; _offsetX = -_offsetX; } } else { if (_faceInfo.left.visible) { _textAlign = 'left'; } else { _textAlign = 'right'; _offsetX = -_offsetX; } } } else { //top 可见 if (_faceInfo.left.visible) { origin = new Vector3(width, height, 0); _tickLineDir = new Vector3(1, 0, 0); } else { origin = new Vector3(0, height, 0) _tickLineDir = new Vector3(-1, 0, 0); } if (_faceInfo.front.visible) { if (_faceInfo.left.visible) { _textAlign = 'right'; } else { _textAlign = 'left'; _offsetX = -_offsetX; } } else { if (_faceInfo.left.visible) { _textAlign = 'left'; } else { _textAlign = 'right'; _offsetX = -_offsetX; } } } if (this._axisLine) { if (this._axisLine.getOrigin().equals(origin)) { return; } //this._axisLine.dispose(); this._axisLine.setOrigin(origin); this._axisLine.update(); // this._axisLine.drawStart(); // this._axisLine.draw(); //二次绘制 // this._tickLine.dispose(); this._tickLine.setDir(_tickLineDir); this._tickLine.initData(this._axisLine, this.axisAttribute, _coordSystem.getZAxisPosition); this._tickLine.update(); // this._tickLine.drawStart(); // this._tickLine.draw(); //this._tickText.dispose(); this._tickText.setDir(_tickLineDir); this._tickText.initData(this._axisLine, this.axisAttribute, _coordSystem.getZAxisPosition); this._tickText.setTextAlign(_textAlign); this._tickText.offset.setX(_offsetX); // this._tickText.drawStart(this._formatTextSection); // this._tickText.draw(); } 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('zAxisLine') 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.getZAxisPosition); this._tickLine.drawStart(); this.group.add(this._tickLine.group); //初始化tickText this._tickText = new TickTexts(_coordSystem, this.label); this._tickText.offset.x = _offsetX; this._tickText.setDir(_tickLineDir); this._tickText.initData(this._axisLine, this.axisAttribute, _coordSystem.getZAxisPosition); //this._tickText.initData(this._axisLine, _coordSystem.zAxisAttribute); this._tickText.drawStart(this._formatTextSection); //this.group.add(this._tickText.group); this._root.labelGroup.add(this._tickText.group) } } _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 ); // } // } } _setZAxisWidth() { //检测下文字的宽度 var me = this; const _coordSystem = me._coordSystem; if (!me.enabled) { me.width = 0; } else { var _maxTextWidth = 0; if (this.label.enabled) { //me._formatTextSection.forEach((val)=>{ let width = TextTexture.getTextWidth(me._formatTextSection, ['normal', 'normal', this.label.fontColor, this.label.fontSize].join(' ')) _maxTextWidth = Math.max(_maxTextWidth, width); //}) // _.each(me.dataSection, function (val, i) { // //从_formatTextSection中取出对应的格式化后的文本 // let txt = me._textElements[i]; // let scale = me._root.renderView.getObjectScale(txt); // let textWidth = scale.x; // let textHeight = scale.y; // let width = textWidth; //文本在外接矩形width // let height = textHeight;//文本在外接矩形height // if (!!me.label.rotation) { // //有设置旋转 // if (me.label.rotation == 90) { // width = textHeight; // height = textWidth; // } else { // let sinR = Math.sin(Math.abs(me.label.rotation) * Math.PI / 180); // let cosR = Math.cos(Math.abs(me.label.rotation) * Math.PI / 180); // height = parseInt(sinR * textWidth); // width = parseInt(cosR * textWidth); // }; // }; // _maxTextWidth = Math.max(_maxTextWidth, width); // console.log('width',width); // }); }; this._maxTextWidth = _maxTextWidth; let ratio = _coordSystem.getRatioPixelToWorldByOrigin(); this.width = (_maxTextWidth + this.tickLine.lineLength + this.tickLine.offset + this.label.offset + this.axisLine.lineWidth) * ratio; //this.width+=10; // if (this._title) { // this.height += this._title.getTextHeight() // }; } } //设置布局 setLayout(opt) { } draw() { this._axisLine.draw(); this._tickLine.draw(); this._tickText.draw(); // console.log('z axis 项目三 pos: ',this._root.currCoord.getZAxisPosition('项目三')); } 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 { ZAxis };