Files
XCharts/Runtime/Internal/CoordinateChart_DrawCandlestick.cs
2021-06-05 09:56:40 +08:00

146 lines
7.2 KiB
C#

/************************************************/
/* */
/* Copyright (c) 2018 - 2021 monitor1394 */
/* https://github.com/monitor1394 */
/* */
/************************************************/
using UnityEngine;
using UnityEngine.UI;
using XUGL;
namespace XCharts
{
public partial class CoordinateChart
{
protected void DrawCandlestickSerie(VertexHelper vh, int colorIndex, Serie serie)
{
if (!IsActive(serie.index)) return;
if (serie.animation.HasFadeOut()) return;
var showData = serie.GetDataList(dataZoom);
var yAxis = m_YAxes[serie.yAxisIndex];
var xAxis = m_XAxes[serie.xAxisIndex];
var grid = GetSerieGridOrDefault(serie);
float categoryWidth = AxisHelper.GetDataWidth(xAxis, grid.runtimeWidth, showData.Count, dataZoom);
float barWidth = serie.GetBarWidth(categoryWidth);
float space = (categoryWidth - barWidth) / 2;
int maxCount = serie.maxShow > 0
? (serie.maxShow > showData.Count ? showData.Count : serie.maxShow)
: showData.Count;
bool dataChanging = false;
float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
float yMinValue = yAxis.GetCurrMinValue(dataChangeDuration);
float yMaxValue = yAxis.GetCurrMaxValue(dataChangeDuration);
var isAllBarEnd = true;
var isYAxis = false;
for (int i = serie.minShow; i < maxCount; i++)
{
var serieData = showData[i];
if (serie.IsIgnoreValue(serieData))
{
serie.dataPoints.Add(Vector3.zero);
continue;
}
var highlight = (tooltip.show && tooltip.IsSelected(i))
|| serie.data[i].highlighted
|| serie.highlighted;
var itemStyle = SerieHelper.GetItemStyle(serie, serieData, highlight);
var open = serieData.GetCurrData(0, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue);
var close = serieData.GetCurrData(1, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue);
var lowest = serieData.GetCurrData(2, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue);
var heighest = serieData.GetCurrData(3, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue);
var isRise = yAxis.inverse ? close < open : close > open;
var borderWidth = open == 0 ? 0f
: (itemStyle.runtimeBorderWidth == 0 ? m_Theme.serie.candlestickBorderWidth
: itemStyle.runtimeBorderWidth);
if (serieData.IsDataChanged()) dataChanging = true;
float pX = grid.runtimeX + i * categoryWidth;
float zeroY = grid.runtimeY + yAxis.runtimeZeroYOffset;
if (!xAxis.boundaryGap) pX -= categoryWidth / 2;
float pY = zeroY;
var barHig = 0f;
double valueTotal = yMaxValue - yMinValue;
var minCut = (yMinValue > 0 ? yMinValue : 0);
if (valueTotal != 0)
{
barHig = (float)((close - open) / valueTotal * grid.runtimeHeight);
pY += (float)((open - minCut) / valueTotal * grid.runtimeHeight);
}
serieData.runtimeStackHig = barHig;
var isBarEnd = false;
float currHig = Internal_CheckBarAnimation(serie, i, barHig, out isBarEnd);
if (!isBarEnd) isAllBarEnd = false;
Vector3 plb, plt, prt, prb, top;
plb = new Vector3(pX + space + borderWidth, pY + borderWidth);
plt = new Vector3(pX + space + borderWidth, pY + currHig - borderWidth);
prt = new Vector3(pX + space + barWidth - borderWidth, pY + currHig - borderWidth);
prb = new Vector3(pX + space + barWidth - borderWidth, pY + borderWidth);
top = new Vector3(pX + space + barWidth / 2, pY + currHig - borderWidth);
if (serie.clip)
{
plb = ClampInGrid(grid, plb);
plt = ClampInGrid(grid, plt);
prt = ClampInGrid(grid, prt);
prb = ClampInGrid(grid, prb);
top = ClampInGrid(grid, top);
}
serie.dataPoints.Add(top);
var areaColor = isRise
? itemStyle.GetColor(m_Theme.serie.candlestickColor)
: itemStyle.GetColor0(m_Theme.serie.candlestickColor0);
var borderColor = isRise
? itemStyle.GetBorderColor(m_Theme.serie.candlestickBorderColor)
: itemStyle.GetBorderColor0(m_Theme.serie.candlestickBorderColor0);
var itemWidth = Mathf.Abs(prt.x - plb.x);
var itemHeight = Mathf.Abs(plt.y - prb.y);
var center = new Vector3((plb.x + prt.x) / 2, (plt.y + prb.y) / 2);
var lowPos = new Vector3(center.x, zeroY + (float)((lowest - minCut) / valueTotal * grid.runtimeHeight));
var heighPos = new Vector3(center.x, zeroY + (float)((heighest - minCut) / valueTotal * grid.runtimeHeight));
var openCenterPos = new Vector3(center.x, prb.y);
var closeCenterPos = new Vector3(center.x, prt.y);
if (barWidth > 2f * borderWidth)
{
if (itemWidth > 0 && itemHeight > 0)
{
if (ItemStyleHelper.IsNeedCorner(itemStyle))
{
UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaColor, 0,
itemStyle.cornerRadius, isYAxis, 0.5f);
}
else
{
Internal_CheckClipAndDrawPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaColor,
serie.clip, grid);
}
UGL.DrawBorder(vh, center, itemWidth, itemHeight, 2 * borderWidth, borderColor, 0,
itemStyle.cornerRadius, isYAxis, 0.5f);
}
}
else
{
UGL.DrawLine(vh, openCenterPos, closeCenterPos, Mathf.Max(borderWidth, barWidth / 2), borderColor);
}
if (isRise)
{
UGL.DrawLine(vh, openCenterPos, lowPos, borderWidth, borderColor);
UGL.DrawLine(vh, closeCenterPos, heighPos, borderWidth, borderColor);
}
else
{
UGL.DrawLine(vh, closeCenterPos, lowPos, borderWidth, borderColor);
UGL.DrawLine(vh, openCenterPos, heighPos, borderWidth, borderColor);
}
}
if (isAllBarEnd)
{
serie.animation.AllBarEnd();
}
if (dataChanging)
{
RefreshPainter(serie);
}
}
}
}