1. 程式人生 > >Unity3D資料視覺化控制元件的簡單實現-Mysql資料庫

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;
	}