husilu 5 years ago
parent
commit
85d82d915f

+ 0 - 0
mock/modules2/index.js


+ 1 - 3
src/App.vue

@@ -1,5 +1,6 @@
1 1
 <template>
2 2
   <el-row id='app'>
3
+    <chaoge-brush></chaoge-brush>
3 4
     <el-col :span="24" class='main-container'>
4 5
     <router-view></router-view>
5 6
     </el-col>
@@ -10,9 +11,6 @@
10 11
      <!-- <my-table></my-table> -->
11 12
     <!-- <chao-ge></chao-ge> -->
12 13
     <!-- <test-com></test-com> -->
13
-    <!-- <chaoge-brush></chaoge-brush> -->
14
-    <!-- <keep-alive> -->
15
-    <!-- </keep-alive> -->
16 14
    <!-- <ant></ant> -->
17 15
    <!-- <my-list></my-list> -->
18 16
    <!-- <my-can></my-can> -->

+ 4 - 0
src/components/chaogebrush.vue

@@ -14,11 +14,15 @@
14 14
   </div>
15 15
 </template>
16 16
 <script>
17
+// import BrushController2 from './utils/BrushController2'
17 18
 import { mapGetters } from 'vuex'
18 19
 import echarts from 'echarts'
19 20
 import Mock from 'mockjs'
20 21
 import moment from 'moment'
22
+// import BrushView from './utils/BrushView'
21 23
 // import chartConfig from '@/utils/chart/baseConf.js'
24
+// import BrushView from '../utils/BrushView'
25
+var BrushView = require('../utils/BrushView')
22 26
 let startTimes = (new Date()).getTime() - 60 * 60 * 1000
23 27
 
24 28
 let MockData = Mock.mock({

+ 1 - 0
src/main.js

@@ -11,6 +11,7 @@ import hljs from 'highlight.js'
11 11
 import 'highlight.js/styles/googlecode.css'
12 12
 import '../mock'
13 13
 import axios from 'axios'
14
+
14 15
 Vue.prototype.$http = axios
15 16
 Vue.prototype.$echarts = echarts
16 17
 Vue.config.productionTip = false

+ 878 - 0
src/utils/BrushController2.js

@@ -0,0 +1,878 @@
1
+import {__DEV__} from '../../node_modules/echarts/lib/config';
2
+import * as zrUtil from '../../node_modules/zrender/src/core/util';
3
+import Eventful from '../../node_modules/zrender/src/mixin/Eventful';
4
+import * as graphic from '../../node_modules/echarts/lib/util/graphic';
5
+import * as interactionMutex from '../../node_modules/echarts/lib/component/helper/interactionMutex';
6
+import DataDiffer from '../../node_modules/echarts/lib/data/DataDiffer';
7
+
8
+/*
9
+* Licensed to the Apache Software Foundation (ASF) under one
10
+* or more contributor license agreements.  See the NOTICE file
11
+* distributed with this work for additional information
12
+* regarding copyright ownership.  The ASF licenses this file
13
+* to you under the Apache License, Version 2.0 (the
14
+* "License"); you may not use this file except in compliance
15
+* with the License.  You may obtain a copy of the License at
16
+*
17
+*   http://www.apache.org/licenses/LICENSE-2.0
18
+*
19
+* Unless required by applicable law or agreed to in writing,
20
+* software distributed under the License is distributed on an
21
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
22
+* KIND, either express or implied.  See the License for the
23
+* specific language governing permissions and limitations
24
+* under the License.
25
+*/
26
+var curry = zrUtil.curry;
27
+var each = zrUtil.each;
28
+var map = zrUtil.map;
29
+var mathMin = Math.min;
30
+var mathMax = Math.max;
31
+var mathPow = Math.pow;
32
+var COVER_Z = 10000;
33
+var UNSELECT_THRESHOLD = 6;
34
+var MIN_RESIZE_LINE_WIDTH = 6;
35
+var MUTEX_RESOURCE_KEY = 'globalPan';
36
+var DIRECTION_MAP = {
37
+  w: [0, 0],
38
+  e: [0, 1],
39
+  n: [1, 0],
40
+  s: [1, 1]
41
+};
42
+var CURSOR_MAP = {
43
+  w: 'ew',
44
+  e: 'ew',
45
+  n: 'ns',
46
+  s: 'ns',
47
+  ne: 'nesw',
48
+  sw: 'nesw',
49
+  nw: 'nwse',
50
+  se: 'nwse'
51
+};
52
+var DEFAULT_BRUSH_OPT = {
53
+  brushStyle: {
54
+    lineWidth: 2,
55
+    stroke: 'rgba(0,0,0,0.3)',
56
+    fill: 'rgba(0,0,0,0.1)'
57
+  },
58
+  transformable: true,
59
+  brushMode: 'single',
60
+  removeOnClick: false
61
+};
62
+var baseUID = 0;
63
+/**
64
+ * @alias module:echarts/component/helper/BrushController
65
+ * @constructor
66
+ * @mixin {module:zrender/mixin/Eventful}
67
+ * @event module:echarts/component/helper/BrushController#brush
68
+ *        params:
69
+ *            areas: Array.<Array>, coord relates to container group,
70
+ *                                    If no container specified, to global.
71
+ *            opt {
72
+ *                isEnd: boolean,
73
+ *                removeOnClick: boolean
74
+ *            }
75
+ *
76
+ * @param {module:zrender/zrender~ZRender} zr
77
+ */
78
+
79
+function BrushController(zr) {
80
+  Eventful.call(this);
81
+  /**
82
+   * @type {module:zrender/zrender~ZRender}
83
+   * @private
84
+   */
85
+
86
+  this._zr = zr;
87
+  /**
88
+   * @type {module:zrender/container/Group}
89
+   * @readOnly
90
+   */
91
+
92
+  this.group = new graphic.Group();
93
+  /**
94
+   * Only for drawing (after enabledBrush).
95
+   *     'line', 'rect', 'polygon' or false
96
+   *     If passing false/null/undefined, disable brush.
97
+   *     If passing 'auto', determined by panel.defaultBrushType
98
+   * @private
99
+   * @type {string}
100
+   */
101
+
102
+  this._brushType;
103
+  /**
104
+   * Only for drawing (after enabledBrush).
105
+   *
106
+   * @private
107
+   * @type {Object}
108
+   */
109
+
110
+  this._brushOption;
111
+  /**
112
+   * @private
113
+   * @type {Object}
114
+   */
115
+
116
+  this._panels;
117
+  /**
118
+   * @private
119
+   * @type {Array.<nubmer>}
120
+   */
121
+
122
+  this._track = [];
123
+  /**
124
+   * @private
125
+   * @type {boolean}
126
+   */
127
+
128
+  this._dragging;
129
+  /**
130
+   * @private
131
+   * @type {Array}
132
+   */
133
+
134
+  this._covers = [];
135
+  /**
136
+   * @private
137
+   * @type {moudule:zrender/container/Group}
138
+   */
139
+
140
+  this._creatingCover;
141
+  /**
142
+   * `true` means global panel
143
+   * @private
144
+   * @type {module:zrender/container/Group|boolean}
145
+   */
146
+
147
+  this._creatingPanel;
148
+  /**
149
+   * @private
150
+   * @type {boolean}
151
+   */
152
+
153
+  this._enableGlobalPan;
154
+  /**
155
+   * @private
156
+   * @type {boolean}
157
+   */
158
+
159
+  /**
160
+   * @private
161
+   * @type {string}
162
+   */
163
+  this._uid = 'brushController_' + baseUID++;
164
+  /**
165
+   * @private
166
+   * @type {Object}
167
+   */
168
+
169
+  this._handlers = {};
170
+  each(mouseHandlers, function (handler, eventName) {
171
+    this._handlers[eventName] = zrUtil.bind(handler, this);
172
+  }, this);
173
+}
174
+
175
+BrushController.prototype = {
176
+  constructor: BrushController,
177
+
178
+  /**
179
+   * If set to null/undefined/false, select disabled.
180
+   * @param {Object} brushOption
181
+   * @param {string|boolean} brushOption.brushType 'line', 'rect', 'polygon' or false
182
+   *                          If passing false/null/undefined, disable brush.
183
+   *                          If passing 'auto', determined by panel.defaultBrushType.
184
+   *                              ('auto' can not be used in global panel)
185
+   * @param {number} [brushOption.brushMode='single'] 'single' or 'multiple'
186
+   * @param {boolean} [brushOption.transformable=true]
187
+   * @param {boolean} [brushOption.removeOnClick=false]
188
+   * @param {Object} [brushOption.brushStyle]
189
+   * @param {number} [brushOption.brushStyle.width]
190
+   * @param {number} [brushOption.brushStyle.lineWidth]
191
+   * @param {string} [brushOption.brushStyle.stroke]
192
+   * @param {string} [brushOption.brushStyle.fill]
193
+   * @param {number} [brushOption.z]
194
+   */
195
+  enableBrush: function (brushOption) {
196
+    this._brushType && doDisableBrush(this);
197
+    brushOption.brushType && doEnableBrush(this, brushOption);
198
+    return this;
199
+  },
200
+
201
+  /**
202
+   * @param {Array.<Object>} panelOpts If not pass, it is global brush.
203
+   *        Each items: {
204
+   *            panelId, // mandatory.
205
+   *            clipPath, // mandatory. function.
206
+   *            isTargetByCursor, // mandatory. function.
207
+   *            defaultBrushType, // optional, only used when brushType is 'auto'.
208
+   *            getLinearBrushOtherExtent, // optional. function.
209
+   *        }
210
+   */
211
+  setPanels: function (panelOpts) {
212
+    if (panelOpts && panelOpts.length) {
213
+      var panels = this._panels = {};
214
+      zrUtil.each(panelOpts, function (panelOpts) {
215
+        panels[panelOpts.panelId] = zrUtil.clone(panelOpts);
216
+      });
217
+    } else {
218
+      this._panels = null;
219
+    }
220
+
221
+    return this;
222
+  },
223
+
224
+  /**
225
+   * @param {Object} [opt]
226
+   * @return {boolean} [opt.enableGlobalPan=false]
227
+   */
228
+  mount: function (opt) {
229
+    opt = opt || {};
230
+    this._enableGlobalPan = opt.enableGlobalPan;
231
+    var thisGroup = this.group;
232
+
233
+    this._zr.add(thisGroup);
234
+
235
+    thisGroup.attr({
236
+      position: opt.position || [0, 0],
237
+      rotation: opt.rotation || 0,
238
+      scale: opt.scale || [1, 1]
239
+    });
240
+    this._transform = thisGroup.getLocalTransform();
241
+    return this;
242
+  },
243
+  eachCover: function (cb, context) {
244
+    each(this._covers, cb, context);
245
+  },
246
+
247
+  /**
248
+   * Update covers.
249
+   * @param {Array.<Object>} brushOptionList Like:
250
+   *        [
251
+   *            {id: 'xx', brushType: 'line', range: [23, 44], brushStyle, transformable},
252
+   *            {id: 'yy', brushType: 'rect', range: [[23, 44], [23, 54]]},
253
+   *            ...
254
+   *        ]
255
+   *        `brushType` is required in each cover info. (can not be 'auto')
256
+   *        `id` is not mandatory.
257
+   *        `brushStyle`, `transformable` is not mandatory, use DEFAULT_BRUSH_OPT by default.
258
+   *        If brushOptionList is null/undefined, all covers removed.
259
+   */
260
+  updateCovers: function (brushOptionList) {
261
+    brushOptionList = zrUtil.map(brushOptionList, function (brushOption) {
262
+      return zrUtil.merge(zrUtil.clone(DEFAULT_BRUSH_OPT), brushOption, true);
263
+    });
264
+    var tmpIdPrefix = '\0-brush-index-';
265
+    var oldCovers = this._covers;
266
+    var newCovers = this._covers = [];
267
+    var controller = this;
268
+    var creatingCover = this._creatingCover;
269
+    new DataDiffer(oldCovers, brushOptionList, oldGetKey, getKey).add(addOrUpdate).update(addOrUpdate).remove(remove).execute();
270
+    return this;
271
+
272
+    function getKey(brushOption, index) {
273
+      return (brushOption.id != null ? brushOption.id : tmpIdPrefix + index) + '-' + brushOption.brushType;
274
+    }
275
+
276
+    function oldGetKey(cover, index) {
277
+      return getKey(cover.__brushOption, index);
278
+    }
279
+
280
+    function addOrUpdate(newIndex, oldIndex) {
281
+      var newBrushOption = brushOptionList[newIndex]; // Consider setOption in event listener of brushSelect,
282
+      // where updating cover when creating should be forbiden.
283
+
284
+      if (oldIndex != null && oldCovers[oldIndex] === creatingCover) {
285
+        newCovers[newIndex] = oldCovers[oldIndex];
286
+      } else {
287
+        var cover = newCovers[newIndex] = oldIndex != null ? (oldCovers[oldIndex].__brushOption = newBrushOption, oldCovers[oldIndex]) : endCreating(controller, createCover(controller, newBrushOption));
288
+        updateCoverAfterCreation(controller, cover);
289
+      }
290
+    }
291
+
292
+    function remove(oldIndex) {
293
+      if (oldCovers[oldIndex] !== creatingCover) {
294
+        controller.group.remove(oldCovers[oldIndex]);
295
+      }
296
+    }
297
+  },
298
+  unmount: function () {
299
+    this.enableBrush(false); // container may 'removeAll' outside.
300
+
301
+    clearCovers(this);
302
+
303
+    this._zr.remove(this.group);
304
+
305
+    return this;
306
+  },
307
+  dispose: function () {
308
+    this.unmount();
309
+    this.off();
310
+  }
311
+};
312
+zrUtil.mixin(BrushController, Eventful);
313
+
314
+function doEnableBrush(controller, brushOption) {
315
+  var zr = controller._zr; // Consider roam, which takes globalPan too.
316
+
317
+  if (!controller._enableGlobalPan) {
318
+    interactionMutex.take(zr, MUTEX_RESOURCE_KEY, controller._uid);
319
+  }
320
+
321
+  each(controller._handlers, function (handler, eventName) {
322
+    zr.on(eventName, handler);
323
+  });
324
+  controller._brushType = brushOption.brushType;
325
+  controller._brushOption = zrUtil.merge(zrUtil.clone(DEFAULT_BRUSH_OPT), brushOption, true);
326
+}
327
+
328
+function doDisableBrush(controller) {
329
+  var zr = controller._zr;
330
+  interactionMutex.release(zr, MUTEX_RESOURCE_KEY, controller._uid);
331
+  each(controller._handlers, function (handler, eventName) {
332
+    zr.off(eventName, handler);
333
+  });
334
+  controller._brushType = controller._brushOption = null;
335
+}
336
+
337
+function createCover(controller, brushOption) {
338
+  var cover = coverRenderers[brushOption.brushType].createCover(controller, brushOption);
339
+  cover.__brushOption = brushOption;
340
+  updateZ(cover, brushOption);
341
+  controller.group.add(cover);
342
+  return cover;
343
+}
344
+
345
+function endCreating(controller, creatingCover) {
346
+  var coverRenderer = getCoverRenderer(creatingCover);
347
+
348
+  if (coverRenderer.endCreating) {
349
+    coverRenderer.endCreating(controller, creatingCover);
350
+    updateZ(creatingCover, creatingCover.__brushOption);
351
+  }
352
+
353
+  return creatingCover;
354
+}
355
+
356
+function updateCoverShape(controller, cover) {
357
+  var brushOption = cover.__brushOption;
358
+  getCoverRenderer(cover).updateCoverShape(controller, cover, brushOption.range, brushOption);
359
+}
360
+
361
+function updateZ(cover, brushOption) {
362
+  var z = brushOption.z;
363
+  z == null && (z = COVER_Z);
364
+  cover.traverse(function (el) {
365
+    el.z = z;
366
+    el.z2 = z; // Consider in given container.
367
+  });
368
+}
369
+
370
+function updateCoverAfterCreation(controller, cover) {
371
+  getCoverRenderer(cover).updateCommon(controller, cover);
372
+  updateCoverShape(controller, cover);
373
+}
374
+
375
+function getCoverRenderer(cover) {
376
+  return coverRenderers[cover.__brushOption.brushType];
377
+} // return target panel or `true` (means global panel)
378
+
379
+
380
+function getPanelByPoint(controller, e, localCursorPoint) {
381
+  var panels = controller._panels;
382
+
383
+  if (!panels) {
384
+    return true; // Global panel
385
+  }
386
+
387
+  var panel;
388
+  var transform = controller._transform;
389
+  each(panels, function (pn) {
390
+    pn.isTargetByCursor(e, localCursorPoint, transform) && (panel = pn);
391
+  });
392
+  return panel;
393
+} // Return a panel or true
394
+
395
+
396
+function getPanelByCover(controller, cover) {
397
+  var panels = controller._panels;
398
+
399
+  if (!panels) {
400
+    return true; // Global panel
401
+  }
402
+
403
+  var panelId = cover.__brushOption.panelId; // User may give cover without coord sys info,
404
+  // which is then treated as global panel.
405
+
406
+  return panelId != null ? panels[panelId] : true;
407
+}
408
+
409
+function clearCovers(controller) {
410
+  var covers = controller._covers;
411
+  var originalLength = covers.length;
412
+  each(covers, function (cover) {
413
+    controller.group.remove(cover);
414
+  }, controller);
415
+  covers.length = 0;
416
+  return !!originalLength;
417
+}
418
+
419
+function trigger(controller, opt) {
420
+  var areas = map(controller._covers, function (cover) {
421
+    var brushOption = cover.__brushOption;
422
+    var range = zrUtil.clone(brushOption.range);
423
+    return {
424
+      brushType: brushOption.brushType,
425
+      panelId: brushOption.panelId,
426
+      range: range
427
+    };
428
+  });
429
+  controller.trigger('brush', areas, {
430
+    isEnd: !!opt.isEnd,
431
+    removeOnClick: !!opt.removeOnClick
432
+  });
433
+}
434
+
435
+function shouldShowCover(controller) {
436
+  var track = controller._track;
437
+
438
+  if (!track.length) {
439
+    return false;
440
+  }
441
+
442
+  var p2 = track[track.length - 1];
443
+  var p1 = track[0];
444
+  var dx = p2[0] - p1[0];
445
+  var dy = p2[1] - p1[1];
446
+  var dist = mathPow(dx * dx + dy * dy, 0.5);
447
+  return dist > UNSELECT_THRESHOLD;
448
+}
449
+
450
+function getTrackEnds(track) {
451
+  var tail = track.length - 1;
452
+  tail < 0 && (tail = 0);
453
+  return [track[0], track[tail]];
454
+}
455
+
456
+function createBaseRectCover(doDrift, controller, brushOption, edgeNames) {
457
+  var cover = new graphic.Group();
458
+  cover.add(new graphic.Rect({
459
+    name: 'main',
460
+    style: makeStyle(brushOption),
461
+    silent: true,
462
+    draggable: true,
463
+    cursor: 'move',
464
+    drift: curry(doDrift, controller, cover, 'nswe'),
465
+    ondragend: curry(trigger, controller, {
466
+      isEnd: true
467
+    })
468
+  }));
469
+  each(edgeNames, function (name) {
470
+    cover.add(new graphic.Rect({
471
+      name: name,
472
+      style: {
473
+        opacity: 0
474
+      },
475
+      draggable: true,
476
+      silent: true,
477
+      invisible: true,
478
+      drift: curry(doDrift, controller, cover, name),
479
+      ondragend: curry(trigger, controller, {
480
+        isEnd: true
481
+      })
482
+    }));
483
+  });
484
+  return cover;
485
+}
486
+
487
+function updateBaseRect(controller, cover, localRange, brushOption) {
488
+  var lineWidth = brushOption.brushStyle.lineWidth || 0
489
+  var handleSize = mathMax(lineWidth, MIN_RESIZE_LINE_WIDTH)
490
+  var x = localRange[0][0]
491
+  var y = localRange[1][0]
492
+  var xa = x - lineWidth / 2
493
+  var ya = y - lineWidth / 2
494
+  var x2 = localRange[0][1]
495
+  var y2 = localRange[1][1]
496
+  var x2a = x2 - handleSize + lineWidth / 2
497
+  var y2a = y2 - handleSize + lineWidth / 2
498
+  var width = x2 - x;
499
+  var height = y2 - y;
500
+  var widtha = width + lineWidth
501
+  var heighta = height + lineWidth
502
+  updateRectShape(controller, cover, 'main', x, y, width, height)
503
+
504
+  if (brushOption.transformable) {
505
+    // updateRectShape(controller, cover, 'w', xa, ya, handleSize, heighta);
506
+    // updateRectShape(controller, cover, 'e', x2a, ya, handleSize, heighta);
507
+    // updateRectShape(controller, cover, 'n', xa, ya, widtha, handleSize);
508
+    // updateRectShape(controller, cover, 's', xa, y2a, widtha, handleSize);
509
+    // updateRectShape(controller, cover, 'nw', xa, ya, handleSize, handleSize);
510
+    // updateRectShape(controller, cover, 'ne', x2a, ya, handleSize, handleSize);
511
+    // updateRectShape(controller, cover, 'sw', xa, y2a, handleSize, handleSize);
512
+    // updateRectShape(controller, cover, 'se', x2a, y2a, handleSize, handleSize);
513
+  }
514
+}
515
+
516
+function updateCommon(controller, cover) {
517
+  var brushOption = cover.__brushOption;
518
+  var transformable = brushOption.transformable;
519
+  var mainEl = cover.childAt(0);
520
+  mainEl.useStyle(makeStyle(brushOption));
521
+  mainEl.attr({
522
+    silent: !transformable,
523
+    cursor: transformable ? 'move' : 'default'
524
+  });
525
+  each(['w', 'e', 'n', 's', 'se', 'sw', 'ne', 'nw'], function (name) {
526
+    var el = cover.childOfName(name);
527
+    var globalDir = getGlobalDirection(controller, name);
528
+    el && el.attr({
529
+      silent: !transformable,
530
+      invisible: !transformable,
531
+      cursor: transformable ? CURSOR_MAP[globalDir] + '-resize' : null
532
+    });
533
+  });
534
+}
535
+
536
+function updateRectShape(controller, cover, name, x, y, w, h) {
537
+  var el = cover.childOfName(name);
538
+  el && el.setShape(pointsToRect(clipByPanel(controller, cover, [[x, y], [x + w, y + h]])));
539
+}
540
+
541
+function makeStyle(brushOption) {
542
+  return zrUtil.defaults({
543
+    strokeNoScale: true
544
+  }, brushOption.brushStyle);
545
+}
546
+
547
+function formatRectRange(x, y, x2, y2) {
548
+  var min = [mathMin(x, x2), mathMin(y, y2)];
549
+  var max = [mathMax(x, x2), mathMax(y, y2)];
550
+  return [[min[0], max[0]], // x range
551
+  [min[1], max[1]] // y range
552
+  ];
553
+}
554
+
555
+function getTransform(controller) {
556
+  return graphic.getTransform(controller.group);
557
+}
558
+
559
+function getGlobalDirection(controller, localDirection) {
560
+  if (localDirection.length > 1) {
561
+    localDirection = localDirection.split('');
562
+    var globalDir = [getGlobalDirection(controller, localDirection[0]), getGlobalDirection(controller, localDirection[1])];
563
+    (globalDir[0] === 'e' || globalDir[0] === 'w') && globalDir.reverse();
564
+    return globalDir.join('');
565
+  } else {
566
+    var map = {
567
+      w: 'left',
568
+      e: 'right',
569
+      n: 'top',
570
+      s: 'bottom'
571
+    };
572
+    var inverseMap = {
573
+      left: 'w',
574
+      right: 'e',
575
+      top: 'n',
576
+      bottom: 's'
577
+    };
578
+    var globalDir = graphic.transformDirection(map[localDirection], getTransform(controller));
579
+    return inverseMap[globalDir];
580
+  }
581
+}
582
+
583
+function driftRect(toRectRange, fromRectRange, controller, cover, name, dx, dy, e) {
584
+  var brushOption = cover.__brushOption;
585
+  var rectRange = toRectRange(brushOption.range);
586
+  var localDelta = toLocalDelta(controller, dx, dy);
587
+  each(name.split(''), function (namePart) {
588
+    var ind = DIRECTION_MAP[namePart];
589
+    rectRange[ind[0]][ind[1]] += localDelta[ind[0]];
590
+  });
591
+  brushOption.range = fromRectRange(formatRectRange(rectRange[0][0], rectRange[1][0], rectRange[0][1], rectRange[1][1]));
592
+  updateCoverAfterCreation(controller, cover);
593
+  trigger(controller, {
594
+    isEnd: false
595
+  });
596
+}
597
+
598
+function driftPolygon(controller, cover, dx, dy, e) {
599
+  var range = cover.__brushOption.range;
600
+  var localDelta = toLocalDelta(controller, dx, dy);
601
+  each(range, function (point) {
602
+    point[0] += localDelta[0];
603
+    point[1] += localDelta[1];
604
+  });
605
+  updateCoverAfterCreation(controller, cover);
606
+  trigger(controller, {
607
+    isEnd: false
608
+  });
609
+}
610
+
611
+function toLocalDelta(controller, dx, dy) {
612
+  var thisGroup = controller.group;
613
+  var localD = thisGroup.transformCoordToLocal(dx, dy);
614
+  var localZero = thisGroup.transformCoordToLocal(0, 0);
615
+  return [localD[0] - localZero[0], localD[1] - localZero[1]];
616
+}
617
+
618
+function clipByPanel(controller, cover, data) {
619
+  var panel = getPanelByCover(controller, cover);
620
+  return panel && panel !== true ? panel.clipPath(data, controller._transform) : zrUtil.clone(data);
621
+}
622
+
623
+function pointsToRect(points) {
624
+  var xmin = mathMin(points[0][0], points[1][0]);
625
+  var ymin = mathMin(points[0][1], points[1][1]);
626
+  var xmax = mathMax(points[0][0], points[1][0]);
627
+  var ymax = mathMax(points[0][1], points[1][1]);
628
+  return {
629
+    x: xmin,
630
+    y: ymin,
631
+    width: xmax - xmin,
632
+    height: ymax - ymin
633
+  };
634
+}
635
+
636
+function resetCursor(controller, e, localCursorPoint) {
637
+  // Check active
638
+  if (!controller._brushType) {
639
+    return;
640
+  }
641
+
642
+  var zr = controller._zr;
643
+  var covers = controller._covers;
644
+  var currPanel = getPanelByPoint(controller, e, localCursorPoint); // Check whether in covers.
645
+
646
+  if (!controller._dragging) {
647
+    for (var i = 0; i < covers.length; i++) {
648
+      var brushOption = covers[i].__brushOption;
649
+
650
+      if (currPanel && (currPanel === true || brushOption.panelId === currPanel.panelId) && coverRenderers[brushOption.brushType].contain(covers[i], localCursorPoint[0], localCursorPoint[1])) {
651
+        // Use cursor style set on cover.
652
+        return;
653
+      }
654
+    }
655
+  }
656
+
657
+  currPanel && zr.setCursorStyle('crosshair');
658
+}
659
+
660
+function preventDefault(e) {
661
+  var rawE = e.event;
662
+  rawE.preventDefault && rawE.preventDefault();
663
+}
664
+
665
+function mainShapeContain(cover, x, y) {
666
+  return cover.childOfName('main').contain(x, y);
667
+}
668
+
669
+function updateCoverByMouse(controller, e, localCursorPoint, isEnd) {
670
+  var creatingCover = controller._creatingCover;
671
+  var panel = controller._creatingPanel;
672
+  var thisBrushOption = controller._brushOption;
673
+  var eventParams;
674
+
675
+  controller._track.push(localCursorPoint.slice());
676
+
677
+  if (shouldShowCover(controller) || creatingCover) {
678
+    if (panel && !creatingCover) {
679
+      thisBrushOption.brushMode === 'single' && clearCovers(controller);
680
+      var brushOption = zrUtil.clone(thisBrushOption);
681
+      brushOption.brushType = determineBrushType(brushOption.brushType, panel);
682
+      brushOption.panelId = panel === true ? null : panel.panelId;
683
+      creatingCover = controller._creatingCover = createCover(controller, brushOption);
684
+
685
+      controller._covers.push(creatingCover);
686
+    }
687
+
688
+    if (creatingCover) {
689
+      var coverRenderer = coverRenderers[determineBrushType(controller._brushType, panel)];
690
+      var coverBrushOption = creatingCover.__brushOption;
691
+      coverBrushOption.range = coverRenderer.getCreatingRange(clipByPanel(controller, creatingCover, controller._track));
692
+
693
+      if (isEnd) {
694
+        endCreating(controller, creatingCover);
695
+        coverRenderer.updateCommon(controller, creatingCover);
696
+      }
697
+
698
+      updateCoverShape(controller, creatingCover);
699
+      eventParams = {
700
+        isEnd: isEnd
701
+      };
702
+    }
703
+  } else if (isEnd && thisBrushOption.brushMode === 'single' && thisBrushOption.removeOnClick) {
704
+    // Help user to remove covers easily, only by a tiny drag, in 'single' mode.
705
+    // But a single click do not clear covers, because user may have casual
706
+    // clicks (for example, click on other component and do not expect covers
707
+    // disappear).
708
+    // Only some cover removed, trigger action, but not every click trigger action.
709
+    if (getPanelByPoint(controller, e, localCursorPoint) && clearCovers(controller)) {
710
+      eventParams = {
711
+        isEnd: isEnd,
712
+        removeOnClick: true
713
+      };
714
+    }
715
+  }
716
+
717
+  return eventParams;
718
+}
719
+
720
+function determineBrushType(brushType, panel) {
721
+  if (brushType === 'auto') {
722
+    return panel.defaultBrushType;
723
+  }
724
+
725
+  return brushType;
726
+}
727
+
728
+var mouseHandlers = {
729
+  mousedown: function (e) {
730
+    if (this._dragging) {
731
+      // In case some browser do not support globalOut,
732
+      // and release mose out side the browser.
733
+      handleDragEnd.call(this, e);
734
+    } else if (!e.target || !e.target.draggable) {
735
+      preventDefault(e);
736
+      var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY);
737
+      this._creatingCover = null;
738
+      var panel = this._creatingPanel = getPanelByPoint(this, e, localCursorPoint);
739
+
740
+      if (panel) {
741
+        this._dragging = true;
742
+        this._track = [localCursorPoint.slice()];
743
+      }
744
+    }
745
+  },
746
+  mousemove: function (e) {
747
+    var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY);
748
+    resetCursor(this, e, localCursorPoint);
749
+
750
+    if (this._dragging) {
751
+      preventDefault(e);
752
+      var eventParams = updateCoverByMouse(this, e, localCursorPoint, false);
753
+      eventParams && trigger(this, eventParams);
754
+    }
755
+  },
756
+  mouseup: handleDragEnd //,
757
+  // FIXME
758
+  // in tooltip, globalout should not be triggered.
759
+  // globalout: handleDragEnd
760
+
761
+};
762
+
763
+function handleDragEnd(e) {
764
+  if (this._dragging) {
765
+    preventDefault(e);
766
+    var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY);
767
+    var eventParams = updateCoverByMouse(this, e, localCursorPoint, true);
768
+    this._dragging = false;
769
+    this._track = [];
770
+    this._creatingCover = null; // trigger event shoule be at final, after procedure will be nested.
771
+
772
+    eventParams && trigger(this, eventParams);
773
+  }
774
+}
775
+/**
776
+ * key: brushType
777
+ * @type {Object}
778
+ */
779
+
780
+
781
+var coverRenderers = {
782
+  lineX: getLineRenderer(0),
783
+  lineY: getLineRenderer(1),
784
+  rect: {
785
+    createCover: function (controller, brushOption) {
786
+      return createBaseRectCover(curry(driftRect, function (range) {
787
+        return range;
788
+      }, function (range) {
789
+        return range;
790
+      }), controller, brushOption, ['w', 'e', 'n', 's', 'se', 'sw', 'ne', 'nw']);
791
+    },
792
+    getCreatingRange: function (localTrack) {
793
+      var ends = getTrackEnds(localTrack);
794
+      return formatRectRange(ends[1][0], ends[1][1], ends[0][0], ends[0][1]);
795
+    },
796
+    updateCoverShape: function (controller, cover, localRange, brushOption) {
797
+      updateBaseRect(controller, cover, localRange, brushOption);
798
+    },
799
+    updateCommon: updateCommon,
800
+    contain: mainShapeContain
801
+  },
802
+  polygon: {
803
+    createCover: function (controller, brushOption) {
804
+      var cover = new graphic.Group(); // Do not use graphic.Polygon because graphic.Polyline do not close the
805
+      // border of the shape when drawing, which is a better experience for user.
806
+
807
+      cover.add(new graphic.Polyline({
808
+        name: 'main',
809
+        style: makeStyle(brushOption),
810
+        silent: true
811
+      }));
812
+      return cover;
813
+    },
814
+    getCreatingRange: function (localTrack) {
815
+      return localTrack;
816
+    },
817
+    endCreating: function (controller, cover) {
818
+      cover.remove(cover.childAt(0)); // Use graphic.Polygon close the shape.
819
+
820
+      cover.add(new graphic.Polygon({
821
+        name: 'main',
822
+        draggable: true,
823
+        drift: curry(driftPolygon, controller, cover),
824
+        ondragend: curry(trigger, controller, {
825
+          isEnd: true
826
+        })
827
+      }));
828
+    },
829
+    updateCoverShape: function (controller, cover, localRange, brushOption) {
830
+      cover.childAt(0).setShape({
831
+        points: clipByPanel(controller, cover, localRange)
832
+      });
833
+    },
834
+    updateCommon: updateCommon,
835
+    contain: mainShapeContain
836
+  }
837
+};
838
+
839
+function getLineRenderer(xyIndex) {
840
+  return {
841
+    createCover: function (controller, brushOption) {
842
+      return createBaseRectCover(curry(driftRect, function (range) {
843
+        var rectRange = [range, [0, 100]];
844
+        xyIndex && rectRange.reverse();
845
+        return rectRange;
846
+      }, function (rectRange) {
847
+        return rectRange[xyIndex];
848
+      }), controller, brushOption, [['w', 'e'], ['n', 's']][xyIndex]);
849
+    },
850
+    getCreatingRange: function (localTrack) {
851
+      var ends = getTrackEnds(localTrack);
852
+      var min = mathMin(ends[0][xyIndex], ends[1][xyIndex]);
853
+      var max = mathMax(ends[0][xyIndex], ends[1][xyIndex]);
854
+      return [min, max];
855
+    },
856
+    updateCoverShape: function (controller, cover, localRange, brushOption) {
857
+      var otherExtent; // If brushWidth not specified, fit the panel.
858
+
859
+      var panel = getPanelByCover(controller, cover);
860
+
861
+      if (panel !== true && panel.getLinearBrushOtherExtent) {
862
+        otherExtent = panel.getLinearBrushOtherExtent(xyIndex, controller._transform);
863
+      } else {
864
+        var zr = controller._zr;
865
+        otherExtent = [0, [zr.getWidth(), zr.getHeight()][1 - xyIndex]];
866
+      }
867
+
868
+      var rectRange = [localRange, otherExtent];
869
+      xyIndex && rectRange.reverse();
870
+      updateBaseRect(controller, cover, rectRange, brushOption);
871
+    },
872
+    updateCommon: updateCommon,
873
+    contain: mainShapeContain
874
+  };
875
+}
876
+
877
+var _default = BrushController;
878
+module.exports = _default;

