| 
/* 
 | 
* 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 { subPixelOptimize } from '../../util/graphic.js'; 
 | 
import createRenderPlanner from '../helper/createRenderPlanner.js'; 
 | 
import { parsePercent } from '../../util/number.js'; 
 | 
import { map, retrieve2 } from 'zrender/lib/core/util.js'; 
 | 
import { createFloat32Array } from '../../util/vendor.js'; 
 | 
var candlestickLayout = { 
 | 
  seriesType: 'candlestick', 
 | 
  plan: createRenderPlanner(), 
 | 
  reset: function (seriesModel) { 
 | 
    var coordSys = seriesModel.coordinateSystem; 
 | 
    var data = seriesModel.getData(); 
 | 
    var candleWidth = calculateCandleWidth(seriesModel, data); 
 | 
    var cDimIdx = 0; 
 | 
    var vDimIdx = 1; 
 | 
    var coordDims = ['x', 'y']; 
 | 
    var cDimI = data.getDimensionIndex(data.mapDimension(coordDims[cDimIdx])); 
 | 
    var vDimsI = map(data.mapDimensionsAll(coordDims[vDimIdx]), data.getDimensionIndex, data); 
 | 
    var openDimI = vDimsI[0]; 
 | 
    var closeDimI = vDimsI[1]; 
 | 
    var lowestDimI = vDimsI[2]; 
 | 
    var highestDimI = vDimsI[3]; 
 | 
    data.setLayout({ 
 | 
      candleWidth: candleWidth, 
 | 
      // The value is experimented visually. 
 | 
      isSimpleBox: candleWidth <= 1.3 
 | 
    }); 
 | 
    if (cDimI < 0 || vDimsI.length < 4) { 
 | 
      return; 
 | 
    } 
 | 
    return { 
 | 
      progress: seriesModel.pipelineContext.large ? largeProgress : normalProgress 
 | 
    }; 
 | 
    function normalProgress(params, data) { 
 | 
      var dataIndex; 
 | 
      var store = data.getStore(); 
 | 
      while ((dataIndex = params.next()) != null) { 
 | 
        var axisDimVal = store.get(cDimI, dataIndex); 
 | 
        var openVal = store.get(openDimI, dataIndex); 
 | 
        var closeVal = store.get(closeDimI, dataIndex); 
 | 
        var lowestVal = store.get(lowestDimI, dataIndex); 
 | 
        var highestVal = store.get(highestDimI, dataIndex); 
 | 
        var ocLow = Math.min(openVal, closeVal); 
 | 
        var ocHigh = Math.max(openVal, closeVal); 
 | 
        var ocLowPoint = getPoint(ocLow, axisDimVal); 
 | 
        var ocHighPoint = getPoint(ocHigh, axisDimVal); 
 | 
        var lowestPoint = getPoint(lowestVal, axisDimVal); 
 | 
        var highestPoint = getPoint(highestVal, axisDimVal); 
 | 
        var ends = []; 
 | 
        addBodyEnd(ends, ocHighPoint, 0); 
 | 
        addBodyEnd(ends, ocLowPoint, 1); 
 | 
        ends.push(subPixelOptimizePoint(highestPoint), subPixelOptimizePoint(ocHighPoint), subPixelOptimizePoint(lowestPoint), subPixelOptimizePoint(ocLowPoint)); 
 | 
        var itemModel = data.getItemModel(dataIndex); 
 | 
        var hasDojiColor = !!itemModel.get(['itemStyle', 'borderColorDoji']); 
 | 
        data.setItemLayout(dataIndex, { 
 | 
          sign: getSign(store, dataIndex, openVal, closeVal, closeDimI, hasDojiColor), 
 | 
          initBaseline: openVal > closeVal ? ocHighPoint[vDimIdx] : ocLowPoint[vDimIdx], 
 | 
          ends: ends, 
 | 
          brushRect: makeBrushRect(lowestVal, highestVal, axisDimVal) 
 | 
        }); 
 | 
      } 
 | 
      function getPoint(val, axisDimVal) { 
 | 
        var p = []; 
 | 
        p[cDimIdx] = axisDimVal; 
 | 
        p[vDimIdx] = val; 
 | 
        return isNaN(axisDimVal) || isNaN(val) ? [NaN, NaN] : coordSys.dataToPoint(p); 
 | 
      } 
 | 
      function addBodyEnd(ends, point, start) { 
 | 
        var point1 = point.slice(); 
 | 
        var point2 = point.slice(); 
 | 
        point1[cDimIdx] = subPixelOptimize(point1[cDimIdx] + candleWidth / 2, 1, false); 
 | 
        point2[cDimIdx] = subPixelOptimize(point2[cDimIdx] - candleWidth / 2, 1, true); 
 | 
        start ? ends.push(point1, point2) : ends.push(point2, point1); 
 | 
      } 
 | 
      function makeBrushRect(lowestVal, highestVal, axisDimVal) { 
 | 
        var pmin = getPoint(lowestVal, axisDimVal); 
 | 
        var pmax = getPoint(highestVal, axisDimVal); 
 | 
        pmin[cDimIdx] -= candleWidth / 2; 
 | 
        pmax[cDimIdx] -= candleWidth / 2; 
 | 
        return { 
 | 
          x: pmin[0], 
 | 
          y: pmin[1], 
 | 
          width: vDimIdx ? candleWidth : pmax[0] - pmin[0], 
 | 
          height: vDimIdx ? pmax[1] - pmin[1] : candleWidth 
 | 
        }; 
 | 
      } 
 | 
      function subPixelOptimizePoint(point) { 
 | 
        point[cDimIdx] = subPixelOptimize(point[cDimIdx], 1); 
 | 
        return point; 
 | 
      } 
 | 
    } 
 | 
    function largeProgress(params, data) { 
 | 
      // Structure: [sign, x, yhigh, ylow, sign, x, yhigh, ylow, ...] 
 | 
      var points = createFloat32Array(params.count * 4); 
 | 
      var offset = 0; 
 | 
      var point; 
 | 
      var tmpIn = []; 
 | 
      var tmpOut = []; 
 | 
      var dataIndex; 
 | 
      var store = data.getStore(); 
 | 
      var hasDojiColor = !!seriesModel.get(['itemStyle', 'borderColorDoji']); 
 | 
      while ((dataIndex = params.next()) != null) { 
 | 
        var axisDimVal = store.get(cDimI, dataIndex); 
 | 
        var openVal = store.get(openDimI, dataIndex); 
 | 
        var closeVal = store.get(closeDimI, dataIndex); 
 | 
        var lowestVal = store.get(lowestDimI, dataIndex); 
 | 
        var highestVal = store.get(highestDimI, dataIndex); 
 | 
        if (isNaN(axisDimVal) || isNaN(lowestVal) || isNaN(highestVal)) { 
 | 
          points[offset++] = NaN; 
 | 
          offset += 3; 
 | 
          continue; 
 | 
        } 
 | 
        points[offset++] = getSign(store, dataIndex, openVal, closeVal, closeDimI, hasDojiColor); 
 | 
        tmpIn[cDimIdx] = axisDimVal; 
 | 
        tmpIn[vDimIdx] = lowestVal; 
 | 
        point = coordSys.dataToPoint(tmpIn, null, tmpOut); 
 | 
        points[offset++] = point ? point[0] : NaN; 
 | 
        points[offset++] = point ? point[1] : NaN; 
 | 
        tmpIn[vDimIdx] = highestVal; 
 | 
        point = coordSys.dataToPoint(tmpIn, null, tmpOut); 
 | 
        points[offset++] = point ? point[1] : NaN; 
 | 
      } 
 | 
      data.setLayout('largePoints', points); 
 | 
    } 
 | 
  } 
 | 
}; 
 | 
/** 
 | 
 * Get the sign of a single data. 
 | 
 * 
 | 
 * @returns 0 for doji with hasDojiColor: true, 
 | 
 *          1 for positive, 
 | 
 *          -1 for negative. 
 | 
 */ 
 | 
