/*
|
* 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.
|
*/
|
|
|
import { EventProcessor, EventQuery } from 'zrender/src/core/Eventful';
|
import { ECActionEvent, NormalizedEventQuery, EventQueryItem, ECElementEvent } from './types';
|
import ComponentModel from '../model/Component';
|
import ComponentView from '../view/Component';
|
import ChartView from '../view/Chart';
|
import * as zrUtil from 'zrender/src/core/util';
|
import { parseClassType } from './clazz';
|
import Element from 'zrender/src/Element';
|
|
/**
|
* Usage of query:
|
* `chart.on('click', query, handler);`
|
* The `query` can be:
|
* + The component type query string, only `mainType` or `mainType.subType`,
|
* like: 'xAxis', 'series', 'xAxis.category' or 'series.line'.
|
* + The component query object, like:
|
* `{seriesIndex: 2}`, `{seriesName: 'xx'}`, `{seriesId: 'some'}`,
|
* `{xAxisIndex: 2}`, `{xAxisName: 'xx'}`, `{xAxisId: 'some'}`.
|
* + The data query object, like:
|
* `{dataIndex: 123}`, `{dataType: 'link'}`, `{name: 'some'}`.
|
* + The other query object (cmponent customized query), like:
|
* `{element: 'some'}` (only available in custom series).
|
*
|
* Caveat: If a prop in the `query` object is `null/undefined`, it is the
|
* same as there is no such prop in the `query` object.
|
*/
|
export class ECEventProcessor implements EventProcessor {
|
|
// These info required: targetEl, packedEvent, model, view
|
eventInfo: {
|
targetEl: Element;
|
packedEvent: ECActionEvent | ECElementEvent;
|
model: ComponentModel;
|
view: ComponentView | ChartView;
|
};
|
|
normalizeQuery(query: EventQuery): NormalizedEventQuery {
|
const cptQuery: EventQueryItem = {};
|
const dataQuery: EventQueryItem = {};
|
const otherQuery: EventQueryItem = {};
|
|
// `query` is `mainType` or `mainType.subType` of component.
|
if (zrUtil.isString(query)) {
|
const condCptType = parseClassType(query);
|
// `.main` and `.sub` may be ''.
|
cptQuery.mainType = condCptType.main || null;
|
cptQuery.subType = condCptType.sub || null;
|
}
|
// `query` is an object, convert to {mainType, index, name, id}.
|
else {
|
// `xxxIndex`, `xxxName`, `xxxId`, `name`, `dataIndex`, `dataType` is reserved,
|
// can not be used in `compomentModel.filterForExposedEvent`.
|
const suffixes = ['Index', 'Name', 'Id'];
|
const dataKeys = {name: 1, dataIndex: 1, dataType: 1};
|
zrUtil.each(query, function (val, key) {
|
let reserved = false;
|
for (let i = 0; i < suffixes.length; i++) {
|
const propSuffix = suffixes[i];
|
const suffixPos = key.lastIndexOf(propSuffix);
|
if (suffixPos > 0 && suffixPos === key.length - propSuffix.length) {
|
const mainType = key.slice(0, suffixPos);
|
// Consider `dataIndex`.
|
if (mainType !== 'data') {
|
cptQuery.mainType = mainType;
|
cptQuery[propSuffix.toLowerCase()] = val;
|
reserved = true;
|
}
|
}
|
}
|
if (dataKeys.hasOwnProperty(key)) {
|
dataQuery[key] = val;
|
reserved = true;
|
}
|
if (!reserved) {
|
otherQuery[key] = val;
|
}
|
});
|
}
|
|
return {
|
cptQuery: cptQuery,
|
dataQuery: dataQuery,
|
otherQuery: otherQuery
|
};
|
}
|
|
filter(eventType: string, query: NormalizedEventQuery): boolean {
|
// They should be assigned before each trigger call.
|
const eventInfo = this.eventInfo;
|
|
if (!eventInfo) {
|
return true;
|
}
|
|
const targetEl = eventInfo.targetEl;
|
const packedEvent = eventInfo.packedEvent;
|
const model = eventInfo.model;
|
const view = eventInfo.view;
|
|
// For event like 'globalout'.
|
if (!model || !view) {
|
return true;
|
}
|
|
const cptQuery = query.cptQuery;
|
const dataQuery = query.dataQuery;
|
|
return check(cptQuery, model, 'mainType')
|
&& check(cptQuery, model, 'subType')
|
&& check(cptQuery, model, 'index', 'componentIndex')
|
&& check(cptQuery, model, 'name')
|
&& check(cptQuery, model, 'id')
|
&& check(dataQuery, packedEvent, 'name')
|
&& check(dataQuery, packedEvent, 'dataIndex')
|
&& check(dataQuery, packedEvent, 'dataType')
|
&& (!view.filterForExposedEvent || view.filterForExposedEvent(
|
eventType, query.otherQuery, targetEl, packedEvent
|
));
|
|
function check(
|
query: EventQueryItem, host: any, prop: string, propOnHost?: string
|
): boolean {
|
return query[prop] == null || host[propOnHost || prop] === query[prop];
|
}
|
}
|
|
afterTrigger() {
|
// Make sure the eventInfo wont be used in next trigger.
|
this.eventInfo = null;
|
}
|
};
|