+ 106 - 0
src/utils/BrushView.js

@@ -0,0 +1,106 @@
1
+import * as echarts from '../../node_modules/echarts'
2
+// var echarts = require('../../node_modules/echarts')
3
+import * as zrUtil from '../../node_modules/zrender/src/core/util'
4
+// var zrUtil = require('../../node_modules/zrender/src/core/util')
5
+var BrushController = require('./BrushController2')
6
+
7
+/*
8
+* Licensed to the Apache Software Foundation (ASF) under one
9
+* or more contributor license agreements.  See the NOTICE file
10
+* distributed with this work for additional information
11
+* regarding copyright ownership.  The ASF licenses this file
12
+* to you under the Apache License, Version 2.0 (the
13
+* "License"); you may not use this file except in compliance
14
+* with the License.  You may obtain a copy of the License at
15
+*
16
+*   http://www.apache.org/licenses/LICENSE-2.0
17
+*
18
+* Unless required by applicable law or agreed to in writing,
19
+* software distributed under the License is distributed on an
20
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
+* KIND, either express or implied.  See the License for the
22
+* specific language governing permissions and limitations
23
+* under the License.
24
+*/
25
+var _default = echarts.extendComponentView({
26
+  type: 'brush',
27
+  init: function (ecModel, api) {
28
+    /**
29
+     * @readOnly
30
+     * @type {module:echarts/model/Global}
31
+     */
32
+    this.ecModel = ecModel
33
+    /**
34
+     * @readOnly
35
+     * @type {module:echarts/ExtensionAPI}
36
+     */
37
+    this.api = api
38
+    /**
39
+     * @readOnly
40
+     * @type {module:echarts/component/brush/BrushModel}
41
+     */
42
+    this.model
43
+    /**
44
+     * @private
45
+     * @type {module:echarts/component/helper/BrushController}
46
+     */
47
+    (this._brushController = new BrushController(api.getZr())).on('brush', zrUtil.bind(this._onBrush, this)).mount()
48
+  },
49
+
50
+  /**
51
+   * @override
52
+   */
53
+  render: function (brushModel) {
54
+    this.model = brushModel
55
+    return updateController.apply(this, arguments)
56
+  },
57
+
58
+  /**
59
+   * @override
60
+   */
61
+  updateTransform: updateController,
62
+
63
+  /**
64
+   * @override
65
+   */
66
+  updateView: updateController,
67
+  // /**
68
+  //  * @override
69
+  //  */
70
+  // updateLayout: updateController,
71
+  // /**
72
+  //  * @override
73
+  //  */
74
+  // updateVisual: updateController,
75
+
76
+  /**
77
+   * @override
78
+   */
79
+  dispose: function () {
80
+    this._brushController.dispose()
81
+  },
82
+
83
+  /**
84
+   * @private
85
+   */
86
+  _onBrush: function (areas, opt) {
87
+    var modelId = this.model.id
88
+    this.model.brushTargetManager.setOutputRanges(areas, this.ecModel) // Action is not dispatched on drag end, because the drag end
89
+    // emits the same params with the last drag move event, and
90
+    // may have some delay when using touch pad, which makes
91
+    // animation not smooth (when using debounce).
92
+    (!opt.isEnd || opt.removeOnClick) && this.api.dispatchAction({
93
+      type: 'brush',
94
+      brushId: modelId,
95
+      areas: zrUtil.clone(areas),
96
+      $from: modelId
97
+    })
98
+  }
99
+})
100
+
101
+function updateController (brushModel, ecModel, api, payload) {
102
+  // Do not update controller when drawing.
103
+  (!payload || payload.$from !== brushModel.id) && this._brushController.setPanels(brushModel.brushTargetManager.makePanelOpts(api)).enableBrush(brushModel.brushOption).updateCovers(brushModel.areas.slice())
104
+}
105
+
106
+module.exports = _default

