Unity3D資料視覺化控制元件的簡單實現-Mysql資料庫
專案實現的是比較簡易的資料視覺化,用到Mysql資料庫和Unity3D中的Graph_Maker.
直接上實現圖,通過輸入資料庫名、賬號、密碼、資料表名跳轉
展示效果為Graph_Maker中的折線圖,X軸和Y軸座標內容可以手動更改,滑鼠指標滑動到資料點時能夠顯示更多資訊。(即為綠底白字內容)
一、資料讀入
利用Mysql.Data.Dll實現與Mysql資料庫的連線,啟動連線後使用MysqlCommand執行sql語句,本專案就是簡單的Select *,查詢出來的資料我以DataSet格式進行儲存
public static void OpenSql(string id, string pwd, string database) { string connectionString = string.Format("Server = {0};port={4};Database = {1}; User ID = {2}; Password = {3};", host, database, id, pwd, "3306"); dbConnection = new MySqlConnection(connectionString); dbConnection.Open(); } public DataSet SelectWhere(string tableName) { string selstr = "select * from " + tableName ; MySqlCommand myselect = new MySqlCommand(selstr, dbConnection); DataSet ds = new DataSet(); try { MySqlDataAdapter da = new MySqlDataAdapter(selstr, dbConnection); da.Fill(ds); Debug.Log("Select success!"); } catch (Exception ee) { throw new Exception("SQL: " + selstr + "\n" + ee.Message.ToString()); } return ds; }
然後為了改變Graph_Maker裡X、Y軸的內容,我需要將DataSet裡的資料區分出來
OpenSql(username,userpwd,database); DataSet ds = SelectWhere(tabname); string result; result = ds.ToString(); int rows = ds.Tables[0].Rows.Count; List<string> deta = new List<string>(); List<float> minTemp = new List<float>(); List<float> maxTemp = new List<float>(); List<string> condition = new List<string>(); List<Vector2> minmax = new List<Vector2>(); for (int i = 0; i < rows; i++) { deta.Add(ds.Tables[0].Rows[i][0].ToString()); minTemp.Add(float.Parse(ds.Tables[0].Rows[i][1].ToString())); maxTemp.Add(float.Parse(ds.Tables[0].Rows[i][2].ToString())); minmax.Add(new Vector2(minTemp[i], maxTemp[i]));
condition.Add(ds.Tables[0].Rows[i][3].ToString());
// Debug.Log(ds.Tables[0].Rows[i][3]);
}
在這裡為了方便理解,我把資料庫中的資料格式和程式碼中的List含義說明一下,其中minmax就是一個儲存最大值最小值的二維列表
二、繪製折線圖
拿到我們想要的資料之後我們開始繪製折線圖,折線圖的基本展示你可以從Graph_Maker的樣例場景中找到Graphs_Test,裡面有三種圖表的展示,我們利用到的是其中的折線圖,即LineGraph,你可以把他的LineGraph直接複製到自己的專案中,UI效果稍作更改即可。(下面是Graph_Test直接展示的效果)
樣例中自帶的LineGraph由三部分組成,Background是UI圖形,Series是是動態繪製的資料點,Tooltip是滑鼠移動到資料點顯示出的視窗。我們通過修改Graph_Maker中的方法來實現想要的展示效果。
WMG_Axis_Graph LineGraph = GameObject.Find("LineGraph").GetComponent<WMG_Axis_Graph>();
List<float> temp = new List<float>();
for(int i = 0; i < rows; i++)
{
temp.Add((minTemp[i] + maxTemp[i]) / 2);
}
List<Vector2> mSeriesData = new List<Vector2>();
for (int i = 0; i < temp.Count; i++)
{
mSeriesData.Add(new Vector2(i + 1, temp[i]));
}
WMG_Series mSeries = GameObject.Find("Series2").GetComponent<WMG_Series>();
mSeries._pointValues = mSeriesData;
LineGraph.xAxis._axisLabels = deta;
LineGraph.yAxis.AxisMinValue = 10;
LineGraph.yAxis.AxisMaxValue = 40;
LineGraph.yAxis.AxisNumTicks = 15;
mSeries.tempvalue = minmax;
mSeries.condition = condition;
首先是獲取要繪製的LineGraph,把我們要用到的資料處理一下,temp是最小氣溫和最大氣溫的平均值,mSeriesData表示折線圖中的資料,第i天的氣溫。
之後我們再獲取繪製資料點的遊戲窗體,並對它進行賦值,Graph_Maker中的WMG_Axis_Graph腳本里xAxis表示橫座標,yAxis表示縱座標。
最後我們要完成滑鼠滑動到資料點的詳細資訊顯示部分,通過重寫WMG_Series指令碼和WMG_Graph_Tooltip指令碼中的方法實現,首先在WMG_Series指令碼中新增三個方法,即為獲取當前資料點的資訊getNodeValue(),獲取溫度的詳細資訊getTemp(),獲取天氣狀況的getCondition()。
public Vector2 getNodeValue(WMG_Node aNode) {
for (int i = 0; i < pointValues.Count; i++) {
if (points[i].GetComponent<WMG_Node>() == aNode) return pointValues[i];
}
return Vector2.zero;
}
public Vector2 getTemp(WMG_Node anode)
{
for (int i = 0; i < pointValues.Count; i++)
{
if (points[i].GetComponent<WMG_Node>() == anode) return tempvalue[i];
}
return Vector2.zero;
}
public string getcondition(WMG_Node anode)
{
for (int i = 0; i < pointValues.Count; i++)
{
if (points[i].GetComponent<WMG_Node>() == anode) return condition[i];
}
return "";
}
然後重寫WMG_Graph_Tooltip指令碼中的defaultTooltipLabeler()方法,更改Tooltip的顯示。
private string defaultTooltipLabeler(WMG_Series aSeries, WMG_Node aNode) {
// Find out the point value data for this node
Vector2 nodeData = aSeries.getNodeValue(aNode);
Vector2 temp = aSeries.getTemp(aNode);
string condition = aSeries.getcondition(aNode);
float numberToMult = Mathf.Pow(10f, aSeries.theGraph.tooltipNumberDecimals);
string nodeX = (Mathf.Round(nodeData.x*numberToMult)/numberToMult).ToString();
string nodeY = (Mathf.Round(nodeData.y*numberToMult)/numberToMult).ToString();
// Determine the tooltip text to display
string textToSet;
textToSet = "最低氣溫:" + nodeData.x.ToString() + " 最高氣溫:" + nodeData.y.ToString() +"\n"+ " 天氣狀況:" + condition;
return textToSet;
}