import * as echarts from 'echarts/lib/echarts'; import { createTextStyle } from 'echarts/lib/label/labelStyle'; import graphicGL from '../../util/graphicGL'; import Lines3DGeometry from '../../util/geometry/Lines3D'; import retrieve from '../../util/retrieve'; import LabelsMesh from '../../util/mesh/LabelsMesh'; var firstNotNull = retrieve.firstNotNull; var dimIndicesMap = { // Left to right x: 0, // Far to near y: 2, // Bottom to up z: 1 }; function Grid3DAxis(dim, linesMaterial) { var linesMesh = new graphicGL.Mesh({ geometry: new Lines3DGeometry({ useNativeLine: false }), material: linesMaterial, castShadow: false, ignorePicking: true, renderOrder: 2 }); var axisLabelsMesh = new LabelsMesh(); axisLabelsMesh.material.depthMask = false; var rootNode = new graphicGL.Node(); rootNode.add(linesMesh); rootNode.add(axisLabelsMesh); this.rootNode = rootNode; this.dim = dim; this.linesMesh = linesMesh; this.labelsMesh = axisLabelsMesh; this.axisLineCoords = null; this.labelElements = []; } var otherDim = { x: 'y', y: 'x', z: 'y' }; Grid3DAxis.prototype.update = function (grid3DModel, axisLabelSurface, api) { var cartesian = grid3DModel.coordinateSystem; var axis = cartesian.getAxis(this.dim); var linesGeo = this.linesMesh.geometry; var labelsGeo = this.labelsMesh.geometry; linesGeo.convertToDynamicArray(true); labelsGeo.convertToDynamicArray(true); var axisModel = axis.model; var extent = axis.getExtent(); var dpr = api.getDevicePixelRatio(); var axisLineModel = axisModel.getModel('axisLine', grid3DModel.getModel('axisLine')); var axisTickModel = axisModel.getModel('axisTick', grid3DModel.getModel('axisTick')); var axisLabelModel = axisModel.getModel('axisLabel', grid3DModel.getModel('axisLabel')); var axisLineColor = axisLineModel.get('lineStyle.color'); // Render axisLine if (axisLineModel.get('show')) { var axisLineStyleModel = axisLineModel.getModel('lineStyle'); var p0 = [0, 0, 0]; var p1 = [0, 0, 0]; var idx = dimIndicesMap[axis.dim]; p0[idx] = extent[0]; p1[idx] = extent[1]; // Save some useful info. this.axisLineCoords = [p0, p1]; var color = graphicGL.parseColor(axisLineColor); var lineWidth = firstNotNull(axisLineStyleModel.get('width'), 1.0); var opacity = firstNotNull(axisLineStyleModel.get('opacity'), 1.0); color[3] *= opacity; linesGeo.addLine(p0, p1, color, lineWidth * dpr); } // Render axis ticksCoords if (axisTickModel.get('show')) { var lineStyleModel = axisTickModel.getModel('lineStyle'); var lineColor = graphicGL.parseColor(firstNotNull(lineStyleModel.get('color'), axisLineColor)); var lineWidth = firstNotNull(lineStyleModel.get('width'), 1.0); lineColor[3] *= firstNotNull(lineStyleModel.get('opacity'), 1.0); var ticksCoords = axis.getTicksCoords(); var tickLength = axisTickModel.get('length'); for (var i = 0; i < ticksCoords.length; i++) { var tickCoord = ticksCoords[i].coord; var p0 = [0, 0, 0]; var p1 = [0, 0, 0]; var idx = dimIndicesMap[axis.dim]; var otherIdx = dimIndicesMap[otherDim[axis.dim]]; // 0 : x, 1 : y p0[idx] = p1[idx] = tickCoord; p1[otherIdx] = tickLength; linesGeo.addLine(p0, p1, lineColor, lineWidth * dpr); } } this.labelElements = []; var dpr = api.getDevicePixelRatio(); if (axisLabelModel.get('show')) { var ticksCoords = axis.getTicksCoords(); var categoryData = axisModel.get('data'); var labelMargin = axisLabelModel.get('margin'); var labels = axis.getViewLabels(); for (var i = 0; i < labels.length; i++) { var tickValue = labels[i].tickValue; var formattedLabel = labels[i].formattedLabel; var rawLabel = labels[i].rawLabel; var tickCoord = axis.dataToCoord(tickValue); var p = [0, 0, 0]; var idx = dimIndicesMap[axis.dim]; var otherIdx = dimIndicesMap[otherDim[axis.dim]]; // 0 : x, 1 : y p[idx] = p[idx] = tickCoord; p[otherIdx] = labelMargin; var itemTextStyleModel = axisLabelModel; if (categoryData && categoryData[tickValue] && categoryData[tickValue].textStyle) { itemTextStyleModel = new echarts.Model(categoryData[tickValue].textStyle, axisLabelModel, axisModel.ecModel); } var textColor = firstNotNull(itemTextStyleModel.get('color'), axisLineColor); var textEl = new echarts.graphic.Text({ style: createTextStyle(itemTextStyleModel, { text: formattedLabel, fill: typeof textColor === 'function' ? textColor( // (1) In category axis with data zoom, tick is not the original // index of axis.data. So tick should not be exposed to user // in category axis. // (2) Compatible with previous version, which always returns labelStr. // But in interval scale labelStr is like '223,445', which maked // user repalce ','. So we modify it to return original val but remain // it as 'string' to avoid error in replacing. axis.type === 'category' ? rawLabel : axis.type === 'value' ? tickValue + '' : tickValue, i) : textColor, verticalAlign: 'top', align: 'left' }) }); var coords = axisLabelSurface.add(textEl); var rect = textEl.getBoundingRect(); labelsGeo.addSprite(p, [rect.width * dpr, rect.height * dpr], coords); this.labelElements.push(textEl); } } if (axisModel.get('name')) { var nameTextStyleModel = axisModel.getModel('nameTextStyle'); var p = [0, 0, 0]; var idx = dimIndicesMap[axis.dim]; var otherIdx = dimIndicesMap[otherDim[axis.dim]]; var labelColor = firstNotNull(nameTextStyleModel.get('color'), axisLineColor); var strokeColor = nameTextStyleModel.get('borderColor'); var lineWidth = nameTextStyleModel.get('borderWidth'); // TODO start and end p[idx] = p[idx] = (extent[0] + extent[1]) / 2; p[otherIdx] = axisModel.get('nameGap'); var textEl = new echarts.graphic.Text({ style: createTextStyle(nameTextStyleModel, { text: axisModel.get('name'), fill: labelColor, stroke: strokeColor, lineWidth: lineWidth }) }); var coords = axisLabelSurface.add(textEl); var rect = textEl.getBoundingRect(); labelsGeo.addSprite(p, [rect.width * dpr, rect.height * dpr], coords); textEl.__idx = this.labelElements.length; this.nameLabelElement = textEl; } this.labelsMesh.material.set('textureAtlas', axisLabelSurface.getTexture()); this.labelsMesh.material.set('uvScale', axisLabelSurface.getCoordsScale()); linesGeo.convertToTypedArray(); labelsGeo.convertToTypedArray(); }; Grid3DAxis.prototype.setSpriteAlign = function (textAlign, textVerticalAlign, api) { var dpr = api.getDevicePixelRatio(); var labelGeo = this.labelsMesh.geometry; for (var i = 0; i < this.labelElements.length; i++) { var labelEl = this.labelElements[i]; var rect = labelEl.getBoundingRect(); labelGeo.setSpriteAlign(i, [rect.width * dpr, rect.height * dpr], textAlign, textVerticalAlign); } // name label var nameLabelEl = this.nameLabelElement; if (nameLabelEl) { var rect = nameLabelEl.getBoundingRect(); labelGeo.setSpriteAlign(nameLabelEl.__idx, [rect.width * dpr, rect.height * dpr], textAlign, textVerticalAlign); labelGeo.dirty(); } this.textAlign = textAlign; this.textVerticalAlign = textVerticalAlign; }; export default Grid3DAxis;