| 
/* 
 | 
* 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. 
 | 
*/ 
 | 
  
 | 
  
 | 
/** 
 | 
 * AUTO-GENERATED FILE. DO NOT MODIFY. 
 | 
 */ 
 | 
  
 | 
/* 
 | 
* 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 { makeInner } from '../../util/model.js'; 
 | 
import * as modelHelper from './modelHelper.js'; 
 | 
import findPointFromSeries from './findPointFromSeries.js'; 
 | 
import { each, curry, bind, extend } from 'zrender/lib/core/util.js'; 
 | 
var inner = makeInner(); 
 | 
/** 
 | 
 * Basic logic: check all axis, if they do not demand show/highlight, 
 | 
 * then hide/downplay them. 
 | 
 * 
 | 
 * @return content of event obj for echarts.connect. 
 | 
 */ 
 | 
export default function axisTrigger(payload, ecModel, api) { 
 | 
  var currTrigger = payload.currTrigger; 
 | 
  var point = [payload.x, payload.y]; 
 | 
  var finder = payload; 
 | 
  var dispatchAction = payload.dispatchAction || bind(api.dispatchAction, api); 
 | 
  var coordSysAxesInfo = ecModel.getComponent('axisPointer').coordSysAxesInfo; 
 | 
  // Pending 
 | 
  // See #6121. But we are not able to reproduce it yet. 
 | 
  if (!coordSysAxesInfo) { 
 | 
    return; 
 | 
  } 
 | 
  if (illegalPoint(point)) { 
 | 
    // Used in the default behavior of `connection`: use the sample seriesIndex 
 | 
    // and dataIndex. And also used in the tooltipView trigger. 
 | 
    point = findPointFromSeries({ 
 | 
      seriesIndex: finder.seriesIndex, 
 | 
      // Do not use dataIndexInside from other ec instance. 
 | 
      // FIXME: auto detect it? 
 | 
      dataIndex: finder.dataIndex 
 | 
    }, ecModel).point; 
 | 
  } 
 | 
  var isIllegalPoint = illegalPoint(point); 
 | 
  // Axis and value can be specified when calling dispatchAction({type: 'updateAxisPointer'}). 
 | 
  // Notice: In this case, it is difficult to get the `point` (which is necessary to show 
 | 
  // tooltip, so if point is not given, we just use the point found by sample seriesIndex 
 | 
  // and dataIndex. 
 | 
  var inputAxesInfo = finder.axesInfo; 
 | 
  var axesInfo = coordSysAxesInfo.axesInfo; 
 | 
  var shouldHide = currTrigger === 'leave' || illegalPoint(point); 
 | 
  var outputPayload = {}; 
 | 
  var showValueMap = {}; 
 | 
  var dataByCoordSys = { 
 | 
    list: [], 
 | 
    map: {} 
 | 
  }; 
 | 
  var updaters = { 
 | 
    showPointer: curry(showPointer, showValueMap), 
 | 
    showTooltip: curry(showTooltip, dataByCoordSys) 
 | 
  }; 
 | 
  // Process for triggered axes. 
 | 
  each(coordSysAxesInfo.coordSysMap, function (coordSys, coordSysKey) { 
 | 
    // If a point given, it must be contained by the coordinate system. 
 | 
    var coordSysContainsPoint = isIllegalPoint || coordSys.containPoint(point); 
 | 
    each(coordSysAxesInfo.coordSysAxesInfo[coordSysKey], function (axisInfo, key) { 
 | 
      var axis = axisInfo.axis; 
 | 
      var inputAxisInfo = findInputAxisInfo(inputAxesInfo, axisInfo); 
 | 
      // If no inputAxesInfo, no axis is restricted. 
 | 
      if (!shouldHide && coordSysContainsPoint && (!inputAxesInfo || inputAxisInfo)) { 
 | 
        var val = inputAxisInfo && inputAxisInfo.value; 
 | 
        if (val == null && !isIllegalPoint) { 
 | 
          val = axis.pointToData(point); 
 | 
        } 
 | 
        val != null && processOnAxis(axisInfo, val, updaters, false, outputPayload); 
 | 
      } 
 | 
    }); 
 | 
  }); 
 | 
  // Process for linked axes. 
 | 
  var linkTriggers = {}; 
 | 
  each(axesInfo, function (tarAxisInfo, tarKey) { 
 | 
    var linkGroup = tarAxisInfo.linkGroup; 
 | 
    // If axis has been triggered in the previous stage, it should not be triggered by link. 
 | 
    if (linkGroup && !showValueMap[tarKey]) { 
 | 
      each(linkGroup.axesInfo, function (srcAxisInfo, srcKey) { 
 | 
        var srcValItem = showValueMap[srcKey]; 
 | 
        // If srcValItem exist, source axis is triggered, so link to target axis. 
 | 
        if (srcAxisInfo !== tarAxisInfo && srcValItem) { 
 | 
          var val = srcValItem.value; 
 | 
          linkGroup.mapper && (val = tarAxisInfo.axis.scale.parse(linkGroup.mapper(val, makeMapperParam(srcAxisInfo), makeMapperParam(tarAxisInfo)))); 
 | 
          linkTriggers[tarAxisInfo.key] = val; 
 | 
        } 
 | 
      }); 
 | 
    } 
 | 
  }); 
 | 
  each(linkTriggers, function (val, tarKey) { 
 | 
    processOnAxis(axesInfo[tarKey], val, updaters, true, outputPayload); 
 | 
  }); 
 | 
  updateModelActually(showValueMap, axesInfo, outputPayload); 
 | 
  dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction); 
 | 
  dispatchHighDownActually(axesInfo, dispatchAction, api); 
 | 
  return outputPayload; 
 | 
} 
 | 
