273 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			273 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
 | |
| /*
 | |
| * Licensed to the Apache Software Foundation (ASF) under one
 | |
| * or more contributor license agreements.  See the NOTICE file
 | |
| * distributed with this work for additional information
 | |
| * regarding copyright ownership.  The ASF licenses this file
 | |
| * to you under the Apache License, Version 2.0 (the
 | |
| * "License"); you may not use this file except in compliance
 | |
| * with the License.  You may obtain a copy of the License at
 | |
| *
 | |
| *   http://www.apache.org/licenses/LICENSE-2.0
 | |
| *
 | |
| * Unless required by applicable law or agreed to in writing,
 | |
| * software distributed under the License is distributed on an
 | |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 | |
| * KIND, either express or implied.  See the License for the
 | |
| * specific language governing permissions and limitations
 | |
| * under the License.
 | |
| */
 | |
| 
 | |
| var graphic = require("../../util/graphic");
 | |
| 
 | |
| var IncrementalDisplayable = require("zrender/lib/graphic/IncrementalDisplayable");
 | |
| 
 | |
| var lineContain = require("zrender/lib/contain/line");
 | |
| 
 | |
| var quadraticContain = require("zrender/lib/contain/quadratic");
 | |
| 
 | |
| /*
 | |
| * Licensed to the Apache Software Foundation (ASF) under one
 | |
| * or more contributor license agreements.  See the NOTICE file
 | |
| * distributed with this work for additional information
 | |
| * regarding copyright ownership.  The ASF licenses this file
 | |
| * to you under the Apache License, Version 2.0 (the
 | |
| * "License"); you may not use this file except in compliance
 | |
| * with the License.  You may obtain a copy of the License at
 | |
| *
 | |
| *   http://www.apache.org/licenses/LICENSE-2.0
 | |
| *
 | |
| * Unless required by applicable law or agreed to in writing,
 | |
| * software distributed under the License is distributed on an
 | |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 | |
| * KIND, either express or implied.  See the License for the
 | |
| * specific language governing permissions and limitations
 | |
| * under the License.
 | |
| */
 | |
| // TODO Batch by color
 | |
| var LargeLineShape = graphic.extendShape({
 | |
|   shape: {
 | |
|     polyline: false,
 | |
|     curveness: 0,
 | |
|     segs: []
 | |
|   },
 | |
|   buildPath: function (path, shape) {
 | |
|     var segs = shape.segs;
 | |
|     var curveness = shape.curveness;
 | |
| 
 | |
|     if (shape.polyline) {
 | |
|       for (var i = 0; i < segs.length;) {
 | |
|         var count = segs[i++];
 | |
| 
 | |
|         if (count > 0) {
 | |
|           path.moveTo(segs[i++], segs[i++]);
 | |
| 
 | |
|           for (var k = 1; k < count; k++) {
 | |
|             path.lineTo(segs[i++], segs[i++]);
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     } else {
 | |
|       for (var i = 0; i < segs.length;) {
 | |
|         var x0 = segs[i++];
 | |
|         var y0 = segs[i++];
 | |
|         var x1 = segs[i++];
 | |
|         var y1 = segs[i++];
 | |
|         path.moveTo(x0, y0);
 | |
| 
 | |
|         if (curveness > 0) {
 | |
|           var x2 = (x0 + x1) / 2 - (y0 - y1) * curveness;
 | |
|           var y2 = (y0 + y1) / 2 - (x1 - x0) * curveness;
 | |
|           path.quadraticCurveTo(x2, y2, x1, y1);
 | |
|         } else {
 | |
|           path.lineTo(x1, y1);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   },
 | |
|   findDataIndex: function (x, y) {
 | |
|     var shape = this.shape;
 | |
|     var segs = shape.segs;
 | |
|     var curveness = shape.curveness;
 | |
| 
 | |
|     if (shape.polyline) {
 | |
|       var dataIndex = 0;
 | |
| 
 | |
|       for (var i = 0; i < segs.length;) {
 | |
|         var count = segs[i++];
 | |
| 
 | |
|         if (count > 0) {
 | |
|           var x0 = segs[i++];
 | |
|           var y0 = segs[i++];
 | |
| 
 | |
|           for (var k = 1; k < count; k++) {
 | |
|             var x1 = segs[i++];
 | |
|             var y1 = segs[i++];
 | |
| 
 | |
|             if (lineContain.containStroke(x0, y0, x1, y1)) {
 | |
|               return dataIndex;
 | |
|             }
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         dataIndex++;
 | |
|       }
 | |
|     } else {
 | |
|       var dataIndex = 0;
 | |
| 
 | |
|       for (var i = 0; i < segs.length;) {
 | |
|         var x0 = segs[i++];
 | |
|         var y0 = segs[i++];
 | |
|         var x1 = segs[i++];
 | |
|         var y1 = segs[i++];
 | |
| 
 | |
|         if (curveness > 0) {
 | |
|           var x2 = (x0 + x1) / 2 - (y0 - y1) * curveness;
 | |
|           var y2 = (y0 + y1) / 2 - (x1 - x0) * curveness;
 | |
| 
 | |
|           if (quadraticContain.containStroke(x0, y0, x2, y2, x1, y1)) {
 | |
|             return dataIndex;
 | |
|           }
 | |
|         } else {
 | |
|           if (lineContain.containStroke(x0, y0, x1, y1)) {
 | |
|             return dataIndex;
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         dataIndex++;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     return -1;
 | |
|   }
 | |
| });
 | |
| 
 | |
| function LargeLineDraw() {
 | |
|   this.group = new graphic.Group();
 | |
| }
 | |
| 
 | |
| var largeLineProto = LargeLineDraw.prototype;
 | |
| 
 | |
| largeLineProto.isPersistent = function () {
 | |
|   return !this._incremental;
 | |
| };
 | |
| /**
 | |
|  * Update symbols draw by new data
 | |
|  * @param {module:echarts/data/List} data
 | |
|  */
 | |
| 
 | |
| 
 | |
| largeLineProto.updateData = function (data) {
 | |
|   this.group.removeAll();
 | |
|   var lineEl = new LargeLineShape({
 | |
|     rectHover: true,
 | |
|     cursor: 'default'
 | |
|   });
 | |
|   lineEl.setShape({
 | |
|     segs: data.getLayout('linesPoints')
 | |
|   });
 | |
| 
 | |
|   this._setCommon(lineEl, data); // Add back
 | |
| 
 | |
| 
 | |
|   this.group.add(lineEl);
 | |
|   this._incremental = null;
 | |
| };
 | |
| /**
 | |
|  * @override
 | |
|  */
 | |
| 
 | |
| 
 | |
| largeLineProto.incrementalPrepareUpdate = function (data) {
 | |
|   this.group.removeAll();
 | |
| 
 | |
|   this._clearIncremental();
 | |
| 
 | |
|   if (data.count() > 5e5) {
 | |
|     if (!this._incremental) {
 | |
|       this._incremental = new IncrementalDisplayable({
 | |
|         silent: true
 | |
|       });
 | |
|     }
 | |
| 
 | |
|     this.group.add(this._incremental);
 | |
|   } else {
 | |
|     this._incremental = null;
 | |
|   }
 | |
| };
 | |
| /**
 | |
|  * @override
 | |
|  */
 | |
| 
 | |
| 
 | |
| largeLineProto.incrementalUpdate = function (taskParams, data) {
 | |
|   var lineEl = new LargeLineShape();
 | |
|   lineEl.setShape({
 | |
|     segs: data.getLayout('linesPoints')
 | |
|   });
 | |
| 
 | |
|   this._setCommon(lineEl, data, !!this._incremental);
 | |
| 
 | |
|   if (!this._incremental) {
 | |
|     lineEl.rectHover = true;
 | |
|     lineEl.cursor = 'default';
 | |
|     lineEl.__startIndex = taskParams.start;
 | |
|     this.group.add(lineEl);
 | |
|   } else {
 | |
|     this._incremental.addDisplayable(lineEl, true);
 | |
|   }
 | |
| };
 | |
| /**
 | |
|  * @override
 | |
|  */
 | |
| 
 | |
| 
 | |
| largeLineProto.remove = function () {
 | |
|   this._clearIncremental();
 | |
| 
 | |
|   this._incremental = null;
 | |
|   this.group.removeAll();
 | |
| };
 | |
| 
 | |
| largeLineProto._setCommon = function (lineEl, data, isIncremental) {
 | |
|   var hostModel = data.hostModel;
 | |
|   lineEl.setShape({
 | |
|     polyline: hostModel.get('polyline'),
 | |
|     curveness: hostModel.get('lineStyle.curveness')
 | |
|   });
 | |
|   lineEl.useStyle(hostModel.getModel('lineStyle').getLineStyle());
 | |
|   lineEl.style.strokeNoScale = true;
 | |
|   var visualColor = data.getVisual('color');
 | |
| 
 | |
|   if (visualColor) {
 | |
|     lineEl.setStyle('stroke', visualColor);
 | |
|   }
 | |
| 
 | |
|   lineEl.setStyle('fill');
 | |
| 
 | |
|   if (!isIncremental) {
 | |
|     // Enable tooltip
 | |
|     // PENDING May have performance issue when path is extremely large
 | |
|     lineEl.seriesIndex = hostModel.seriesIndex;
 | |
|     lineEl.on('mousemove', function (e) {
 | |
|       lineEl.dataIndex = null;
 | |
|       var dataIndex = lineEl.findDataIndex(e.offsetX, e.offsetY);
 | |
| 
 | |
|       if (dataIndex > 0) {
 | |
|         // Provide dataIndex for tooltip
 | |
|         lineEl.dataIndex = dataIndex + lineEl.__startIndex;
 | |
|       }
 | |
|     });
 | |
|   }
 | |
| };
 | |
| 
 | |
| largeLineProto._clearIncremental = function () {
 | |
|   var incremental = this._incremental;
 | |
| 
 | |
|   if (incremental) {
 | |
|     incremental.clearDisplaybles();
 | |
|   }
 | |
| };
 | |
| 
 | |
| var _default = LargeLineDraw;
 | |
| module.exports = _default; | 
