1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072 |
- using System;
- using UnityEngine;
- using UnityEngine.UI;
- using XCharts.Runtime;
- using XUGL;
- namespace XCharts
- {
- public abstract class AxisHandler<T> : MainComponentHandler
- where T : Axis
- {
- private static readonly string s_DefaultAxisName = "name";
- private double m_LastInterval = double.MinValue;
- private int m_LastSplitNumber = int.MinValue;
- public T component { get; internal set; }
- internal override void SetComponent(MainComponent component)
- {
- this.component = (T)component;
- }
- protected virtual Vector3 GetLabelPosition(float scaleWid, int i)
- {
- return Vector3.zero;
- }
- internal virtual float GetAxisLineXOrY()
- {
- return 0;
- }
- protected virtual Orient orient { get; set; }
- protected virtual void UpdatePointerValue(Axis axis)
- {
- var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
- if (grid == null)
- return;
- if (!grid.context.isPointerEnter)
- {
- axis.context.pointerValue = double.PositiveInfinity;
- }
- else
- {
- var lastPointerValue = axis.context.pointerValue;
- if (axis.IsCategory())
- {
- var dataZoom = chart.GetDataZoomOfAxis(axis);
- var dataCount = chart.series.Count > 0 ? chart.series[0].GetDataList(dataZoom).Count : 0;
- var local = chart.pointerPos;
- if (axis is YAxis)
- {
- float splitWid = AxisHelper.GetDataWidth(axis, grid.context.height, dataCount, dataZoom);
- for (int j = 0; j < axis.GetDataCount(dataZoom); j++)
- {
- float pY = grid.context.y + j * splitWid;
- if ((axis.boundaryGap && (local.y > pY && local.y <= pY + splitWid)) ||
- (!axis.boundaryGap && (local.y > pY - splitWid / 2 && local.y <= pY + splitWid / 2)))
- {
- axis.context.pointerValue = j;
- axis.context.pointerLabelPosition = axis.GetLabelObjectPosition(j);
- if (j != lastPointerValue)
- {
- if (chart.onAxisPointerValueChanged != null)
- chart.onAxisPointerValueChanged(axis, j);
- }
- break;
- }
- }
- }
- else
- {
- float splitWid = AxisHelper.GetDataWidth(axis, grid.context.width, dataCount, dataZoom);
- for (int j = 0; j < axis.GetDataCount(dataZoom); j++)
- {
- float pX = grid.context.x + j * splitWid;
- if ((axis.boundaryGap && (local.x > pX && local.x <= pX + splitWid)) ||
- (!axis.boundaryGap && (local.x > pX - splitWid / 2 && local.x <= pX + splitWid / 2)))
- {
- axis.context.pointerValue = j;
- axis.context.pointerLabelPosition = axis.GetLabelObjectPosition(j);
- if (j != lastPointerValue)
- {
- if (chart.onAxisPointerValueChanged != null)
- chart.onAxisPointerValueChanged(axis, j);
- }
- break;
- }
- }
- }
- }
- else
- {
- if (axis is YAxis)
- {
- var yRate = axis.context.minMaxRange / grid.context.height;
- var yValue = yRate * (chart.pointerPos.y - grid.context.y - axis.context.offset);
- if (axis.context.minValue > 0)
- yValue += axis.context.minValue;
- var labelX = axis.GetLabelObjectPosition(0).x;
- axis.context.pointerValue = yValue;
- axis.context.pointerLabelPosition = new Vector3(labelX, chart.pointerPos.y);
- if (yValue != lastPointerValue)
- {
- if (chart.onAxisPointerValueChanged != null)
- chart.onAxisPointerValueChanged(axis, yValue);
- }
- }
- else
- {
- double xValue;
- if (axis.IsLog())
- {
- var logBase = axis.logBase;
- var minLog = Math.Log(axis.context.minValue, logBase);
- var maxLog = Math.Log(axis.context.maxValue, logBase);
- var logRange = maxLog - minLog;
- var pointerLog = minLog + logRange * (chart.pointerPos.x - grid.context.x - axis.context.offset) / grid.context.width;
- xValue = Math.Pow(logBase, pointerLog);
- }
- else
- {
- var xRate = axis.context.minMaxRange / grid.context.width;
- xValue = xRate * (chart.pointerPos.x - grid.context.x - axis.context.offset);
- if (axis.context.minValue > 0)
- xValue += axis.context.minValue;
- }
- var labelY = axis.GetLabelObjectPosition(0).y;
- axis.context.pointerValue = xValue;
- axis.context.pointerLabelPosition = new Vector3(chart.pointerPos.x, labelY);
- if (xValue != lastPointerValue)
- {
- if (chart.onAxisPointerValueChanged != null)
- chart.onAxisPointerValueChanged(axis, xValue);
- }
- }
- }
- }
- }
- internal void UpdateAxisMinMaxValue(int axisIndex, Axis axis, bool updateChart = true)
- {
- if (!axis.show)
- return;
- if (axis.IsCategory())
- {
- axis.context.minValue = 0;
- axis.context.maxValue = SeriesHelper.GetMaxSerieDataCount(chart.series) - 1;
- axis.context.minMaxRange = axis.context.maxValue;
- return;
- }
- double tempMinValue;
- double tempMaxValue;
- axis.context.needAnimation = Application.isPlaying && axis.animation.show;
- chart.GetSeriesMinMaxValue(axis, axisIndex, out tempMinValue, out tempMaxValue);
- var dataZoom = chart.GetDataZoomOfAxis(axis);
- if (dataZoom != null && dataZoom.enable)
- {
- if (axis is XAxis)
- dataZoom.SetXAxisIndexValueInfo(axisIndex, ref tempMinValue, ref tempMaxValue);
- else
- dataZoom.SetYAxisIndexValueInfo(axisIndex, ref tempMinValue, ref tempMaxValue);
- }
- if (tempMinValue != axis.context.destMinValue ||
- tempMaxValue != axis.context.destMaxValue ||
- m_LastInterval != axis.interval ||
- m_LastSplitNumber != axis.splitNumber)
- {
- m_LastSplitNumber = axis.splitNumber;
- m_LastInterval = axis.interval;
- axis.UpdateMinMaxValue(tempMinValue, tempMaxValue, axis.context.needAnimation);
- axis.context.offset = 0;
- axis.context.lastCheckInverse = axis.inverse;
- UpdateAxisTickValueList(axis);
- if (tempMinValue != 0 || tempMaxValue != 0)
- {
- var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
- if (grid != null && axis is XAxis && axis.IsValue())
- {
- axis.UpdateZeroOffset(grid.context.width);
- }
- if (grid != null && axis is YAxis && axis.IsValue())
- {
- axis.UpdateZeroOffset(grid.context.height);
- }
- }
- if (updateChart)
- {
- UpdateAxisLabelText(axis);
- chart.RefreshChart();
- }
- }
- if (axis.context.needAnimation && (axis.context.minValue != axis.context.destMinValue || axis.context.maxValue != axis.context.destMaxValue))
- {
- var duration = axis.animation.duration == 0
- ? SeriesHelper.GetMinAnimationDuration(chart.series) / 1000f
- : axis.animation.duration / 1000f;
- var deltaTime = axis.animation.unscaledTime ? Time.unscaledDeltaTime : Time.deltaTime;
- var minDiff = axis.context.destMinValue - axis.context.lastMinValue;
- var maxDiff = axis.context.destMaxValue - axis.context.lastMaxValue;
- var minDelta = minDiff / duration * deltaTime;
- var maxDelta = maxDiff / duration * deltaTime;
- axis.context.minValue += minDelta;
- axis.context.maxValue += maxDelta;
- if ((minDiff > 0 && axis.context.minValue > axis.context.destMinValue)
- || (minDiff < 0 && axis.context.minValue < axis.context.destMinValue))
- {
- axis.context.minValue = axis.context.destMinValue;
- axis.context.lastMinValue = axis.context.destMinValue;
- }
- if ((maxDiff > 0 && axis.context.maxValue > axis.context.destMaxValue)
- || (maxDiff < 0 && axis.context.maxValue < axis.context.destMaxValue))
- {
- axis.context.maxValue = axis.context.destMaxValue;
- axis.context.lastMaxValue = axis.context.destMaxValue;
- }
- axis.context.minMaxRange = axis.context.maxValue - axis.context.minValue;
- UpdateAxisTickValueList(axis);
- UpdateAxisLabelText(axis);
- chart.RefreshChart();
- }
- }
- internal virtual void UpdateAxisLabelText(Axis axis)
- {
- var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
- if (grid == null || axis == null)
- return;
- float runtimeWidth = axis is XAxis ? grid.context.width : grid.context.height;
- var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series);
- var dataZoom = chart.GetDataZoomOfAxis(axis);
- axis.UpdateLabelText(runtimeWidth, dataZoom, isPercentStack);
- }
- internal void UpdateAxisTickValueList(Axis axis)
- {
- if (axis.IsTime())
- {
- var lastCount = axis.context.labelValueList.Count;
- axis.context.tickValue = DateTimeUtil.UpdateTimeAxisDateTimeList(axis.context.labelValueList,
- (int)axis.context.minValue, (int)axis.context.maxValue, axis.splitNumber);
- if (axis.context.labelValueList.Count != lastCount)
- axis.SetAllDirty();
- }
- else if (axis.IsValue())
- {
- var list = axis.context.labelValueList;
- var lastCount = list.Count;
- list.Clear();
- var range = axis.context.maxValue - axis.context.minValue;
- if (range <= 0)
- return;
- double tick = axis.interval;
- if (axis.interval == 0)
- {
- if (range >= double.MaxValue / 2)
- {
- tick = range / 4;
- }
- else if (axis.splitNumber > 0)
- {
- tick = range / axis.splitNumber;
- }
- else
- {
- var each = GetTick(range);
- tick = each;
- if (range / 4 % each == 0)
- tick = range / 4;
- else if (range / tick > 8)
- tick = 2 * each;
- else if (range / tick < 4)
- tick = each / 2;
- }
- }
- var value = 0d;
- axis.context.tickValue = tick;
- if (Mathf.Approximately((float)(axis.context.minValue % tick), 0))
- {
- value = axis.context.minValue;
- }
- else
- {
- list.Add(axis.context.minValue);
- value = Math.Ceiling(axis.context.minValue / tick) * tick;
- }
- var maxSplitNumber = chart.settings.axisMaxSplitNumber;
- while (value <= axis.context.maxValue)
- {
- list.Add(value);
- value += tick;
- if (maxSplitNumber > 0 && list.Count > maxSplitNumber)
- break;
- }
- if (!ChartHelper.IsEquals(axis.context.maxValue, list[list.Count - 1]))
- {
- list.Add(axis.context.maxValue);
- }
- if (lastCount != list.Count)
- {
- axis.SetAllDirty();
- }
- }
- }
- private static double GetTick(double max)
- {
- if (max <= 1) return max / 5;
- if (max > 1 && max < 10) return 1;
- var bigger = Math.Ceiling(Math.Abs(max));
- int n = 1;
- while (bigger / (Mathf.Pow(10, n)) > 10)
- {
- n++;
- }
- return Math.Pow(10, n);
- }
- internal void CheckValueLabelActive(Axis axis, int i, ChartLabel label, Vector3 pos)
- {
- if (!axis.show || !axis.axisLabel.show)
- {
- label.SetTextActive(false);
- return;
- }
- if (axis.IsValue())
- {
- if (orient == Orient.Horizonal)
- {
- if (i == 0)
- {
- var dist = GetLabelPosition(0, 1).x - pos.x;
- label.SetTextActive(axis.IsNeedShowLabel(i) && dist > label.text.GetPreferredWidth());
- }
- else if (i == axis.context.labelValueList.Count - 1)
- {
- var dist = pos.x - GetLabelPosition(0, i - 1).x;
- label.SetTextActive(axis.IsNeedShowLabel(i) && dist > label.text.GetPreferredWidth());
- }
- }
- else
- {
- if (i == 0)
- {
- var dist = GetLabelPosition(0, 1).y - pos.y;
- label.SetTextActive(axis.IsNeedShowLabel(i) && dist > label.text.GetPreferredHeight());
- }
- else if (i == axis.context.labelValueList.Count - 1)
- {
- var dist = pos.y - GetLabelPosition(0, i - 1).y;
- label.SetTextActive(axis.IsNeedShowLabel(i) && dist > label.text.GetPreferredHeight());
- }
- }
- }
- }
- protected void InitAxis(Axis relativedAxis, Orient orient,
- float axisStartX, float axisStartY, float axisLength, float relativedLength)
- {
- Axis axis = component;
- chart.InitAxisRuntimeData(axis);
- var objName = ChartCached.GetComponentObjectName(axis);
- var axisObj = ChartHelper.AddObject(objName,
- chart.transform,
- chart.chartMinAnchor,
- chart.chartMaxAnchor,
- chart.chartPivot,
- chart.chartSizeDelta);
- axisObj.SetActive(axis.show);
- axisObj.hideFlags = chart.chartHideFlags;
- ChartHelper.HideAllObject(axisObj);
- axis.gameObject = axisObj;
- axis.context.labelObjectList.Clear();
- if (!axis.show)
- return;
- var axisLabelTextStyle = axis.axisLabel.textStyle;
- var dataZoom = chart.GetDataZoomOfAxis(axis);
- var splitNumber = AxisHelper.GetScaleNumber(axis, axisLength, dataZoom);
- var totalWidth = 0f;
- var eachWidth = AxisHelper.GetEachWidth(axis, axisLength, dataZoom);
- var gapWidth = axis.boundaryGap ? eachWidth / 2 : 0;
- var textWidth = axis.axisLabel.width > 0 ?
- axis.axisLabel.width :
- (orient == Orient.Horizonal ?
- AxisHelper.GetScaleWidth(axis, axisLength, 0, dataZoom) :
- (axisStartX - chart.chartX)
- );
- var textHeight = axis.axisLabel.height > 0 ?
- axis.axisLabel.height :
- 20f;
- var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series);
- var inside = axis.axisLabel.inside;
- var defaultAlignment = orient == Orient.Horizonal ? TextAnchor.MiddleCenter :
- ((inside && axis.IsLeft()) || (!inside && axis.IsRight()) ?
- TextAnchor.MiddleLeft :
- TextAnchor.MiddleRight);
- if (axis.IsCategory() && axis.boundaryGap)
- splitNumber -= 1;
- axis.context.aligment = defaultAlignment;
- for (int i = 0; i < splitNumber; i++)
- {
- var labelWidth = AxisHelper.GetScaleWidth(axis, axisLength, i + 1, dataZoom);
- var labelName = AxisHelper.GetLabelName(axis, axisLength, i,
- axis.context.destMinValue,
- axis.context.destMaxValue,
- dataZoom, isPercentStack);
- var label = ChartHelper.AddAxisLabelObject(splitNumber, i,
- ChartCached.GetAxisLabelName(i),
- axisObj.transform,
- new Vector2(textWidth, textHeight),
- axis, chart.theme.axis, labelName,
- Color.clear,
- defaultAlignment,
- chart.theme.GetColor(i));
- if (i == 0)
- axis.axisLabel.SetRelatedText(label.text, labelWidth);
- var pos = GetLabelPosition(totalWidth + gapWidth, i);
- label.SetPosition(pos);
- CheckValueLabelActive(axis, i, label, pos);
- axis.context.labelObjectList.Add(label);
- totalWidth += labelWidth;
- }
- if (axis.axisName.show)
- {
- ChartLabel label = null;
- var relativedDist = (relativedAxis == null ? 0 : relativedAxis.context.offset);
- var zeroPos = new Vector3(axisStartX, axisStartY + relativedDist);
- var offset = axis.axisName.labelStyle.offset;
- var autoColor = axis.axisLine.GetColor(chart.theme.axis.lineColor);
- if (orient == Orient.Horizonal)
- {
- var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
- var posY = !axis.axisName.onZero && grid != null ? grid.context.y : GetAxisLineXOrY() + offset.y;
- switch (axis.axisName.labelStyle.position)
- {
- case LabelStyle.Position.Start:
- label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
- chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleRight);
- label.SetActive(axis.axisName.labelStyle.show);
- label.SetPosition(axis.position == Axis.AxisPosition.Top ?
- new Vector2(zeroPos.x - offset.x, axisStartY + relativedLength + offset.y + axis.offset) :
- new Vector2(zeroPos.x - offset.x, posY + offset.y));
- break;
- case LabelStyle.Position.Middle:
- label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
- chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
- label.SetActive(axis.axisName.labelStyle.show);
- label.SetPosition(axis.position == Axis.AxisPosition.Top ?
- new Vector2(axisStartX + axisLength / 2 + offset.x, axisStartY + relativedLength - offset.y + axis.offset) :
- new Vector2(axisStartX + axisLength / 2 + offset.x, posY + offset.y));
- break;
- default:
- label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
- chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleLeft);
- label.SetActive(axis.axisName.labelStyle.show);
- label.SetPosition(axis.position == Axis.AxisPosition.Top ?
- new Vector2(axisStartX + axisLength + offset.x, axisStartY + relativedLength + offset.y + axis.offset) :
- new Vector2(axisStartX + axisLength + offset.x, posY + offset.y));
- break;
- }
- }
- else
- {
- var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
- var posX = !axis.axisName.onZero && grid != null ? grid.context.x : GetAxisLineXOrY() + offset.x;
- switch (axis.axisName.labelStyle.position)
- {
- case LabelStyle.Position.Start:
- label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
- chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
- label.SetActive(axis.axisName.labelStyle.show);
- label.SetPosition(axis.position == Axis.AxisPosition.Right ?
- new Vector2(axisStartX + relativedLength + offset.x + axis.offset, axisStartY - offset.y) :
- new Vector2(posX + offset.x, axisStartY - offset.y));
- break;
- case LabelStyle.Position.Middle:
- label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
- chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
- label.SetActive(axis.axisName.labelStyle.show);
- label.SetPosition(axis.position == Axis.AxisPosition.Right ?
- new Vector2(axisStartX + relativedLength - offset.x + axis.offset, axisStartY + axisLength / 2 + offset.y) :
- new Vector2(posX + offset.x, axisStartY + axisLength / 2 + offset.y));
- break;
- default:
- //LabelStyle.Position
- label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
- chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
- label.SetActive(axis.axisName.labelStyle.show);
- label.SetPosition(axis.position == Axis.AxisPosition.Right ?
- new Vector2(axisStartX + relativedLength + offset.x + axis.offset, axisStartY + axisLength + offset.y) :
- new Vector2(posX + offset.x, axisStartY + axisLength + offset.y));
- break;
- }
- }
- }
- }
- internal static Vector3 GetLabelPosition(int i, Orient orient, Axis axis, Axis relativedAxis, AxisTheme theme,
- float scaleWid, float axisStartX, float axisStartY, float axisLength, float relativedLength)
- {
- var inside = axis.axisLabel.inside;
- var fontSize = axis.axisLabel.textStyle.GetFontSize(theme);
- var current = axis.offset;
- if (axis.IsTime() || axis.IsValue())
- {
- scaleWid = axis.context.minMaxRange != 0 ?
- axis.GetDistance(axis.GetLabelValue(i), axisLength) :
- 0;
- }
- if (orient == Orient.Horizonal)
- {
- if (axis.axisLabel.onZero && relativedAxis != null)
- axisStartY += relativedAxis.context.offset;
- if (axis.IsTop())
- axisStartY += relativedLength;
- if ((inside && axis.IsBottom()) || (!inside && axis.IsTop()))
- current += axisStartY + axis.axisLabel.distance + fontSize / 2;
- else
- current += axisStartY - axis.axisLabel.distance - fontSize / 2;
- return new Vector3(axisStartX + scaleWid, current) + axis.axisLabel.offset;
- }
- else
- {
- if (axis.axisLabel.onZero && relativedAxis != null)
- axisStartX += relativedAxis.context.offset;
- if (axis.IsRight())
- axisStartX += relativedLength;
- if ((inside && axis.IsLeft()) || (!inside && axis.IsRight()))
- current += axisStartX + axis.axisLabel.distance;
- else
- current += axisStartX - axis.axisLabel.distance;
- return new Vector3(current, axisStartY + scaleWid) + axis.axisLabel.offset;
- }
- }
- internal static void DrawAxisLine(VertexHelper vh, Axis axis, AxisTheme theme, Orient orient,
- float startX, float startY, float axisLength)
- {
- var inverse = axis.IsValue() && axis.inverse;
- var offset = AxisHelper.GetAxisLineArrowOffset(axis);
- var lineWidth = axis.axisLine.GetWidth(theme.lineWidth);
- var lineType = axis.axisLine.GetType(theme.lineType);
- var lineColor = axis.axisLine.GetColor(theme.lineColor);
- if (orient == Orient.Horizonal)
- {
- var left = new Vector3(startX - lineWidth - (inverse ? offset : 0), startY);
- var right = new Vector3(startX + axisLength + lineWidth + (!inverse ? offset : 0), startY);
- ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, left, right, lineColor);
- }
- else
- {
- var bottom = new Vector3(startX, startY - lineWidth - (inverse ? offset : 0));
- var top = new Vector3(startX, startY + axisLength + lineWidth + (!inverse ? offset : 0));
- ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, bottom, top, lineColor);
- }
- }
- internal static void DrawAxisTick(VertexHelper vh, Axis axis, AxisTheme theme, DataZoom dataZoom,
- Orient orient, float startX, float startY, float axisLength)
- {
- var lineWidth = axis.axisLine.GetWidth(theme.lineWidth);
- var tickLength = axis.axisTick.GetLength(theme.tickLength);
- if (AxisHelper.NeedShowSplit(axis))
- {
- var size = AxisHelper.GetScaleNumber(axis, axisLength, dataZoom);
- if (axis.IsTime())
- {
- size += 1;
- if (!ChartHelper.IsEquals(axis.GetLastLabelValue(), axis.context.maxValue))
- size += 1;
- }
- var tickWidth = axis.axisTick.GetWidth(theme.tickWidth);
- var tickColor = axis.axisTick.GetColor(theme.tickColor);
- var current = orient == Orient.Horizonal ? startX : startY;
- var maxAxisXY = current + axisLength;
- var lastTickX = current;
- var lastTickY = current;
- var minorTickSplitNumber = axis.minorTick.splitNumber <= 0 ? 5 : axis.minorTick.splitNumber;
- var minorTickDistance = axis.GetValueLength(axis.context.tickValue / minorTickSplitNumber, axisLength);
- var minorTickColor = axis.minorTick.GetColor(theme.tickColor);
- var minorTickWidth = axis.minorTick.GetWidth(theme.tickWidth);
- var minorTickLength = axis.minorTick.GetLength(theme.tickLength * 0.6f);
- var minorStartIndex = axis.IsTime() ? 0 : 1;
- var isLogAxis = axis.IsLog();
- for (int i = 0; i < size; i++)
- {
- var scaleWidth = AxisHelper.GetScaleWidth(axis, axisLength, i + 1, dataZoom);
- var hideTick = (i == 0 && (!axis.axisTick.showStartTick || axis.axisTick.alignWithLabel)) ||
- (i == size - 1 && !axis.axisTick.showEndTick);
- if (axis.axisTick.show)
- {
- if (orient == Orient.Horizonal)
- {
- float pX = axis.IsTime() ?
- (startX + axis.GetDistance(axis.GetLabelValue(i), axisLength)) :
- current;
- if (axis.boundaryGap && axis.axisTick.alignWithLabel)
- pX -= scaleWidth / 2;
- var sY = 0f;
- var eY = 0f;
- var mY = 0f;
- if ((axis.axisTick.inside && axis.IsBottom()) ||
- (!axis.axisTick.inside && axis.IsTop()))
- {
- sY = startY + lineWidth;
- eY = sY + tickLength;
- mY = sY + minorTickLength;
- }
- else
- {
- sY = startY - lineWidth;
- eY = sY - tickLength;
- mY = sY - minorTickLength;
- }
- if (!hideTick)
- UGL.DrawLine(vh, new Vector3(pX, sY), new Vector3(pX, eY), tickWidth, tickColor);
- if (axis.minorTick.show && i >= minorStartIndex && (minorTickDistance > 0 || isLogAxis))
- {
- if (isLogAxis)
- {
- var count = 0;
- var logRange = (axis.logBase - 1f);
- minorTickDistance = scaleWidth * axis.GetLogValue(1 + (count + 1) * logRange / minorTickSplitNumber);
- var tickTotal = lastTickX + minorTickDistance;
- while (tickTotal < current && count < minorTickSplitNumber - 1)
- {
- UGL.DrawLine(vh, new Vector3(tickTotal, sY), new Vector3(tickTotal, mY), minorTickWidth, minorTickColor);
- count++;
- minorTickDistance = scaleWidth * axis.GetLogValue(1 + (count + 1) * logRange / minorTickSplitNumber);
- tickTotal = lastTickX + minorTickDistance;
- }
- }
- else if (lastTickX <= axis.context.zeroX || (i == minorStartIndex && pX > axis.context.zeroX))
- {
- var tickTotal = pX - minorTickDistance;
- while (tickTotal > lastTickX)
- {
- UGL.DrawLine(vh, new Vector3(tickTotal, sY), new Vector3(tickTotal, mY), minorTickWidth, minorTickColor);
- tickTotal -= minorTickDistance;
- }
- }
- else
- {
- var tickTotal = lastTickX + minorTickDistance;
- while (tickTotal < pX)
- {
- UGL.DrawLine(vh, new Vector3(tickTotal, sY), new Vector3(tickTotal, mY), minorTickWidth, minorTickColor);
- tickTotal += minorTickDistance;
- }
- }
- if (i == size - 1)
- {
- var tickTotal = pX + minorTickDistance;
- while (tickTotal < maxAxisXY)
- {
- UGL.DrawLine(vh, new Vector3(tickTotal, sY), new Vector3(tickTotal, mY), minorTickWidth, minorTickColor);
- tickTotal += minorTickDistance;
- }
- }
- }
- lastTickX = pX;
- }
- else
- {
- float pY = axis.IsTime() ?
- (startY + axis.GetDistance(axis.GetLabelValue(i), axisLength)) :
- current;
- if (axis.boundaryGap && axis.axisTick.alignWithLabel)
- pY -= scaleWidth / 2;
- var sX = 0f;
- var eX = 0f;
- var mX = 0f;
- if ((axis.axisTick.inside && axis.IsLeft()) ||
- (!axis.axisTick.inside && axis.IsRight()))
- {
- sX = startX + lineWidth;
- eX = sX + tickLength;
- mX = sX + minorTickLength;
- }
- else
- {
- sX = startX - lineWidth;
- eX = sX - tickLength;
- mX = sX - minorTickLength;
- }
- if (!hideTick)
- UGL.DrawLine(vh, new Vector3(sX, pY), new Vector3(eX, pY), tickWidth, tickColor);
- if (axis.minorTick.show && i >= minorStartIndex && (minorTickDistance > 0 || isLogAxis))
- {
- if (isLogAxis)
- {
- var count = 0;
- var logRange = (axis.logBase - 1f);
- minorTickDistance = scaleWidth * axis.GetLogValue(1 + (count + 1) * logRange / minorTickSplitNumber);
- var tickTotal = lastTickY + minorTickDistance;
- while (tickTotal < current && count < minorTickSplitNumber - 1)
- {
- UGL.DrawLine(vh, new Vector3(sX, tickTotal), new Vector3(mX, tickTotal), minorTickWidth, minorTickColor);
- count++;
- minorTickDistance = scaleWidth * axis.GetLogValue(1 + (count + 1) * logRange / minorTickSplitNumber);
- tickTotal = lastTickY + minorTickDistance;
- }
- }
- else if (lastTickY <= axis.context.zeroY || (i == minorStartIndex && pY > axis.context.zeroY))
- {
- var tickTotal = pY - minorTickDistance;
- while (tickTotal > lastTickY)
- {
- UGL.DrawLine(vh, new Vector3(sX, tickTotal), new Vector3(mX, tickTotal), minorTickWidth, minorTickColor);
- tickTotal -= minorTickDistance;
- }
- }
- else
- {
- var tickTotal = lastTickY + minorTickDistance;
- while (tickTotal < pY)
- {
- UGL.DrawLine(vh, new Vector3(sX, tickTotal), new Vector3(mX, tickTotal), minorTickWidth, minorTickColor);
- tickTotal += minorTickDistance;
- }
- }
- if (i == size - 1)
- {
- var tickTotal = pY + minorTickDistance;
- while (tickTotal < maxAxisXY)
- {
- UGL.DrawLine(vh, new Vector3(sX, tickTotal), new Vector3(mX, tickTotal), minorTickWidth, minorTickColor);
- tickTotal += minorTickDistance;
- }
- }
- }
- lastTickY = pY;
- }
- }
- current += scaleWidth;
- }
- }
- if (axis.show && axis.axisLine.show && axis.axisLine.showArrow)
- {
- var lineY = startY + axis.offset;
- var inverse = axis.IsValue() && axis.inverse;
- var axisArrow = axis.axisLine.arrow;
- if (orient == Orient.Horizonal)
- {
- if (inverse)
- {
- var startPos = new Vector3(startX + axisLength, lineY);
- var arrowPos = new Vector3(startX, lineY);
- UGL.DrawArrow(vh, startPos, arrowPos, axisArrow.width, axisArrow.height,
- axisArrow.offset, axisArrow.dent,
- axisArrow.GetColor(axis.axisLine.GetColor(theme.lineColor)));
- }
- else
- {
- var arrowPosX = startX + axisLength + lineWidth;
- var startPos = new Vector3(startX, lineY);
- var arrowPos = new Vector3(arrowPosX, lineY);
- UGL.DrawArrow(vh, startPos, arrowPos, axisArrow.width, axisArrow.height,
- axisArrow.offset, axisArrow.dent,
- axisArrow.GetColor(axis.axisLine.GetColor(theme.lineColor)));
- }
- }
- else
- {
- if (inverse)
- {
- var startPos = new Vector3(startX, startY + axisLength);
- var arrowPos = new Vector3(startX, startY);
- UGL.DrawArrow(vh, startPos, arrowPos, axisArrow.width, axisArrow.height,
- axisArrow.offset, axisArrow.dent,
- axisArrow.GetColor(axis.axisLine.GetColor(theme.lineColor)));
- }
- else
- {
- var startPos = new Vector3(startX, startY);
- var arrowPos = new Vector3(startX, startY + axisLength + lineWidth);
- UGL.DrawArrow(vh, startPos, arrowPos, axisArrow.width, axisArrow.height,
- axisArrow.offset, axisArrow.dent,
- axisArrow.GetColor(axis.axisLine.GetColor(theme.lineColor)));
- }
- }
- }
- }
- protected void DrawAxisSplit(VertexHelper vh, AxisTheme theme, DataZoom dataZoom,
- Orient orient, float startX, float startY, float axisLength, float splitLength,
- Axis relativedAxis = null)
- {
- Axis axis = component;
- var axisLineWidth = axis.axisLine.GetWidth(theme.lineWidth);
- splitLength -= axisLineWidth;
- var lineColor = axis.splitLine.GetColor(theme.splitLineColor);
- var lineWidth = axis.splitLine.GetWidth(theme.lineWidth);
- var lineType = axis.splitLine.GetType(theme.splitLineType);
- var size = AxisHelper.GetScaleNumber(axis, axisLength, dataZoom);
- if (axis.IsTime())
- {
- size += 1;
- if (!ChartHelper.IsEquals(axis.GetLastLabelValue(), axis.context.maxValue))
- size += 1;
- }
- var current = orient == Orient.Horizonal ? startX : startY;
- var maxAxisXY = current + axisLength;
- var lastSplitX = 0f;
- var lastSplitY = 0f;
- var minorTickSplitNumber = axis.minorTick.splitNumber <= 0 ? 5 : axis.minorTick.splitNumber;
- var minorTickDistance = axis.GetValueLength(axis.context.tickValue / minorTickSplitNumber, axisLength);
- var minorSplitLineColor = axis.minorSplitLine.GetColor(theme.minorSplitLineColor);
- var minorLineWidth = axis.minorSplitLine.GetWidth(theme.lineWidth);
- var minorLineType = axis.minorSplitLine.GetType(theme.splitLineType);
- var minorStartIndex = axis.IsTime() ? 0 : 1;
- var isLogAxis = axis.IsLog();
- for (int i = 0; i < size; i++)
- {
- var scaleWidth = AxisHelper.GetScaleWidth(axis, axisLength, axis.IsTime() ? i : i + 1, dataZoom);
- if (axis.boundaryGap && axis.axisTick.alignWithLabel)
- current -= scaleWidth / 2;
- if (axis.splitArea.show && i <= size - 1)
- {
- if (orient == Orient.Horizonal)
- {
- UGL.DrawQuadrilateral(vh,
- new Vector2(current, startY),
- new Vector2(current, startY + splitLength),
- new Vector2(current + scaleWidth, startY + splitLength),
- new Vector2(current + scaleWidth, startY),
- axis.splitArea.GetColor(i, theme));
- }
- else
- {
- UGL.DrawQuadrilateral(vh,
- new Vector2(startX, current),
- new Vector2(startX + splitLength, current),
- new Vector2(startX + splitLength, current + scaleWidth),
- new Vector2(startX, current + scaleWidth),
- axis.splitArea.GetColor(i, theme));
- }
- }
- if (axis.splitLine.show)
- {
- if (axis.splitLine.NeedShow(i, size))
- {
- if (orient == Orient.Horizonal)
- {
- if (relativedAxis == null || !relativedAxis.axisLine.show || !MathUtil.Approximately(current, relativedAxis.context.x))
- {
- ChartDrawer.DrawLineStyle(vh,
- lineType,
- lineWidth,
- new Vector3(current, startY),
- new Vector3(current, startY + splitLength),
- lineColor);
- }
- if (axis.minorSplitLine.show && i >= minorStartIndex && (minorTickDistance > 0 || isLogAxis))
- {
- if (isLogAxis)
- {
- var count = 0;
- var logRange = axis.logBase - 1f;
- minorTickDistance = scaleWidth * axis.GetLogValue(1 + (count + 1) * logRange / minorTickSplitNumber);
- var tickTotal = lastSplitX + minorTickDistance;
- while (tickTotal < current && count < minorTickSplitNumber - 1)
- {
- ChartDrawer.DrawLineStyle(vh,
- minorLineType,
- minorLineWidth,
- new Vector3(tickTotal, startY),
- new Vector3(tickTotal, startY + splitLength),
- minorSplitLineColor);
- count++;
- minorTickDistance = scaleWidth * axis.GetLogValue(1 + (count + 1) * logRange / minorTickSplitNumber);
- tickTotal = lastSplitX + minorTickDistance;
- }
- }
- else if (lastSplitX <= axis.context.zeroX || (i == minorStartIndex && current > axis.context.zeroX))
- {
- var tickTotal = current - minorTickDistance;
- var count = 0;
- while (tickTotal > lastSplitX && count < minorTickSplitNumber - 1)
- {
- ChartDrawer.DrawLineStyle(vh,
- minorLineType,
- minorLineWidth,
- new Vector3(tickTotal, startY),
- new Vector3(tickTotal, startY + splitLength),
- minorSplitLineColor);
- count++;
- tickTotal -= minorTickDistance;
- }
- }
- else
- {
- var tickTotal = lastSplitX + minorTickDistance;
- var count = 0;
- while (tickTotal < current && count < minorTickSplitNumber - 1)
- {
- ChartDrawer.DrawLineStyle(vh,
- minorLineType,
- minorLineWidth,
- new Vector3(tickTotal, startY),
- new Vector3(tickTotal, startY + splitLength),
- minorSplitLineColor);
- count++;
- tickTotal += minorTickDistance;
- }
- }
- if (i == size - 1)
- {
- var tickTotal = current + minorTickDistance;
- var count = 0;
- while (tickTotal < maxAxisXY && count < minorTickSplitNumber - 1)
- {
- ChartDrawer.DrawLineStyle(vh,
- minorLineType,
- minorLineWidth,
- new Vector3(tickTotal, startY),
- new Vector3(tickTotal, startY + splitLength),
- minorSplitLineColor);
- count++;
- tickTotal += minorTickDistance;
- }
- }
- }
- lastSplitX = current;
- }
- else
- {
- if (relativedAxis == null || !relativedAxis.axisLine.show || !MathUtil.Approximately(current, relativedAxis.context.y))
- {
- ChartDrawer.DrawLineStyle(vh,
- lineType,
- lineWidth,
- new Vector3(startX, current),
- new Vector3(startX + splitLength, current),
- lineColor);
- }
- if (axis.minorSplitLine.show && i >= minorStartIndex && (minorTickDistance > 0 || isLogAxis))
- {
- if (isLogAxis)
- {
- var count = 0;
- var logRange = (axis.logBase - 1f);
- minorTickDistance = scaleWidth * axis.GetLogValue(1 + (count + 1) * logRange / minorTickSplitNumber);
- var tickTotal = lastSplitY + minorTickDistance;
- while (tickTotal < current && count < minorTickSplitNumber - 1)
- {
- ChartDrawer.DrawLineStyle(vh,
- minorLineType,
- minorLineWidth,
- new Vector3(startX, tickTotal),
- new Vector3(startX + splitLength, tickTotal),
- minorSplitLineColor);
- count++;
- minorTickDistance = scaleWidth * axis.GetLogValue(1 + (count + 1) * logRange / minorTickSplitNumber);
- tickTotal = lastSplitY + minorTickDistance;
- }
- }
- else if (lastSplitY <= axis.context.zeroY || (i == minorStartIndex && current > axis.context.zeroY))
- {
- var tickTotal = current - minorTickDistance;
- var count = 0;
- while (tickTotal > lastSplitY && count < minorTickSplitNumber - 1)
- {
- ChartDrawer.DrawLineStyle(vh,
- minorLineType,
- minorLineWidth,
- new Vector3(startX, tickTotal),
- new Vector3(startX + splitLength, tickTotal),
- minorSplitLineColor);
- count++;
- tickTotal -= minorTickDistance;
- }
- }
- else
- {
- var tickTotal = lastSplitY + minorTickDistance;
- var count = 0;
- while (tickTotal < current && count < minorTickSplitNumber - 1)
- {
- ChartDrawer.DrawLineStyle(vh,
- minorLineType,
- minorLineWidth,
- new Vector3(startX, tickTotal),
- new Vector3(startX + splitLength, tickTotal),
- minorSplitLineColor);
- count++;
- tickTotal += minorTickDistance;
- }
- }
- if (i == size - 1)
- {
- var tickTotal = current + minorTickDistance;
- var count = 0;
- while (tickTotal < maxAxisXY && count < minorTickSplitNumber - 1)
- {
- ChartDrawer.DrawLineStyle(vh,
- minorLineType,
- minorLineWidth,
- new Vector3(startX, tickTotal),
- new Vector3(startX + splitLength, tickTotal),
- minorSplitLineColor);
- count++;
- tickTotal += minorTickDistance;
- }
- }
- }
- lastSplitY = current;
- }
- }
- }
- current += scaleWidth;
- }
- }
- }
- }
|