+ 64 - 1
src/views/homepage/index.vue

@@ -89,6 +89,7 @@
89 89
           <!-- <template slot="title">分组一</template> -->
90 90
           <el-menu-item index="7-1">个人中心</el-menu-item>
91 91
           <el-menu-item index="7-2">个人设置</el-menu-item>
92
+          <el-menu-item index="7-3">个人设置2</el-menu-item>
92 93
         </el-menu-item-group>
93 94
       </el-submenu>
94 95
      </el-menu>
@@ -106,6 +107,41 @@
106 107
           <option value="">5</option>
107 108
            <option value="">5</option>
108 109
       </select>
110
+       <el-table
111
+      :data="tableData"
112
+      style="width: 100%"
113
+      @sort-change='sortchange'
114
+      ref='sort'>
115
+      <el-table-column
116
+        prop="date"
117
+        label="日期"
118
+        width="180">
119
+      </el-table-column>
120
+      <el-table-column
121
+        prop="name"
122
+        label="姓名"
123
+        width="180">
124
+      </el-table-column>
125
+      <el-table-column
126
+        prop="address"
127
+        label="地址">
128
+      </el-table-column>
129
+      <el-table-column
130
+        prop="age"
131
+        label="年纪"
132
+        sortable='custom'
133
+        >
134
+      </el-table-column>
135
+      <el-table-column
136
+        label="操作"
137
+        >
138
+        <template slot-scope="scope">
139
+          <el-button
140
+          size="mini"
141
+          @click="handleClear">取消排序</el-button>
142
+        </template>
143
+      </el-table-column>
144
+    </el-table>
109 145
       <router-view></router-view>
