可以与TextMesh Pro一起使用 Assets---Graph Maker--UGUI==>Tep prefab
可改写性很高,下面是我做的简单示例
下面是显示多条曲线的文本值,首先在WMG_Axis_Graph脚本添加两个属性
private List<WMG_Change_Obj> changeObjs = new List<WMG_Change_Obj>();
public WMG_Change_Obj graphC = new WMG_Change_Obj();
public WMG_Change_Obj resizeC = new WMG_Change_Obj();
public WMG_Change_Obj seriesCountC = new WMG_Change_Obj();
public WMG_Change_Obj seriesNoCountC = new WMG_Change_Obj();
private WMG_Change_Obj tooltipEnabledC = new WMG_Change_Obj();
private WMG_Change_Obj autoAnimEnabledC = new WMG_Change_Obj();
private WMG_Change_Obj orientationC = new WMG_Change_Obj();
private WMG_Change_Obj graphTypeC = new WMG_Change_Obj();
public delegate void GraphBackgroundChangedHandler(WMG_Axis_Graph aGraph);
public event GraphBackgroundChangedHandler GraphBackgroundChanged;
//==============================================================需要添加的属性
// [Header("是否显示所有xy标签")]
[SerializeField] private bool _IsShowAllSeries;
public bool IsShowAllSeries
{
get { return _IsShowAllSeries; }
set
{
if (value != _IsShowAllSeries)
_IsShowAllSeries = value;
}
}
// [Header("展示X轴是否使用年月日")]
[SerializeField] private bool _Is_X_AXiesUseYear;
public bool Is_X_AXiesUseYear
{
get { return _Is_X_AXiesUseYear; }
set
{
if (value != _Is_X_AXiesUseYear)
_Is_X_AXiesUseYear = value;
}
}
//添加指示线条
public Object X_Axis_LinkShow;
//=======================================================================
protected virtual void OnGraphBackgroundChanged() {
GraphBackgroundChangedHandler handler = GraphBackgroundChanged;
if (handler != null) {
handler(this);
}
}
void Start() {
Init ();
PauseCallbacks();
AllChanged();
}
然后修改WMG_Axis_Graph_E脚本内容
void DrawCore() {
ExposeProperty(fields["graphType"]);
ExposeProperty(fields["orientationType"]);
ExposeProperty(fields["axesType"]);
ExposeProperty(fields["resizeEnabled"]);
ExposeEnumMaskProperty(fields["resizeProperties"]);
ExposeProperty(fields["useGroups"]);
ArrayGUIoc<string> (graph.groups, "Groups", "_groups");
ArrayGUI("Series", "lineSeries");
ExposeProperty(fields["paddingLeftRight"]);
ExposeProperty(fields["paddingTopBottom"]);
ExposeProperty(fields["theOrigin"]);
ExposeProperty(fields["barWidth"]);
ExposeProperty(fields["barAxisValue"]);
ExposeProperty(fields["autoUpdateOrigin"]);
ExposeProperty(fields["autoUpdateBarWidth"]);
ExposeProperty(fields["autoUpdateBarWidthSpacing"]);
ExposeProperty(fields["autoUpdateSeriesAxisSpacing"]);
ExposeProperty(fields["autoUpdateBarAxisValue"]);
ExposeProperty(fields["autoFitLabels"]);
ExposeProperty(fields["autoFitPadding"]);
//============================添加内容
ExposeProperty(fields["IsShowAllSeries"]);
ExposeProperty(fields["Is_X_AXiesUseYear"]);
graph.X_Axis_LinkShow = EditorGUILayout.ObjectField("X_Axis_LinkShow", graph.X_Axis_LinkShow, typeof(Object), false);
}
修改WMG_Axis_Graph脚本中defaultTooltipLabeler方法
private string defaultTooltipLabeler(WMG_Series aSeries, WMG_Node aNode) {
// Find out the point value data for this node
//Debug.Log(theGraph.lineSeries[0]);
Vector2 nodeData;
string textToSet="";
nodeData = aSeries.getNodeValue(aNode);
textToSet = SetStringText(aSeries, nodeData);
if(theGraph.IsShowAllSeries)
{
textToSet = null;
for (int i = 0; i < theGraph.lineSeries.Count; i++)
{
aSeries = theGraph.lineSeries[i].GetComponent<WMG_Series>();
for (int t = 0; t < aSeries.pointValues.Count; t++)
{
if (aSeries.pointValues[t].x == nodeData.x)
{
if (textToSet != null)
textToSet += "\n";
textToSet += SetStringText(aSeries, aSeries.pointValues[t]);
break;
}
}
}
}
return textToSet;
}
private string SetStringText(WMG_Series aSeries, Vector2 nodeData)
{
float numberToMult = Mathf.Pow(10f, aSeries.theGraph.tooltipNumberDecimals);
string nodeX="";
string textToSet="";
if (!theGraph.Is_X_AXiesUseYear)
nodeX = (Mathf.Round(nodeData.x * numberToMult) / numberToMult).ToString();
else
{
//nian
nodeX = LongDateTimeToDateTimeString(nodeData.x/10000);
}
string nodeY = (Mathf.Round(nodeData.y * numberToMult) / numberToMult).ToString();
textToSet = "(" + nodeX + ", " + nodeY + ")";
if (aSeries.theGraph.tooltipDisplaySeriesName)
{
textToSet = aSeries.seriesName + ": " + textToSet;
}
return textToSet;
}
/// <summary>
/// 时间戳转为日期
/// </summary>
/// <param name="longDateTime"></param>
/// <returns></returns>
public static string LongDateTimeToDateTimeString(double longDateTime, string format = "yyyy-MM-dd")
{
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
// long mTime = long.Parse(longDateTime.ToString());
// TimeSpan toNow = new TimeSpan(mTime);
return startTime.AddDays(longDateTime).ToString(format);
}
/// <summary>
/// 日期转为时间戳
/// </summary>
/// <param name="longDateTime"></param>
/// <returns></returns>
public static double DateTimeStringToLongDateTime(DateTime longDateTime, string format = "yyyy-MM-dd")
{
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
// long mTime = long.Parse(longDateTime.ToString());
// TimeSpan toNow = new TimeSpan(mTime);
return (longDateTime - startTime).TotalDays;
}
/// <summary>
/// 日期转为时间戳
/// </summary>
/// <param name="longDateTime"></param>
/// <returns></returns>
public static bool DateTimeStringToLongDateTime(string longDateTime, out double TotalDateTime,string format = "yyyy-MM-dd")
{
DateTime endtime;
TotalDateTime = 0;
if (DateTime.TryParse(longDateTime,out endtime))
{
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
// long mTime = long.Parse(longDateTime.ToString());
// TimeSpan toNow = new TimeSpan(mTime);
TotalDateTime = (endtime - startTime).TotalDays;
return true;
}
return false;
}
指示标识线段,做个image预制体线条(注意:把它的射线检测给关掉),把它拉入我们刚刚修改的WMG_Axis_Graph脚本中的一个属性X_Axis_LinkShow里
修改MouseEnterCommon和MouseExitCommon方法
private void MouseEnterCommon(string textToSet, GameObject objToAnimate, Vector3 animTo) {
currentObj = objToAnimate;
//Debug.Log(theGraph.toolTipLabel);
// Set the text
changeLabelText(theGraph.toolTipLabel, textToSet);
// 调整此控件的大小以匹配内容的大小
changeSpriteWidth(theGraph.toolTipPanel, Mathf.RoundToInt(getSpriteWidth(theGraph.toolTipLabel)) + 24);
// 在显示工具提示之前,确保它处于正确的位置,这样它就不会出现跳转
repositionTooltip();
//展示线条
MouseShowX_Axis_Link(objToAnimate.transform.position);
StartCoroutine(delayedTooltipActive());
performTooltipAnimation(objToAnimate.transform, animTo);
}
private void MouseShowX_Axis_Link(Vector3 target)
{
if (theGraph.X_Axis_LinkShow != null)
{
Transform trans = theGraph.transform.Find(theGraph.X_Axis_LinkShow.name);
if (trans == null)
{
trans = Instantiate(theGraph.X_Axis_LinkShow as GameObject).transform;
trans.name = theGraph.X_Axis_LinkShow.name;
trans.GetComponent<RectTransform>().sizeDelta = new Vector2(2, theGraph.yAxis.AxisLine.GetComponent<RectTransform>().sizeDelta.y - theGraph.yAxis.AxisLinePadding);
trans.SetParent(theGraph.transform);
}
if (!trans.gameObject.activeInHierarchy)
{
showControl(trans.gameObject);
}
trans.position = new Vector3(target.x, theGraph.yAxis.AxisLine.GetComponent<RectTransform>().position.y - theGraph.yAxis.AxisLinePadding/2, 0);
}
}
private void MouseExitCommon(GameObject objToAnimate) {
hideControl(theGraph.toolTipPanel);
if (theGraph.X_Axis_LinkShow != null)
{
Transform trans = theGraph.transform.Find(theGraph.X_Axis_LinkShow.name);
if (trans != null)
hideControl(trans.gameObject);
}
sendSpriteToBack(theGraph.toolTipPanel);
performTooltipAnimation(objToAnimate.transform, Vector3.one);
}
如果我们想让他始终在图表范围内展示Tooltip信息的话,不让它超出界限,需要修改WMG_Graph_Tooltip脚本中的repositionTooltip方法
private void repositionTooltip() {
// 如果控件是可见的,则在更新期间会连续调用此方法,并且在显示可见之前也会调用一次,这样工具提示就不会出现跳转位置
// 将位置从“屏幕坐标”转换为“gui坐标”
Vector3 position;
RectTransformUtility.ScreenPointToWorldPointInRectangle(theGraph.toolTipPanel.GetComponent<RectTransform>(),
new Vector2(Input.mousePosition.x, Input.mousePosition.y),
(_canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : _canvas.worldCamera),
out position);
//如果没有偏移,工具提示的左下角将位于光标位置
float offsetX = theGraph.tooltipOffset.x;
float offsetY = theGraph.tooltipOffset.y;
// Center the control on the mouse/touch
// Debug.Log(position);
theGraph.toolTipPanel.transform.localPosition = theGraph.toolTipPanel.transform.parent.InverseTransformPoint(position) ;
EnsureTooltipStaysOnScreen(position, offsetX, offsetY);
}
void EnsureTooltipStaysOnScreen(Vector3 position, float offsetX, float offsetY) {
Vector3 newPos = theGraph.toolTipPanel.transform.position;
Vector2 mind = Vector2.zero;
ReturnYX_Axies(theGraph, ref mind);
Vector3[] corners = new Vector3[4];
offsetX *= _canvas.transform.localScale.x;
offsetY *= _canvas.transform.localScale.y;
((RectTransform)theGraph.toolTipPanel.transform).GetWorldCorners(corners);
var width = corners[2].x - corners[0].x;
var height = corners[1].y - corners[0].y;
if (position.x< mind.x && position.y< mind.y)
{
width = (width / 2);
height = height / 2;
//Debug.Log("左下");
}
else if (position.x < mind.x && position.y > mind.y)
{
offsetY = -offsetY;
width = (width/2);
height = -height / 2;
// Debug.Log("左上");
}
else if (position.x >= mind.x && position.y >= mind.y)
{
//Debug.Log("右上");
offsetX = -offsetX;
offsetY = -offsetY;
width = (-width/2);
height = (-height/2);
}
else if (position.x >= mind.x && position.y <= mind.y)
{
offsetX = -offsetX;
width = (-width/2);
height = (height/2);
Debug.Log("右下");
}
newPos = new Vector3(position.x + offsetX + width, position.y +offsetY + height);
theGraph.toolTipPanel.transform.position = newPos;
}
private static void ReturnYX_Axies(WMG_Axis_Graph _Graph,ref Vector2 mind )
{
mind = new Vector2(_Graph.xAxis.AxisLine.GetComponent<RectTransform>().position.x,_Graph.yAxis.AxisLine.GetComponent<RectTransform>().position.y);
}
最后需要把Tooltip中的Pivot改为 0.5f,0.5f