|   | 
| /* | 
| * 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)); | 
|         data.setItemLayout(dataIndex, { | 
|           sign: getSign(store, dataIndex, openVal, closeVal, closeDimI), | 
|           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(); | 
|   | 
|       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); | 
|         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); | 
|     } | 
|   } | 
| }; | 
|   | 
| function getSign(store, dataIndex, openVal, closeVal, closeDimI) { | 
|   var sign; | 
|   | 
|   if (openVal > closeVal) { | 
|     sign = -1; | 
|   } else if (openVal < closeVal) { | 
|     sign = 1; | 
|   } else { | 
|     sign = 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; |