function processOnAxis(axisInfo, newValue, updaters, noSnap, outputFinder) { 
 | 
  var axis = axisInfo.axis; 
 | 
  if (axis.scale.isBlank() || !axis.containData(newValue)) { 
 | 
    return; 
 | 
  } 
 | 
  if (!axisInfo.involveSeries) { 
 | 
    updaters.showPointer(axisInfo, newValue); 
 | 
    return; 
 | 
  } 
 | 
  // Heavy calculation. So put it after axis.containData checking. 
 | 
  var payloadInfo = buildPayloadsBySeries(newValue, axisInfo); 
 | 
  var payloadBatch = payloadInfo.payloadBatch; 
 | 
  var snapToValue = payloadInfo.snapToValue; 
 | 
  // Fill content of event obj for echarts.connect. 
 | 
  // By default use the first involved series data as a sample to connect. 
 | 
  if (payloadBatch[0] && outputFinder.seriesIndex == null) { 
 | 
    extend(outputFinder, payloadBatch[0]); 
 | 
  } 
 | 
  // If no linkSource input, this process is for collecting link 
 | 
  // target, where snap should not be accepted. 
 | 
  if (!noSnap && axisInfo.snap) { 
 | 
    if (axis.containData(snapToValue) && snapToValue != null) { 
 | 
      newValue = snapToValue; 
 | 
    } 
 | 
  } 
 | 
  updaters.showPointer(axisInfo, newValue, payloadBatch); 
 | 
  // Tooltip should always be snapToValue, otherwise there will be 
 | 
  // incorrect "axis value ~ series value" mapping displayed in tooltip. 
 | 
  updaters.showTooltip(axisInfo, payloadInfo, snapToValue); 
 | 
} 
 | 
function buildPayloadsBySeries(value, axisInfo) { 
 | 
  var axis = axisInfo.axis; 
 | 
  var dim = axis.dim; 
 | 
  var snapToValue = value; 
 | 
  var payloadBatch = []; 
 | 
  var minDist = Number.MAX_VALUE; 
 | 
  var minDiff = -1; 
 | 
  each(axisInfo.seriesModels, function (series, idx) { 
 | 
    var dataDim = series.getData().mapDimensionsAll(dim); 
 | 
    var seriesNestestValue; 
 | 
    var dataIndices; 
 | 
    if (series.getAxisTooltipData) { 
 | 
      var result = series.getAxisTooltipData(dataDim, value, axis); 
 | 
      dataIndices = result.dataIndices; 
 | 
      seriesNestestValue = result.nestestValue; 
 | 
    } else { 
 | 
      dataIndices = series.getData().indicesOfNearest(dataDim[0], value, 
 | 
      // Add a threshold to avoid find the wrong dataIndex 
 | 
      // when data length is not same. 
 | 
      // false, 
 | 
      axis.type === 'category' ? 0.5 : null); 
 | 
      if (!dataIndices.length) { 
 | 
        return; 
 | 
      } 
 | 
      seriesNestestValue = series.getData().get(dataDim[0], dataIndices[0]); 
 | 
    } 
 | 
    if (seriesNestestValue == null || !isFinite(seriesNestestValue)) { 
 | 
      return; 
 | 
    } 
 | 
    var diff = value - seriesNestestValue; 
 | 
    var dist = Math.abs(diff); 
 | 
    // Consider category case 
 | 
    if (dist <= minDist) { 
 | 
      if (dist < minDist || diff >= 0 && minDiff < 0) { 
 | 
        minDist = dist; 
 | 
        minDiff = diff; 
 | 
        snapToValue = seriesNestestValue; 
 | 
        payloadBatch.length = 0; 
 | 
      } 
 | 
      each(dataIndices, function (dataIndex) { 
 | 
        payloadBatch.push({ 
 | 
          seriesIndex: series.seriesIndex, 
 | 
          dataIndexInside: dataIndex, 
 | 
          dataIndex: series.getData().getRawIndex(dataIndex) 
 | 
        }); 
 | 
      }); 
 | 
    } 
 | 
  }); 
 | 
  return { 
 | 
    payloadBatch: payloadBatch, 
 | 
    snapToValue: snapToValue 
 | 
  }; 
 | 
} 
 | 
function showPointer(showValueMap, axisInfo, value, payloadBatch) { 
 | 
  showValueMap[axisInfo.key] = { 
 | 
    value: value, 
 | 
    payloadBatch: payloadBatch 
 | 
  }; 
 | 
} 
 | 
function showTooltip(dataByCoordSys, axisInfo, payloadInfo, value) { 
 | 
  var payloadBatch = payloadInfo.payloadBatch; 
 | 
  var axis = axisInfo.axis; 
 | 
  var axisModel = axis.model; 
 | 
  var axisPointerModel = axisInfo.axisPointerModel; 
 | 
  // If no data, do not create anything in dataByCoordSys, 
 | 
  // whose length will be used to judge whether dispatch action. 
 | 
  if (!axisInfo.triggerTooltip || !payloadBatch.length) { 
 | 
    return; 
 | 
  } 
 | 
  var coordSysModel = axisInfo.coordSys.model; 
 | 
  var coordSysKey = modelHelper.makeKey(coordSysModel); 
 | 
  var coordSysItem = dataByCoordSys.map[coordSysKey]; 
 | 
  if (!coordSysItem) { 
 | 
    coordSysItem = dataByCoordSys.map[coordSysKey] = { 
 | 
      coordSysId: coordSysModel.id, 
 | 
      coordSysIndex: coordSysModel.componentIndex, 
 | 
      coordSysType: coordSysModel.type, 
 | 
      coordSysMainType: coordSysModel.mainType, 
 | 
      dataByAxis: [] 
 | 
    }; 
 | 
    dataByCoordSys.list.push(coordSysItem); 
 | 
  } 
 | 
  coordSysItem.dataByAxis.push({ 
 | 
    axisDim: axis.dim, 
 | 
    axisIndex: axisModel.componentIndex, 
 | 
    axisType: axisModel.type, 
 | 
    axisId: axisModel.id, 
 | 
    value: value, 
 | 
    // Caustion: viewHelper.getValueLabel is actually on "view stage", which 
 | 
    // depends that all models have been updated. So it should not be performed 
 | 
    // here. Considering axisPointerModel used here is volatile, which is hard 
 | 
    // to be retrieve in TooltipView, we prepare parameters here. 
 | 
    valueLabelOpt: { 
 | 
      precision: axisPointerModel.get(['label', 'precision']), 
 | 
      formatter: axisPointerModel.get(['label', 'formatter']) 
 | 
    }, 
 | 
    seriesDataIndices: payloadBatch.slice() 
 | 
  }); 
 | 
} 
 | 
function updateModelActually(showValueMap, axesInfo, outputPayload) { 
 | 
  var outputAxesInfo = outputPayload.axesInfo = []; 
 | 
  // Basic logic: If no 'show' required, 'hide' this axisPointer. 
 | 
  each(axesInfo, function (axisInfo, key) { 
 | 
    var option = axisInfo.axisPointerModel.option; 
 | 
    var valItem = showValueMap[key]; 
 | 
    if (valItem) { 
 | 
      !axisInfo.useHandle && (option.status = 'show'); 
 | 
      option.value = valItem.value; 
 | 
      // For label formatter param and highlight. 
 | 
      option.seriesDataIndices = (valItem.payloadBatch || []).slice(); 
 | 
    } 
 | 
    // When always show (e.g., handle used), remain 
 | 
    // original value and status. 
 | 
    else { 
 | 
      // If hide, value still need to be set, consider 
 | 
      // click legend to toggle axis blank. 
 | 
      !axisInfo.useHandle && (option.status = 'hide'); 
 | 
    } 
 | 
    // If status is 'hide', should be no info in payload. 
 | 
    option.status === 'show' && outputAxesInfo.push({ 
 | 
      axisDim: axisInfo.axis.dim, 
 | 
      axisIndex: axisInfo.axis.model.componentIndex, 
 | 
      value: option.value 
 | 
    }); 
 | 
  }); 
 | 
} 
 | 
function dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction) { 
 | 
  // Basic logic: If no showTip required, hideTip will be dispatched. 
 | 
  if (illegalPoint(point) || !dataByCoordSys.list.length) { 
 | 
    dispatchAction({ 
 | 
      type: 'hideTip' 
 | 
    }); 
 | 
    return; 
 | 
  } 
 | 
  // In most case only one axis (or event one series is used). It is 
 | 
  // convenient to fetch payload.seriesIndex and payload.dataIndex 
 | 
  // directly. So put the first seriesIndex and dataIndex of the first 
 | 
  // axis on the payload. 
 | 
  var sampleItem = ((dataByCoordSys.list[0].dataByAxis[0] || {}).seriesDataIndices || [])[0] || {}; 
 | 
  dispatchAction({ 
 | 
    type: 'showTip', 
 | 
    escapeConnect: true, 
 | 
    x: point[0], 
 | 
    y: point[1], 
 | 
    tooltipOption: payload.tooltipOption, 
 | 
    position: payload.position, 
 | 
    dataIndexInside: sampleItem.dataIndexInside, 
 | 
    dataIndex: sampleItem.dataIndex, 
 | 
    seriesIndex: sampleItem.seriesIndex, 
 | 
    dataByCoordSys: dataByCoordSys.list 
 | 
  }); 
 | 
} 
 | 
function dispatchHighDownActually(axesInfo, dispatchAction, api) { 
 | 
  // FIXME 
 | 
  // highlight status modification should be a stage of main process? 
 | 
  // (Consider confilct (e.g., legend and axisPointer) and setOption) 
 | 
  var zr = api.getZr(); 
 | 
  var highDownKey = 'axisPointerLastHighlights'; 
 | 
  var lastHighlights = inner(zr)[highDownKey] || {}; 
 | 
  var newHighlights = inner(zr)[highDownKey] = {}; 
 | 
  // Update highlight/downplay status according to axisPointer model. 
 | 
  // Build hash map and remove duplicate incidentally. 
 | 
  each(axesInfo, function (axisInfo, key) { 
 | 
    var option = axisInfo.axisPointerModel.option; 
 | 
    option.status === 'show' && axisInfo.triggerEmphasis && each(option.seriesDataIndices, function (batchItem) { 
 | 
      var key = batchItem.seriesIndex + ' | ' + batchItem.dataIndex; 
 | 
      newHighlights[key] = batchItem; 
 | 
    }); 
 | 
  }); 
 | 
  // Diff. 
 | 
  var toHighlight = []; 
 | 
  var toDownplay = []; 
 | 
  each(lastHighlights, function (batchItem, key) { 
 | 
    !newHighlights[key] && toDownplay.push(batchItem); 
 | 
  }); 
 | 
  each(newHighlights, function (batchItem, key) { 
 | 
    !lastHighlights[key] && toHighlight.push(batchItem); 
 | 
  }); 
 | 
  toDownplay.length && api.dispatchAction({ 
 | 
    type: 'downplay', 
 | 
    escapeConnect: true, 
 | 
    // Not blur others when highlight in axisPointer. 
 | 
    notBlur: true, 
 | 
    batch: toDownplay 
 | 
  }); 
 | 
  toHighlight.length && api.dispatchAction({ 
 | 
    type: 'highlight', 
 | 
    escapeConnect: true, 
 | 
    // Not blur others when highlight in axisPointer. 
 | 
    notBlur: true, 
 | 
    batch: toHighlight 
 | 
  }); 
 | 
} 
 | 
function findInputAxisInfo(inputAxesInfo, axisInfo) { 
 | 
  for (var i = 0; i < (inputAxesInfo || []).length; i++) { 
 | 
    var inputAxisInfo = inputAxesInfo[i]; 
 | 
    if (axisInfo.axis.dim === inputAxisInfo.axisDim && axisInfo.axis.model.componentIndex === inputAxisInfo.axisIndex) { 
 | 
      return inputAxisInfo; 
 | 
    } 
 | 
  } 
 | 
} 
 | 
function makeMapperParam(axisInfo) { 
 | 
  var axisModel = axisInfo.axis.model; 
 | 
  var item = {}; 
 | 
  var dim = item.axisDim = axisInfo.axis.dim; 
 | 
  item.axisIndex = item[dim + 'AxisIndex'] = axisModel.componentIndex; 
 | 
  item.axisName = item[dim + 'AxisName'] = axisModel.name; 
 | 
  item.axisId = item[dim + 'AxisId'] = axisModel.id; 
 | 
  return item; 
 | 
} 
 | 
function illegalPoint(point) { 
 | 
  return !point || point[0] == null || isNaN(point[0]) || point[1] == null || isNaN(point[1]); 
 | 
} 
 |