123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616 |
- using System.Collections.Generic;
- using System.Text;
- using UnityEngine;
- using UnityEngine.EventSystems;
- using UnityEngine.UI;
-
- namespace XCharts.Runtime
- {
- public abstract class SerieHandler
- {
- public BaseChart chart { get; internal set; }
- public SerieHandlerAttribute attribute { get; internal set; }
- public virtual int defaultDimension { get; internal set; }
-
- public virtual void InitComponent() { }
- public virtual void RemoveComponent() { }
- public virtual void CheckComponent(StringBuilder sb) { }
- public virtual void Update() { }
- public virtual void DrawBase(VertexHelper vh) { }
- public virtual void DrawSerie(VertexHelper vh) { }
- public virtual void DrawUpper(VertexHelper vh) { }
- public virtual void DrawTop(VertexHelper vh) { }
- public virtual void OnPointerClick(PointerEventData eventData) { }
- public virtual void OnPointerDown(PointerEventData eventData) { }
- public virtual void OnPointerUp(PointerEventData eventData) { }
- public virtual void OnPointerEnter(PointerEventData eventData) { }
- public virtual void OnPointerExit(PointerEventData eventData) { }
- public virtual void OnDrag(PointerEventData eventData) { }
- public virtual void OnBeginDrag(PointerEventData eventData) { }
- public virtual void OnEndDrag(PointerEventData eventData) { }
- public virtual void OnScroll(PointerEventData eventData) { }
- public virtual void RefreshLabelNextFrame() { }
- public virtual void RefreshLabelInternal() { }
- public virtual void UpdateTooltipSerieParams(int dataIndex, bool showCategory,
- string category, string marker,
- string itemFormatter, string numericFormatter, string ignoreDataDefaultContent,
- ref List<SerieParams> paramList, ref string title) { }
- public virtual void OnLegendButtonClick(int index, string legendName, bool show) { }
- public virtual void OnLegendButtonEnter(int index, string legendName) { }
- public virtual void OnLegendButtonExit(int index, string legendName) { }
- internal abstract void SetSerie(Serie serie);
- }
-
- public abstract class SerieHandler<T> : SerieHandler where T : Serie
- {
- private static readonly string s_SerieLabelObjectName = "label";
- private static readonly string s_SerieTitleObjectName = "title";
- private static readonly string s_SerieRootObjectName = "serie";
- private static readonly string s_SerieEndLabelObjectName = "end_label";
- protected GameObject m_SerieRoot;
- protected GameObject m_SerieLabelRoot;
- protected bool m_InitedLabel;
- protected bool m_NeedInitComponent;
- protected bool m_RefreshLabel;
- protected bool m_LastCheckContextFlag = false;
- protected bool m_LegendEnter = false;
- protected int m_LegendEnterIndex;
- protected ChartLabel m_EndLabel;
-
- public T serie { get; internal set; }
- public GameObject labelObject { get { return m_SerieLabelRoot; } }
-
- internal override void SetSerie(Serie serie)
- {
- this.serie = (T) serie;
- this.serie.context.param.serieType = typeof(T);
- m_NeedInitComponent = true;
- AnimationStyleHelper.UpdateSerieAnimation(serie);
- }
-
- public override void Update()
- {
- if (m_NeedInitComponent)
- {
- m_NeedInitComponent = false;
- InitComponent();
- }
- if (m_RefreshLabel)
- {
- m_RefreshLabel = false;
- RefreshLabelInternal();
- RefreshEndLabelInternal();
- }
- if (serie.dataDirty)
- {
- SeriesHelper.UpdateSerieNameList(chart, ref chart.m_LegendRealShowName);
- serie.OnDataUpdate();
- serie.dataDirty = false;
- }
- if (serie.label != null && (serie.labelDirty || serie.label.componentDirty))
- {
- serie.labelDirty = false;
- serie.label.ClearComponentDirty();
- InitSerieLabel();
- InitSerieEndLabel();
- }
- if (serie.endLabel != null && serie.endLabel.componentDirty)
- {
- serie.endLabel.ClearComponentDirty();
- InitSerieEndLabel();
- }
- if (serie.titleStyle != null && (serie.titleDirty || serie.titleStyle.componentDirty))
- {
- serie.titleDirty = false;
- serie.titleStyle.ClearComponentDirty();
- InitSerieTitle();
- }
- if (serie.nameDirty)
- {
- foreach (var component in chart.components)
- {
- if (component is Legend)
- component.SetAllDirty();
- }
- chart.RefreshChart();
- serie.ClearSerieNameDirty();
- }
- if (serie.vertsDirty)
- {
- chart.RefreshPainter(serie);
- serie.ResetInteract();
- serie.ClearVerticesDirty();
- }
- }
-
- public override void RefreshLabelNextFrame()
- {
- m_RefreshLabel = true;
- }
-
- public override void InitComponent()
- {
- m_InitedLabel = false;
- InitRoot();
- InitSerieLabel();
- InitSerieTitle();
- InitSerieEndLabel();
- }
-
- public override void RemoveComponent()
- {
- ChartHelper.SetActive(m_SerieRoot, false);
- }
-
- public override void OnLegendButtonClick(int index, string legendName, bool show)
- {
- if (serie.colorByData && serie.IsSerieDataLegendName(legendName))
- {
- LegendHelper.CheckDataShow(serie, legendName, show);
- chart.UpdateLegendColor(legendName, show);
- chart.RefreshPainter(serie);
- }
- else if (serie.IsLegendName(legendName))
- {
- chart.SetSerieActive(serie, show);
- chart.RefreshPainter(serie);
- }
- }
-
- public override void OnLegendButtonEnter(int index, string legendName)
- {
- if (serie.colorByData && serie.IsSerieDataLegendName(legendName))
- {
- LegendHelper.CheckDataHighlighted(serie, legendName, true);
- chart.RefreshPainter(serie);
- }
- else if (serie.IsLegendName(legendName))
- {
- m_LegendEnter = true;
- chart.RefreshPainter(serie);
- }
- }
-
- public override void OnLegendButtonExit(int index, string legendName)
- {
- if (serie.colorByData && serie.IsSerieDataLegendName(legendName))
- {
- LegendHelper.CheckDataHighlighted(serie, legendName, false);
- chart.RefreshPainter(serie);
- }
- else if (serie.IsLegendName(legendName))
- {
- m_LegendEnter = false;
- chart.RefreshPainter(serie);
- }
- }
-
- private void InitRoot()
- {
- if (m_SerieRoot != null)
- {
- var rect = ChartHelper.GetOrAddComponent<RectTransform>(m_SerieRoot);
- rect.localPosition = Vector3.zero;
- rect.sizeDelta = chart.chartSizeDelta;
- rect.anchorMin = chart.chartMinAnchor;
- rect.anchorMax = chart.chartMaxAnchor;
- rect.pivot = chart.chartPivot;
- return;
- }
- var objName = s_SerieRootObjectName + "_" + serie.index;
- m_SerieRoot = ChartHelper.AddObject(objName, chart.transform, chart.chartMinAnchor,
- chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
- m_SerieRoot.hideFlags = chart.chartHideFlags;
- ChartHelper.SetActive(m_SerieRoot, true);
- ChartHelper.HideAllObject(m_SerieRoot);
- }
-
- private void InitSerieLabel()
- {
- InitRoot();
- m_SerieLabelRoot = ChartHelper.AddObject(s_SerieLabelObjectName, m_SerieRoot.transform,
- chart.chartMinAnchor, chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
- m_SerieLabelRoot.hideFlags = chart.chartHideFlags;
- SerieLabelPool.ReleaseAll(m_SerieLabelRoot.transform);
- int count = 0;
- SerieHelper.UpdateCenter(serie, chart.chartPosition, chart.chartWidth, chart.chartHeight);
- for (int j = 0; j < serie.data.Count; j++)
- {
- var serieData = serie.data[j];
- serieData.index = j;
- serieData.labelObject = null;
- if (AddSerieLabel(m_SerieLabelRoot, serieData, ref count))
- {
- m_InitedLabel = true;
- count++;
- }
- }
- RefreshLabelInternal();
- }
-
- protected bool AddSerieLabel(GameObject serieLabelRoot, SerieData serieData, ref int count)
- {
- if (serieData == null)
- return false;
- if (serieLabelRoot == null)
- return false;
- if (serie.IsPerformanceMode())
- return false;
-
- if (count == -1) count = serie.dataCount;
- var serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
- if (serieLabel == null)
- {
- return false;
- }
-
- var dataAutoColor = GetSerieDataAutoColor(serieData);
- serieData.context.dataLabels.Clear();
- if (serie.multiDimensionLabel)
- {
- for (int i = 0; i < serieData.data.Count; i++)
- {
- var textName = string.Format("{0}_{1}_{2}_{3}", s_SerieLabelObjectName, serie.index, serieData.index, i);
- var label = ChartHelper.AddChartLabel(textName, serieLabelRoot.transform, serieLabel, chart.theme.common,
- "", dataAutoColor, TextAnchor.MiddleCenter);
- label.SetActive(serieLabel.show);
- serieData.context.dataLabels.Add(label);
- }
- }
- else
- {
- var textName = ChartCached.GetSerieLabelName(s_SerieLabelObjectName, serie.index, serieData.index);
- var label = ChartHelper.AddChartLabel(textName, serieLabelRoot.transform, serieLabel, chart.theme.common,
- "", dataAutoColor, TextAnchor.MiddleCenter);
- label.SetActive(serieLabel.show);
- serieData.labelObject = label;
- }
-
- if (serieData.context.children.Count > 0)
- {
- foreach (var childSerieData in serieData.context.children)
- {
- AddSerieLabel(serieLabelRoot, childSerieData, ref count);
- count++;
- }
- }
- return true;
- }
-
- private void InitSerieEndLabel()
- {
- if (serie.endLabel == null)
- {
- if (m_EndLabel != null)
- {
- m_EndLabel.SetActive(false);
- m_EndLabel = null;
- }
- return;
- }
- InitRoot();
- var dataAutoColor = (Color) chart.GetLegendRealShowNameColor(serie.legendName);
- m_EndLabel = ChartHelper.AddChartLabel(s_SerieEndLabelObjectName, m_SerieRoot.transform, serie.endLabel,
- chart.theme.common, "", dataAutoColor, TextAnchor.MiddleLeft);
- m_EndLabel.SetActive(serie.endLabel.show);
- RefreshEndLabelInternal();
- }
-
- private void InitSerieTitle()
- {
- InitRoot();
- var serieTitleRoot = ChartHelper.AddObject(s_SerieTitleObjectName, m_SerieRoot.transform,
- chart.chartMinAnchor, chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
- serieTitleRoot.hideFlags = chart.chartHideFlags;
- SerieLabelPool.ReleaseAll(serieTitleRoot.transform);
- ChartHelper.RemoveComponent<Text>(serieTitleRoot);
-
- SerieHelper.UpdateCenter(serie, chart.chartPosition, chart.chartWidth, chart.chartHeight);
-
- if (serie.titleJustForSerie)
- {
- var titleStyle = SerieHelper.GetTitleStyle(serie, null);
- if (titleStyle != null)
- {
- var color = chart.GetItemColor(serie, null);
- var content = string.Empty;
- if (string.IsNullOrEmpty(titleStyle.formatter))
- {
- content = serie.serieName;
- }
- else
- {
- content = titleStyle.formatter;
- FormatterHelper.ReplaceContent(ref content, 0, titleStyle.numericFormatter, serie, chart);
- }
- var label = ChartHelper.AddChartLabel("title_" + 0, serieTitleRoot.transform, titleStyle, chart.theme.common,
- content, color, TextAnchor.MiddleCenter);
- serie.context.titleObject = label;
- label.SetActive(titleStyle.show);
- var labelPosition = GetSerieDataTitlePosition(null, titleStyle);
- var offset = titleStyle.GetOffset(serie.context.insideRadius);
- label.SetPosition(labelPosition + offset);
- }
- }
- else
- {
- for (int i = 0; i < serie.dataCount; i++)
- {
- var serieData = serie.data[i];
- var titleStyle = SerieHelper.GetTitleStyle(serie, serieData);
- if (titleStyle == null) continue;
- var color = chart.GetItemColor(serie, serieData);
- var content = string.Empty;
- if (string.IsNullOrEmpty(titleStyle.formatter))
- {
- content = serieData.name;
- }
- else
- {
- content = titleStyle.formatter;
- FormatterHelper.ReplaceContent(ref content, 0, titleStyle.numericFormatter, serie, chart);
- }
- FormatterHelper.ReplaceContent(ref content, i, titleStyle.numericFormatter, serie, chart);
- var label = ChartHelper.AddChartLabel("title_" + i, serieTitleRoot.transform, titleStyle, chart.theme.common,
- content, color, TextAnchor.MiddleCenter);
- serieData.titleObject = label;
- label.SetActive(titleStyle.show);
- var labelPosition = GetSerieDataTitlePosition(serieData, titleStyle);
- var offset = titleStyle.GetOffset(serie.context.insideRadius);
- label.SetPosition(labelPosition + offset);
- }
- }
- }
-
- public override void RefreshLabelInternal()
- {
- if (!m_InitedLabel)
- return;
-
- var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
- var unscaledTime = serie.animation.unscaledTime;
- var needCheck = serie.context.dataIndexs.Count > 0;
- foreach (var serieData in serie.data)
- {
- if (serieData.labelObject == null && serieData.context.dataLabels.Count <= 0)
- {
- continue;
- }
- if (needCheck && !serie.context.dataIndexs.Contains(serieData.index))
- {
- serieData.SetLabelActive(false);
- continue;
- };
- var currLabel = SerieHelper.GetSerieLabel(serie, serieData);
- var isIgnore = serie.IsIgnoreIndex(serieData.index, defaultDimension);
- if (serie.show &&
- currLabel != null &&
- serieData.context.canShowLabel &&
- !isIgnore)
- {
- if (serie.multiDimensionLabel)
- {
- var total = serieData.GetTotalData();
- var color = chart.GetItemColor(serie, serieData);
- for (int i = 0; i < serieData.context.dataLabels.Count; i++)
- {
- if (i >= serieData.context.dataPoints.Count) continue;
- var labelObject = serieData.context.dataLabels[i];
- var value = serieData.GetCurrData(i, dataChangeDuration, unscaledTime);
- var content = string.IsNullOrEmpty(currLabel.formatter) ?
- ChartCached.NumberToStr(value, currLabel.numericFormatter) :
- SerieLabelHelper.GetFormatterContent(serie, serieData, value, total,
- currLabel, color);
- var offset = GetSerieDataLabelOffset(serieData, currLabel);
- labelObject.SetActive(currLabel.show && !isIgnore);
- labelObject.SetText(content);
- labelObject.SetPosition(serieData.context.dataPoints[i] + offset);
- labelObject.UpdateIcon(currLabel.icon);
- if (currLabel.textStyle.autoColor)
- {
- var dataAutoColor = GetSerieDataAutoColor(serieData);
- if (!ChartHelper.IsClearColor(dataAutoColor))
- labelObject.SetTextColor(dataAutoColor);
- }
- }
- }
- else
- {
- var value = serieData.GetCurrData(defaultDimension, dataChangeDuration, unscaledTime);
- var total = serie.GetDataTotal(defaultDimension, serieData);
- var color = chart.GetItemColor(serie, serieData);
- var content = string.IsNullOrEmpty(currLabel.formatter) ?
- ChartCached.NumberToStr(value, currLabel.numericFormatter) :
- SerieLabelHelper.GetFormatterContent(serie, serieData, value, total,
- currLabel, color);
- serieData.SetLabelActive(currLabel.show && !isIgnore);
- serieData.labelObject.UpdateIcon(currLabel.icon);
- serieData.labelObject.SetText(content);
- UpdateLabelPosition(serieData, currLabel);
- if (currLabel.textStyle.autoColor)
- {
- var dataAutoColor = GetSerieDataAutoColor(serieData);
- if (!ChartHelper.IsClearColor(dataAutoColor))
- serieData.labelObject.SetTextColor(dataAutoColor);
- }
- }
- }
- else
- {
- serieData.SetLabelActive(false);
- }
- }
- }
-
- public virtual void RefreshEndLabelInternal()
- {
- if (m_EndLabel == null)
- return;
- var endLabelStyle = serie.endLabel;
- if (endLabelStyle == null)
- return;
- var dataCount = serie.context.dataPoints.Count;
- var active = endLabelStyle.show && dataCount > 0;
- m_EndLabel.SetActive(active);
- if (active)
- {
- var value = serie.context.lineEndValue;
- var content = SerieLabelHelper.GetFormatterContent(serie, null, value, 0,
- endLabelStyle, Color.clear);
- m_EndLabel.SetText(content);
- m_EndLabel.SetPosition(serie.context.lineEndPostion + endLabelStyle.offset);
- }
- m_EndLabel.isAnimationEnd = serie.animation.IsFinish();
- }
-
- private void UpdateLabelPosition(SerieData serieData, LabelStyle currLabel)
- {
- var labelPosition = GetSerieDataLabelPosition(serieData, currLabel);
- var offset = GetSerieDataLabelOffset(serieData, currLabel);
- serieData.labelObject.SetPosition(labelPosition + offset);
- }
-
- public virtual Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyle label)
- {
- return ChartHelper.IsZeroVector(serieData.context.labelPosition) ?
- serieData.context.position :
- serieData.context.labelPosition;
- }
-
- public virtual Vector3 GetSerieDataLabelOffset(SerieData serieData, LabelStyle label)
- {
- return label.GetOffset(serie.context.insideRadius);
- }
-
- public virtual Vector3 GetSerieDataTitlePosition(SerieData serieData, TitleStyle titleStyle)
- {
- return serieData.context.position;
- }
-
- public virtual Color GetSerieDataAutoColor(SerieData serieData)
- {
- var colorIndex = serie.colorByData ? serieData.index : serie.index;
- Color32 color, toColor;
- SerieHelper.GetItemColor(out color, out toColor, serie, serieData, chart.theme, colorIndex, SerieState.Normal, false);
- return (Color) color;
- }
-
- protected void UpdateCoordSerieParams(ref List<SerieParams> paramList, ref string title,
- int dataIndex, bool showCategory, string category, string marker,
- string itemFormatter, string numericFormatter, string ignoreDataDefaultContent)
- {
- var dimension = 1;
- if (dataIndex < 0)
- dataIndex = serie.context.pointerItemDataIndex;
-
- if (dataIndex < 0)
- return;
-
- var serieData = serie.GetSerieData(dataIndex);
- if (serieData == null)
- return;
-
- var ignore = serie.IsIgnoreValue(serieData, dimension);
- if (ignore && string.IsNullOrEmpty(ignoreDataDefaultContent))
- return;
-
- itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter);
- if (serie.placeHolder || TooltipHelper.IsIgnoreFormatter(itemFormatter))
- return;
-
- var param = serie.context.param;
- param.serieName = serie.serieName;
- param.serieIndex = serie.index;
- param.category = category;
- param.dimension = dimension;
- param.serieData = serieData;
- param.dataCount = serie.dataCount;
- param.value = serieData.GetData(dimension);
- param.ignore = ignore;
- param.total = serie.yTotal;
- param.color = chart.GetMarkColor(serie, serieData);
- param.marker = SerieHelper.GetItemMarker(serie, serieData, marker);
- param.itemFormatter = itemFormatter;
- param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter);
- param.columns.Clear();
-
- param.columns.Add(param.marker);
- param.columns.Add(showCategory ? category : serie.serieName);
- param.columns.Add(ignore?ignoreDataDefaultContent : ChartCached.NumberToStr(param.value, param.numericFormatter));
-
- paramList.Add(param);
- }
-
- protected void UpdateItemSerieParams(ref List<SerieParams> paramList, ref string title,
- int dataIndex, string category, string marker,
- string itemFormatter, string numericFormatter, string ignoreDataDefaultContent,
- int dimension = 1, int colorIndex = -1)
- {
- if (dataIndex < 0)
- dataIndex = serie.context.pointerItemDataIndex;
-
- if (dataIndex < 0)
- return;
-
- var serieData = serie.GetSerieData(dataIndex);
- if (serieData == null)
- return;
-
- var ignore = serie.IsIgnoreValue(serieData, dimension);
- if (ignore && string.IsNullOrEmpty(ignoreDataDefaultContent))
- return;
-
- itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter);
- if (serie.placeHolder || TooltipHelper.IsIgnoreFormatter(itemFormatter))
- return;
-
- if (colorIndex < 0)
- colorIndex = serie.colorByData?dataIndex : chart.GetLegendRealShowNameIndex(serieData.name);
-
- Color32 color, toColor;
- SerieHelper.GetItemColor(out color, out toColor, serie, serieData, chart.theme, colorIndex, SerieState.Normal);
- var param = serie.context.param;
- param.serieName = serie.serieName;
- param.serieIndex = serie.index;
-
- param.category = category;
- param.dimension = dimension;
- param.serieData = serieData;
- param.dataCount = serie.dataCount;
- param.value = serieData.GetData(param.dimension);
- param.ignore = ignore;
- param.total = serie.multiDimensionLabel? serieData.GetTotalData() : serie.GetDataTotal(defaultDimension);
- param.color = color;
- param.marker = SerieHelper.GetItemMarker(serie, serieData, marker);
- param.itemFormatter = itemFormatter;
- param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter);
- param.columns.Clear();
-
- param.columns.Add(param.marker);
- param.columns.Add(serieData.name);
-
- param.columns.Add(ignore?ignoreDataDefaultContent : ChartCached.NumberToStr(param.value, param.numericFormatter));
-
- paramList.Add(param);
- }
-
- public void DrawLabelLineSymbol(VertexHelper vh, LabelLine labelLine, Vector3 startPos, Vector3 endPos, Color32 defaultColor)
- {
- if (labelLine.startSymbol != null && labelLine.startSymbol.show)
- {
- DrawSymbol(vh, labelLine.startSymbol, startPos, defaultColor);
- }
- if (labelLine.endSymbol != null && labelLine.endSymbol.show)
- {
- DrawSymbol(vh, labelLine.endSymbol, endPos, defaultColor);
- }
- }
-
- private void DrawSymbol(VertexHelper vh, SymbolStyle symbol, Vector3 pos, Color32 defaultColor)
- {
- var color = symbol.GetColor(defaultColor);
- chart.DrawSymbol(vh, symbol.type, symbol.size, 1, pos,
- color, color, ColorUtil.clearColor32, color, symbol.gap, null);
- }
- }
- }
|