function getSign(store, dataIndex, openVal, closeVal, closeDimI, hasDojiColor) { 
 | 
  var sign; 
 | 
  if (openVal > closeVal) { 
 | 
    sign = -1; 
 | 
  } else if (openVal < closeVal) { 
 | 
    sign = 1; 
 | 
  } else { 
 | 
    sign = hasDojiColor 
 | 
    // When doji color is set, use it instead of color/color0. 
 | 
    ? 0 : dataIndex > 0 
 | 
    // If close === open, compare with close of last record 
 | 
    ? store.get(closeDimI, dataIndex - 1) <= closeVal ? 1 : -1 
 | 
    // No record of previous, set to be positive 
 | 
    : 1; 
 | 
  } 
 | 
  return sign; 
 | 
} 
 | 
function calculateCandleWidth(seriesModel, data) { 
 | 
  var baseAxis = seriesModel.getBaseAxis(); 
 | 
  var extent; 
 | 
  var bandWidth = baseAxis.type === 'category' ? baseAxis.getBandWidth() : (extent = baseAxis.getExtent(), Math.abs(extent[1] - extent[0]) / data.count()); 
 | 
  var barMaxWidth = parsePercent(retrieve2(seriesModel.get('barMaxWidth'), bandWidth), bandWidth); 
 | 
  var barMinWidth = parsePercent(retrieve2(seriesModel.get('barMinWidth'), 1), bandWidth); 
 | 
  var barWidth = seriesModel.get('barWidth'); 
 | 
  return barWidth != null ? parsePercent(barWidth, bandWidth) 
 | 
  // Put max outer to ensure bar visible in spite of overlap. 
 | 
  : Math.max(Math.min(bandWidth / 2, barMaxWidth), barMinWidth); 
 | 
} 
 | 
export default candlestickLayout; 
 |