110 146
     </el-main>
111 147
   </el-container>
@@ -117,10 +153,37 @@ export default {
117 153
   name: 'homepage',
118 154
   data () {
119 155
     return {
120
-      isCollapse: false
156
+      isCollapse: false,
157
+      tableData: [{
158
+        date: '2016-05-02',
159
+        name: '王小虎',
160
+        address: '上海市普陀区金沙江路 1518 弄',
161
+        age: 1
162
+      }, {
163
+        date: '2016-05-04',
164
+        name: '王小虎',
165
+        address: '上海市普陀区金沙江路 1517 弄',
166
+        age: 2
167
+      }, {
168
+        date: '2016-05-01',
169
+        name: '王小虎',
170
+        address: '上海市普陀区金沙江路 1519 弄',
171
+        age: 3
172
+      }, {
173
+        date: '2016-05-03',
174
+        name: '王小虎',
175
+        address: '上海市普陀区金沙江路 1516 弄',
176
+        age: 4
177
+      }]
121 178
     }
122 179
   },
123 180
   methods: {
181
+    handleClear () {
182
+      this.$refs.sort.clearSort()
183
+    },
184
+    sortchange () {
185
+      console.log('sortchange')
186
+    },
124 187
     handleClose () {
125 188
       console.log('handleClose')
126 189
     },