UNPKG

11.4 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var tslib_1 = require("tslib");
4var util_1 = require("@antv/util");
5var constant_1 = require("../../constant");
6var dependents_1 = require("../../dependents");
7var bbox_1 = require("../../util/bbox");
8var direction_1 = require("../../util/direction");
9var helper_1 = require("../../util/helper");
10var base_1 = require("./base");
11/**
12 * @ignore
13 * slider Controller
14 */
15var Slider = /** @class */ (function (_super) {
16 tslib_1.__extends(Slider, _super);
17 function Slider(view) {
18 var _this = _super.call(this, view) || this;
19 _this.onChangeFn = util_1.noop;
20 /**
21 * 清除测量
22 */
23 _this.resetMeasure = function () {
24 _this.clear();
25 };
26 /**
27 * 滑块滑动的时候出发
28 * @param v
29 */
30 _this.onValueChange = function (v) {
31 var _a = tslib_1.__read(v, 2), min = _a[0], max = _a[1];
32 _this.start = min;
33 _this.end = max;
34 _this.changeViewData(min, max);
35 };
36 _this.container = _this.view.getLayer(constant_1.LAYER.FORE).addGroup();
37 _this.onChangeFn = (0, util_1.throttle)(_this.onValueChange, 20, {
38 leading: true,
39 });
40 _this.width = 0;
41 _this.view.on(constant_1.VIEW_LIFE_CIRCLE.BEFORE_CHANGE_DATA, _this.resetMeasure);
42 _this.view.on(constant_1.VIEW_LIFE_CIRCLE.BEFORE_CHANGE_SIZE, _this.resetMeasure);
43 return _this;
44 }
45 Object.defineProperty(Slider.prototype, "name", {
46 get: function () {
47 return 'slider';
48 },
49 enumerable: false,
50 configurable: true
51 });
52 Slider.prototype.destroy = function () {
53 _super.prototype.destroy.call(this);
54 this.view.off(constant_1.VIEW_LIFE_CIRCLE.BEFORE_CHANGE_DATA, this.resetMeasure);
55 this.view.off(constant_1.VIEW_LIFE_CIRCLE.BEFORE_CHANGE_SIZE, this.resetMeasure);
56 };
57 /**
58 * 初始化
59 */
60 Slider.prototype.init = function () { };
61 /**
62 * 渲染
63 */
64 Slider.prototype.render = function () {
65 this.option = this.view.getOptions().slider;
66 var _a = this.getSliderCfg(), start = _a.start, end = _a.end;
67 if ((0, util_1.isNil)(this.start)) {
68 this.start = start;
69 this.end = end;
70 }
71 var viewData = this.view.getOptions().data;
72 if (this.option && !(0, util_1.isEmpty)(viewData)) {
73 if (this.slider) {
74 // exist, update
75 this.slider = this.updateSlider();
76 }
77 else {
78 // not exist, create
79 this.slider = this.createSlider();
80 // 监听事件,绑定交互
81 this.slider.component.on('sliderchange', this.onChangeFn);
82 }
83 }
84 else {
85 if (this.slider) {
86 // exist, destroy
87 this.slider.component.destroy();
88 this.slider = undefined;
89 }
90 else {
91 // do nothing
92 }
93 }
94 };
95 /**
96 * 布局
97 */
98 Slider.prototype.layout = function () {
99 var _this = this;
100 if (this.option && !this.width) {
101 this.measureSlider();
102 setTimeout(function () {
103 // 初始状态下的 view 数据过滤
104 if (!_this.view.destroyed) {
105 _this.changeViewData(_this.start, _this.end);
106 }
107 }, 0);
108 }
109 if (this.slider) {
110 var width = this.view.coordinateBBox.width;
111 // 获取组件的 layout bbox
112 var padding = this.slider.component.get('padding');
113 var _a = tslib_1.__read(padding, 4), paddingTop = _a[0], paddingRight = _a[1], paddingBottom = _a[2], paddingLeft = _a[3];
114 var bboxObject = this.slider.component.getLayoutBBox();
115 var bbox = new bbox_1.BBox(bboxObject.x, bboxObject.y, Math.min(bboxObject.width, width), bboxObject.height).expand(padding);
116 var _b = this.getMinMaxText(this.start, this.end), minText = _b.minText, maxText = _b.maxText;
117 var _c = tslib_1.__read((0, direction_1.directionToPosition)(this.view.viewBBox, bbox, constant_1.DIRECTION.BOTTOM), 2), x1 = _c[0], y1 = _c[1];
118 var _d = tslib_1.__read((0, direction_1.directionToPosition)(this.view.coordinateBBox, bbox, constant_1.DIRECTION.BOTTOM), 2), x2 = _d[0], y2 = _d[1];
119 // 默认放在 bottom
120 this.slider.component.update(tslib_1.__assign(tslib_1.__assign({}, this.getSliderCfg()), { x: x2 + paddingLeft, y: y1 + paddingTop, width: this.width, start: this.start, end: this.end, minText: minText, maxText: maxText }));
121 this.view.viewBBox = this.view.viewBBox.cut(bbox, constant_1.DIRECTION.BOTTOM);
122 }
123 };
124 /**
125 * 更新
126 */
127 Slider.prototype.update = function () {
128 // 逻辑和 render 保持一致
129 this.render();
130 };
131 /**
132 * 创建 slider 组件
133 */
134 Slider.prototype.createSlider = function () {
135 var cfg = this.getSliderCfg();
136 // 添加 slider 组件
137 var component = new dependents_1.Slider(tslib_1.__assign({ container: this.container }, cfg));
138 component.init();
139 return {
140 component: component,
141 layer: constant_1.LAYER.FORE,
142 direction: constant_1.DIRECTION.BOTTOM,
143 type: constant_1.COMPONENT_TYPE.SLIDER,
144 };
145 };
146 /**
147 * 更新配置
148 */
149 Slider.prototype.updateSlider = function () {
150 var cfg = this.getSliderCfg();
151 if (this.width) {
152 var _a = this.getMinMaxText(this.start, this.end), minText = _a.minText, maxText = _a.maxText;
153 cfg = tslib_1.__assign(tslib_1.__assign({}, cfg), { width: this.width, start: this.start, end: this.end, minText: minText, maxText: maxText });
154 }
155 this.slider.component.update(cfg);
156 return this.slider;
157 };
158 /**
159 * 进行测量操作
160 */
161 Slider.prototype.measureSlider = function () {
162 var width = this.getSliderCfg().width;
163 this.width = width;
164 };
165 /**
166 * 生成 slider 配置
167 */
168 Slider.prototype.getSliderCfg = function () {
169 var cfg = {
170 height: 16,
171 start: 0,
172 end: 1,
173 minText: '',
174 maxText: '',
175 x: 0,
176 y: 0,
177 width: this.view.coordinateBBox.width,
178 };
179 if ((0, util_1.isObject)(this.option)) {
180 // 用户配置的数据,优先级更高
181 var trendCfg = tslib_1.__assign({ data: this.getData() }, (0, util_1.get)(this.option, 'trendCfg', {}));
182 // 因为有样式,所以深层覆盖
183 cfg = (0, util_1.deepMix)({}, cfg, this.getThemeOptions(), this.option);
184 // trendCfg 因为有数据数组,所以使用浅替换
185 cfg = tslib_1.__assign(tslib_1.__assign({}, cfg), { trendCfg: trendCfg });
186 }
187 cfg.start = (0, util_1.clamp)(Math.min((0, util_1.isNil)(cfg.start) ? 0 : cfg.start, (0, util_1.isNil)(cfg.end) ? 1 : cfg.end), 0, 1);
188 cfg.end = (0, util_1.clamp)(Math.max((0, util_1.isNil)(cfg.start) ? 0 : cfg.start, (0, util_1.isNil)(cfg.end) ? 1 : cfg.end), 0, 1);
189 return cfg;
190 };
191 /**
192 * 从 view 中获取数据,缩略轴使用全量的数据
193 */
194 Slider.prototype.getData = function () {
195 var data = this.view.getOptions().data;
196 var _a = tslib_1.__read(this.view.getYScales(), 1), yScale = _a[0];
197 var groupScales = this.view.getGroupScales();
198 if (groupScales.length) {
199 var _b = groupScales[0], field_1 = _b.field, ticks_1 = _b.ticks;
200 return data.reduce(function (pre, cur) {
201 if (cur[field_1] === ticks_1[0]) {
202 pre.push(cur[yScale.field]);
203 }
204 return pre;
205 }, []);
206 }
207 return data.map(function (datum) { return datum[yScale.field] || 0; });
208 };
209 /**
210 * 获取 slider 的主题配置
211 */
212 Slider.prototype.getThemeOptions = function () {
213 var theme = this.view.getTheme();
214 return (0, util_1.get)(theme, ['components', 'slider', 'common'], {});
215 };
216 /**
217 * 根据 start/end 和当前数据计算出当前的 minText/maxText
218 * @param min
219 * @param max
220 */
221 Slider.prototype.getMinMaxText = function (min, max) {
222 var data = this.view.getOptions().data;
223 var xScale = this.view.getXScale();
224 var isHorizontal = true;
225 var values = (0, util_1.valuesOfKey)(data, xScale.field);
226 // 如果是 xScale 数值类型,则进行排序
227 if (xScale.isLinear) {
228 values = values.sort();
229 }
230 var xValues = isHorizontal ? values : values.reverse();
231 var dataSize = (0, util_1.size)(data);
232 if (!xScale || !dataSize) {
233 return {}; // fix: 需要兼容,否则调用方直接取值会报错
234 }
235 var xTickCount = (0, util_1.size)(xValues);
236 var minIndex = Math.floor(min * (xTickCount - 1));
237 var maxIndex = Math.floor(max * (xTickCount - 1));
238 var minText = (0, util_1.get)(xValues, [minIndex]);
239 var maxText = (0, util_1.get)(xValues, [maxIndex]);
240 var formatter = this.getSliderCfg().formatter;
241 if (formatter) {
242 minText = formatter(minText, data[minIndex], minIndex);
243 maxText = formatter(maxText, data[maxIndex], maxIndex);
244 }
245 return {
246 minText: minText,
247 maxText: maxText,
248 };
249 };
250 /**
251 * 更新 view 过滤数据
252 * @param min
253 * @param max
254 */
255 Slider.prototype.changeViewData = function (min, max) {
256 var data = this.view.getOptions().data;
257 var xScale = this.view.getXScale();
258 var dataSize = (0, util_1.size)(data);
259 if (!xScale || !dataSize) {
260 return;
261 }
262 var isHorizontal = true;
263 var values = (0, util_1.valuesOfKey)(data, xScale.field);
264 // 如果是 xScale 数值类型,则进行排序
265 var xScaleValues = this.view.getXScale().isLinear ? values.sort(function (a, b) { return Number(a) - Number(b); }) : values;
266 var xValues = isHorizontal ? xScaleValues : xScaleValues.reverse();
267 var xTickCount = (0, util_1.size)(xValues);
268 var minIndex = Math.floor(min * (xTickCount - 1));
269 var maxIndex = Math.floor(max * (xTickCount - 1));
270 // 增加 x 轴的过滤器
271 this.view.filter(xScale.field, function (value, datum) {
272 var idx = xValues.indexOf(value);
273 return idx > -1 ? (0, helper_1.isBetween)(idx, minIndex, maxIndex) : true;
274 });
275 this.view.render(true);
276 };
277 /**
278 * 覆写父类方法
279 */
280 Slider.prototype.getComponents = function () {
281 return this.slider ? [this.slider] : [];
282 };
283 /**
284 * 覆盖父类
285 */
286 Slider.prototype.clear = function () {
287 if (this.slider) {
288 this.slider.component.destroy();
289 this.slider = undefined;
290 }
291 this.width = 0;
292 this.start = undefined;
293 this.end = undefined;
294 };
295 return Slider;
296}(base_1.Controller));
297exports.default = Slider;
298//# sourceMappingURL=slider.js.map
\No newline at end of file