增加折线图和柱形图的tooltip

This commit is contained in:
monitor1394
2019-03-12 08:10:25 +08:00
parent f2a29973fe
commit a6778cd308
12 changed files with 4092 additions and 1286 deletions

View File

@@ -13,7 +13,7 @@ public class Demo : MonoBehaviour
void Awake()
{
lineChart = transform.Find("xchart/line_chart").GetComponent<LineChart>();
//lineChart = transform.Find("xchart/line_chart").GetComponent<LineChart>();
var xchart = transform.Find("xchart");
GridLayoutGroup grid = xchart.GetComponent<GridLayoutGroup>();

View File

@@ -25,10 +25,9 @@ namespace xcharts
base.Update();
}
protected override void OnPopulateMesh(VertexHelper vh)
protected override void DrawChart(VertexHelper vh)
{
base.OnPopulateMesh(vh);
base.DrawChart(vh);
if(yAxis.type == AxisType.category)
{
int seriesCount = seriesList.Count;
@@ -36,6 +35,16 @@ namespace xcharts
float barWid = barInfo.barWid > 1 ? barInfo.barWid : scaleWid * barInfo.barWid;
float offset = (scaleWid - barWid * seriesCount - barInfo.space * (seriesCount - 1)) / 2;
float max = GetMaxValue();
if (tooltip.show && tooltip.DataIndex > 0)
{
float pX = zeroX + coordinateWid;
float pY = zeroY + scaleWid * (tooltip.DataIndex - 1);
Vector3 p1 = new Vector3(zeroX, pY);
Vector3 p2 = new Vector3(zeroX, pY + scaleWid);
Vector3 p3 = new Vector3(pX, pY + scaleWid);
Vector3 p4 = new Vector3(pX, pY);
ChartUtils.DrawPolygon(vh, p1, p2, p3, p4, themeInfo.tooltipFlagAreaColor);
}
for (int j = 0; j < seriesCount; j++)
{
if (!legend.IsShowSeries(j)) continue;
@@ -69,6 +78,16 @@ namespace xcharts
float barWid = barInfo.barWid > 1 ? barInfo.barWid : scaleWid * barInfo.barWid;
float offset = (scaleWid - barWid * seriesCount - barInfo.space * (seriesCount - 1)) / 2;
float max = GetMaxValue();
if (tooltip.show && tooltip.DataIndex > 0)
{
float pX = zeroX + scaleWid * (tooltip.DataIndex - 1);
float pY = zeroY + coordinateHig;
Vector3 p1 = new Vector3(pX, zeroY);
Vector3 p2 = new Vector3(pX, pY);
Vector3 p3 = new Vector3(pX + scaleWid, pY);
Vector3 p4 = new Vector3(pX + scaleWid, zeroY);
ChartUtils.DrawPolygon(vh, p1, p2, p3, p4, themeInfo.tooltipFlagAreaColor);
}
for (int j = 0; j < seriesCount; j++)
{
if (!legend.IsShowSeries(j)) continue;

View File

@@ -2,6 +2,7 @@
using System.Collections;
using UnityEngine.UI;
using System.Collections.Generic;
using System.Text;
namespace xcharts
{
@@ -114,12 +115,153 @@ namespace xcharts
CheckCoordinate();
}
protected override void OnPopulateMesh(VertexHelper vh)
protected override void DrawChart(VertexHelper vh)
{
base.OnPopulateMesh(vh);
base.DrawChart(vh);
DrawCoordinate(vh);
}
protected override void CheckTootipArea(Vector2 local)
{
if (local.x < zeroX || local.x > zeroX + coordinateWid ||
local.y < zeroY || local.y > zeroY + coordinateHig)
{
tooltip.DataIndex = 0;
RefreshTooltip();
}
else
{
if (xAxis.type == AxisType.value)
{
float splitWid = coordinateHig / (yAxis.splitNumber - 1);
for (int i = 0; i < yAxis.splitNumber; i++)
{
float pY = zeroY + i * splitWid;
if (yAxis.boundaryGap)
{
if (local.y > pY && local.y <= pY + splitWid)
{
tooltip.DataIndex = i + 1;
break;
}
}
else
{
if (local.y > pY - splitWid / 2 && local.y <= pY + splitWid / 2)
{
tooltip.DataIndex = i + 1;
break;
}
}
}
}
else
{
float splitWid = coordinateWid / (xAxis.splitNumber - 1);
for (int i = 0; i < xAxis.splitNumber; i++)
{
float pX = zeroX + i * splitWid;
if (xAxis.boundaryGap)
{
if (local.x > pX && local.x <= pX + splitWid)
{
tooltip.DataIndex = i + 1;
break;
}
}
else
{
if (local.x > pX - splitWid / 2 && local.x <= pX + splitWid / 2)
{
tooltip.DataIndex = i + 1;
break;
}
}
}
}
}
if (tooltip.DataIndex > 0)
{
tooltip.UpdatePos(new Vector2(local.x + 18, local.y - 25));
RefreshTooltip();
if (tooltip.LastDataIndex != tooltip.DataIndex)
{
RefreshChart();
}
tooltip.LastDataIndex = tooltip.DataIndex;
}
}
protected override void RefreshTooltip()
{
base.RefreshTooltip();
int index = tooltip.DataIndex - 1;
if (index < 0)
{
tooltip.SetActive(false);
return;
}
Axis tempAxis = xAxis.type == AxisType.value ? (Axis)yAxis : (Axis)xAxis;
if (index > tempAxis.data.Count - 1)
{
index = tempAxis.data.Count - 1;
}
tooltip.SetActive(true);
if (seriesList.Count == 1)
{
string txt = tempAxis.data[index] + ": " + seriesList[0].dataList[index].value;
tooltip.UpdateTooltipText(txt);
}
else
{
StringBuilder sb = new StringBuilder(tempAxis.data[index]);
for(int i=0; i<seriesList.Count;i++)
{
string strColor = ColorUtility.ToHtmlStringRGBA(themeInfo.GetColor(i));
string key = seriesList[i].legendKey;
float value = seriesList[i].dataList[index].value;
sb.Append("\n");
sb.AppendFormat("<color=#{0}>● </color>", strColor);
sb.AppendFormat("{0}: {1}", key, value);
}
tooltip.UpdateTooltipText(sb.ToString());
}
var pos = tooltip.GetPos();
if (pos.x + tooltip.Width > chartWid)
{
pos.x = chartWid - tooltip.Width;
}
if (pos.y - tooltip.Height < 0)
{
pos.y = tooltip.Height;
}
tooltip.UpdatePos(pos);
}
TextGenerationSettings GetTextSetting()
{
var setting = new TextGenerationSettings();
var fontdata = FontData.defaultFontData;
//setting.generationExtents = rectTransform.rect.size;
setting.generationExtents = new Vector2(200.0F, 50.0F);
setting.fontSize = 14;
setting.textAnchor = TextAnchor.MiddleCenter;
setting.scaleFactor = 1f;
setting.color = Color.red;
setting.font = themeInfo.font;
setting.pivot = new Vector2(0.5f, 0.5f);
setting.richText = false;
setting.lineSpacing = 0;
setting.fontStyle = FontStyle.Normal;
setting.resizeTextForBestFit = false;
setting.horizontalOverflow = HorizontalWrapMode.Overflow;
setting.verticalOverflow = VerticalWrapMode.Overflow;
return setting;
}
protected override void OnThemeChanged()
{
base.OnThemeChanged();

View File

@@ -15,7 +15,7 @@ namespace xcharts
public class Title
{
public bool show = true;
public string text ="Chart Title";
public string text = "Chart Title";
public Align align = Align.center;
public float left;
public float right;
@@ -81,6 +81,53 @@ namespace xcharts
{
public bool show;
public int DataIndex { get; set; }
public int LastDataIndex { get; set; }
public float Width { get { return bgRect.sizeDelta.x; } }
public float Height { get { return bgRect.sizeDelta.y; } }
private GameObject gameObject;
private Text text;
private RectTransform bgRect;
public void SetObj(GameObject obj)
{
gameObject = obj;
bgRect = gameObject.GetComponent<RectTransform>();
text = gameObject.GetComponentInChildren<Text>();
}
public void SetBackgroundColor(Color color)
{
gameObject.GetComponent<Image>().color = color;
}
public void SetTextColor(Color color)
{
text.color = color;
}
public void UpdateTooltipText(string txt)
{
text.text = txt;
bgRect.sizeDelta = new Vector2(text.preferredWidth + 8, text.preferredHeight + 8);
}
public void SetActive(bool flag)
{
gameObject.SetActive(flag);
}
public void UpdatePos(Vector2 pos)
{
gameObject.transform.localPosition = pos;
}
public Vector3 GetPos()
{
return gameObject.transform.localPosition;
}
}
[System.Serializable]
@@ -155,6 +202,8 @@ namespace xcharts
[SerializeField]
protected Legend legend = new Legend();
[SerializeField]
protected Tooltip tooltip = new Tooltip();
[SerializeField]
protected List<Series> seriesList = new List<Series>();
private Theme checkTheme = 0;
@@ -165,7 +214,7 @@ namespace xcharts
protected List<Text> legendTextList = new List<Text>();
protected float chartWid { get { return rectTransform.sizeDelta.x; } }
protected float chartHig { get { return rectTransform.sizeDelta.y; } }
protected override void Awake()
{
themeInfo = ThemeInfo.Dark;
@@ -174,6 +223,7 @@ namespace xcharts
rectTransform.pivot = Vector2.zero;
InitTitle();
InitLegend();
InitTooltip();
}
protected virtual void Update()
@@ -181,11 +231,12 @@ namespace xcharts
CheckTheme();
CheckTile();
CheckLegend();
CheckTooltip();
}
protected override void OnDestroy()
{
for(int i = transform.childCount - 1; i >= 0; i--)
for (int i = transform.childCount - 1; i >= 0; i--)
{
DestroyImmediate(transform.GetChild(i).gameObject);
}
@@ -244,7 +295,7 @@ namespace xcharts
break;
case Align.right:
anchor = TextAnchor.MiddleRight;
titlePosition = new Vector3(chartWid - title.right - titleWid,
titlePosition = new Vector3(chartWid - title.right - titleWid,
chartHig - title.top, 0);
break;
case Align.center:
@@ -271,7 +322,7 @@ namespace xcharts
{
LegendData data = legend.dataList[i];
Button btn = ChartUtils.AddButtonObject(LEGEND_TEXT + i, transform, themeInfo.font,
themeInfo.textColor, Vector2.zero,Vector2.zero, Vector2.zero,
themeInfo.textColor, Vector2.zero, Vector2.zero, Vector2.zero,
new Vector2(legend.itemWidth, legend.itemHeight));
legend.dataList[i].button = btn;
Color bcolor = data.show ? themeInfo.GetColor(i) : themeInfo.unableColor;
@@ -282,7 +333,8 @@ namespace xcharts
btn.onClick.AddListener(delegate ()
{
data.show = !data.show;
btn.GetComponent<Image>().color = data.show ? themeInfo.GetColor(i) : themeInfo.unableColor;
btn.GetComponent<Image>().color = data.show ?
themeInfo.GetColor(i) : themeInfo.unableColor;
OnYMaxValueChanged();
OnLegendButtonClicked();
RefreshChart();
@@ -290,6 +342,15 @@ namespace xcharts
}
}
private void InitTooltip()
{
GameObject obj = ChartUtils.AddTooltipObject("tooltip", transform,themeInfo.font);
tooltip.SetObj(obj);
tooltip.SetBackgroundColor(themeInfo.tooltipBackgroundColor);
tooltip.SetTextColor(themeInfo.tooltipTextColor);
tooltip.SetActive(false);
}
private Vector3 GetLegendPosition(int i)
{
int legendCount = legend.dataList.Count;
@@ -319,8 +380,8 @@ namespace xcharts
float offset = (chartHig - legendHig) / 2;
startY = chartHig - offset - legend.itemHeight;
}
float posX = legend.location == Location.left ?
legend.left :
float posX = legend.location == Location.left ?
legend.left :
chartWid - legend.right - legend.itemWidth;
return new Vector3(posX, startY - i * (legend.itemHeight + legend.itemGap), 0);
default: break;
@@ -341,7 +402,7 @@ namespace xcharts
private void CheckTheme()
{
if(checkTheme != theme)
if (checkTheme != theme)
{
checkTheme = theme;
OnThemeChanged();
@@ -350,6 +411,7 @@ namespace xcharts
private void CheckTile()
{
if (checkTitle == null || title == null) return;
if (checkTitle.align != title.align ||
checkTitle.left != title.left ||
checkTitle.right != title.right ||
@@ -394,6 +456,27 @@ namespace xcharts
}
}
private void CheckTooltip()
{
if (!tooltip.show) return;
tooltip.DataIndex = 0;
Vector2 local;
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform,
Input.mousePosition, null, out local))
return;
if (local.x < 0 || local.x > chartWid ||
local.y < 0 || local.y > chartHig)
return;
CheckTootipArea(local);
}
protected virtual void CheckTootipArea(Vector2 localPostion)
{
}
protected virtual void OnThemeChanged()
{
switch (theme)
@@ -422,10 +505,10 @@ namespace xcharts
for (int i = 0; i < legend.dataList.Count; i++)
{
Button btn = legend.dataList[i].button;
btn.GetComponent<RectTransform>().sizeDelta =
btn.GetComponent<RectTransform>().sizeDelta =
new Vector2(legend.itemWidth, legend.itemHeight);
Text txt = btn.GetComponentInChildren<Text>();
txt.transform.GetComponent<RectTransform>().sizeDelta =
txt.transform.GetComponent<RectTransform>().sizeDelta =
new Vector2(legend.itemWidth, legend.itemHeight);
txt.transform.localPosition = Vector3.zero;
btn.transform.localPosition = GetLegendPosition(i);
@@ -453,10 +536,24 @@ namespace xcharts
rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, tempWid);
}
protected virtual void RefreshTooltip()
{
}
protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
DrawBackground(vh);
DrawChart(vh);
DrawTooltip(vh);
}
protected virtual void DrawChart(VertexHelper vh)
{
}
protected virtual void DrawTooltip(VertexHelper vh)
{
}
private void DrawBackground(VertexHelper vh)
@@ -469,4 +566,5 @@ namespace xcharts
ChartUtils.DrawPolygon(vh, p1, p2, p3, p4, themeInfo.backgroundColor);
}
}
}
}

View File

@@ -24,6 +24,10 @@ namespace xcharts
public Color axisLineColor;
public Color axisSplitLineColor;
public Color tooltipBackgroundColor;
public Color tooltipFlagAreaColor;
public Color tooltipTextColor;
public Color[] colorPalette;
public Color GetColor(int index)
@@ -46,6 +50,8 @@ namespace xcharts
subTextColor = theme.subTextColor;
axisLineColor = theme.axisLineColor;
axisSplitLineColor = theme.axisSplitLineColor;
tooltipBackgroundColor = theme.tooltipBackgroundColor;
tooltipTextColor = theme.tooltipTextColor;
colorPalette = new Color[theme.colorPalette.Length];
for(int i = 0; i < theme.colorPalette.Length; i++)
{
@@ -67,6 +73,9 @@ namespace xcharts
subTextColor = GetColor("#514D4D"),
axisLineColor = GetColor("#514D4D"),
axisSplitLineColor = GetColor("#AB9999"),
tooltipBackgroundColor = GetColor("#515151B5"),
tooltipTextColor = GetColor("#FFFFFFFF"),
tooltipFlagAreaColor = GetColor("#51515120"),
colorPalette = new Color[]
{
new Color32(194, 53, 49, 255),
@@ -99,6 +108,9 @@ namespace xcharts
subTextColor = GetColor("#514D4D"),
axisLineColor = GetColor("#514D4D"),
axisSplitLineColor = GetColor("#AB9999"),
tooltipBackgroundColor = GetColor("#515151B5"),
tooltipTextColor = GetColor("#FFFFFFFF"),
tooltipFlagAreaColor = GetColor("#51515120"),
colorPalette = new Color[]
{
new Color32(55, 162, 218, 255),
@@ -133,6 +145,9 @@ namespace xcharts
subTextColor = GetColor("#eee"),
axisLineColor = GetColor("#eee"),
axisSplitLineColor = GetColor("#aaa"),
tooltipBackgroundColor = GetColor("#515151B5"),
tooltipTextColor = GetColor("#FFFFFFFF"),
tooltipFlagAreaColor = GetColor("#51515120"),
colorPalette = new Color[]
{
new Color32(221, 107, 102, 255),

View File

@@ -38,11 +38,11 @@ namespace xcharts
txtObj.GetComponent<Text>().alignment = anchor;
RectTransform rect = txtObj.GetComponent<RectTransform>();
rect.localPosition = Vector3.zero;
rect.sizeDelta = sizeDelta;
rect.anchorMin = anchorMin;
rect.anchorMax = anchorMax;
rect.pivot = pivot;
rect.localPosition = Vector3.zero;
return txtObj.GetComponent<Text>();
}
@@ -82,6 +82,40 @@ namespace xcharts
return btnObj.GetComponent<Button>();
}
public static GameObject AddTooltipObject(string name,Transform parent, Font font)
{
GameObject tooltipObj;
if (parent.Find(name))
{
tooltipObj = parent.Find(name).gameObject;
tooltipObj.SetActive(true);
}
else
{
tooltipObj = new GameObject();
tooltipObj.name = name;
tooltipObj.transform.parent = parent;
tooltipObj.transform.localPosition = Vector3.zero;
tooltipObj.transform.localScale = Vector3.one;
tooltipObj.AddComponent<Image>();
Text txt = AddTextObject("Text", tooltipObj.transform, font, Color.white, TextAnchor.UpperLeft,
new Vector2(0, 1), new Vector2(0, 1), new Vector2(0, 1), new Vector2(100, 100));
txt.text = "Text";
}
RectTransform rect = tooltipObj.GetComponent<RectTransform>();
if (rect == null)
{
rect = tooltipObj.AddComponent<RectTransform>();
}
tooltipObj.GetComponent<Image>().color = Color.black;
rect.anchorMax = new Vector2(0, 1);
rect.anchorMin = new Vector2(0, 1);
rect.pivot = new Vector2(0, 1);
rect.sizeDelta = new Vector2(100, 100);
tooltipObj.GetComponentInChildren<Text>().transform.localPosition = new Vector2(3,-3);
return tooltipObj;
}
public static void DrawLine(VertexHelper vh, Vector3 p1, Vector3 p2, float size, Color color)
{
Vector3 v = Vector3.Cross(p2 - p1, Vector3.forward).normalized * size;
@@ -334,6 +368,5 @@ namespace xcharts
return curvedPoints;
}
}
}

View File

@@ -38,9 +38,9 @@ namespace xcharts
base.Update();
}
protected override void OnPopulateMesh(VertexHelper vh)
protected override void DrawChart(VertexHelper vh)
{
base.OnPopulateMesh(vh);
base.DrawChart(vh);
int seriesCount = seriesList.Count;
float max = GetMaxValue();
float scaleWid = coordinateWid / (xAxis.splitNumber - 1);
@@ -99,21 +99,35 @@ namespace xcharts
Vector3 p = new Vector3(startX + i * scaleWid,
zeroY + data.value * coordinateHig / max);
if(theme == Theme.Dark)
float pointWid = lineInfo.pointWid;
if (tooltip.show && i == tooltip.DataIndex - 1)
{
ChartUtils.DrawCricle(vh, p, lineInfo.pointWid, color,
pointWid = pointWid * 1.8f;
}
if (theme == Theme.Dark)
{
ChartUtils.DrawCricle(vh, p, pointWid, color,
(int)lineInfo.pointWid * 5);
}
else
{
ChartUtils.DrawCricle(vh, p, lineInfo.pointWid, Color.white);
ChartUtils.DrawDoughnut(vh, p, lineInfo.pointWid - lineInfo.tickness,
lineInfo.pointWid, 0, 360, color);
ChartUtils.DrawCricle(vh, p, pointWid, Color.white);
ChartUtils.DrawDoughnut(vh, p, pointWid - lineInfo.tickness,
pointWid, 0, 360, color);
}
}
}
}
//draw tooltip line
if (tooltip.show && tooltip.DataIndex > 0)
{
float splitWid = coordinateWid / (xAxis.splitNumber - 1);
float px = zeroX + (tooltip.DataIndex - 1) * splitWid + (xAxis.boundaryGap ? splitWid / 2 : 0);
Vector2 sp = new Vector2(px, zeroY);
Vector2 ep = new Vector2(px, zeroY + coordinateHig);
ChartUtils.DrawLine(vh, sp, ep, coordinate.tickness, themeInfo.tooltipFlagAreaColor);
}
}
}
}

View File

@@ -44,9 +44,9 @@ namespace xcharts
base.Update();
}
protected override void OnPopulateMesh(VertexHelper vh)
protected override void DrawChart(VertexHelper vh)
{
base.OnPopulateMesh(vh);
base.DrawChart(vh);
UpdatePieCenter();
float totalDegree = 360;
float startDegree = 0;

View File

@@ -135,18 +135,14 @@ namespace xcharts
return new Vector3(x,y);
}
protected override void OnPopulateMesh(VertexHelper vh)
protected override void DrawChart(VertexHelper vh)
{
base.OnPopulateMesh(vh);
base.DrawChart(vh);
UpdateRadarCenter();
if (radarInfo.cricle)
{
DrawCricleRadar(vh);
}
else
{
DrawRadar(vh);
}
DrawData(vh);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: a142bb574d9f48c4fa8f0375629732e8
timeCreated: 1539696983
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: