原創(chuàng)|其它|編輯:郝浩|2012-12-24 15:27:04.000|閱讀 2865 次
概述:Chart FX for WPF有著一個強大的功能:XYZExtension。這個功能將能夠使得我們在一個3D圖表上添加或控制第三個軸。個人覺得最新的這個SurfaceXYZ圖表最炫的功能就是創(chuàng)使用來自不同城市的數(shù)據(jù)創(chuàng)建地在理位置上精確的表面。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關(guān)鏈接:
Chart FX for WPF有著一個強大的功能:XYZExtension。這個功能將能夠使得我們在一個3D圖表上添加或控制第三個軸。個人覺得最新的這個SurfaceXYZ圖表最炫的功能就是創(chuàng)使用來自不同城市的數(shù)據(jù)建地理位置上精確的表面。這個功能可以用于很多的地方,比如說圖表繪制、每個城市會甚至是一個國家的總銷售收入等。
在本次的示例中,我們假設(shè)需要顯示整個佛羅里達超過800家店的客戶滿意度,我們將按照城市的字母順序,然而定位指定商店的分數(shù)是非常容易的,但是難的是了解國家哪些區(qū)域的商店比其他的地方做的更好,并將其繪制在表面上。在另一方面,將會打組所有接近的商店,這樣就會很好的找到最好和最差的區(qū)域時哪里,這種情況特別適合于一個國家的地圖,最終的效果將會如下所示:
選擇一張地圖,我選擇了Mercator墨卡托投影的地圖,也許你還沒注意到,我們已將這個所選的地圖放在了表面。這樣做是因為用于表面的三角測量法將會插入所有的數(shù)據(jù)到我們的表面上,從墨西哥灣商店的數(shù)據(jù)收集來造成一種假象。值得注意的是,我們將這張圖蓋住了城市是透明的區(qū)域,這樣的話,非透明的海洋將會覆蓋插入的數(shù)據(jù)就會顯得沒有意義。下面是我們沒有表面的地圖的樣子。
現(xiàn)在已經(jīng)選擇了地圖,來看看數(shù)據(jù)資料:
<Store CITY="MIAMI" LATITUDE="25.64" LONGITUDE="-80.32" SCORE="91" /> <Store CITY="NORTH MIAMI BEAC" LATITUDE="25.94" LONGITUDE="-80.14" SCORE="89" /> <Store CITY="NORTH MIAMI" LATITUDE="25.89" LONGITUDE="-80.18" SCORE="91" /> <Store CITY="NORTH MIAMI BEAC" LATITUDE="25.93" LONGITUDE="-80.18" SCORE="91" /> <Store CITY="OLYMPIA HEIGHTS" LATITUDE="25.74" LONGITUDE="-80.36" SCORE="92" /> <Store CITY="MIAMI SPRINGS" LATITUDE="25.82" LONGITUDE="-80.30" SCORE="92" />
我們有著商店的經(jīng)度和緯度,這將會值得通過GPS找到這個位置非常的容易。接下來,我們要將它轉(zhuǎn)化成在我們隨所挑選的地圖上的像素值,由于這是一個墨卡托投影,使用下面的公式來進行轉(zhuǎn)換(φ表示的是經(jīng)度,λ表示的是緯度)。
一旦將我們的數(shù)據(jù)格式化之后,就可以將數(shù)據(jù)傳遞到圖表,看看會得到什么樣的結(jié)果:
SurfaceXYZ surfaceXYZ = new SurfaceXYZ(); surfaceXYZ.ShowPointsGridlines = false; surfaceXYZ.ShowSeriesGridlines = false; surfaceXYZ.ShowContourLines = true; chart1.ItemsSource = chartData; SeriesAttributes series0 = new SeriesAttributes(); SeriesAttributes series1 = new SeriesAttributes(); series0.GalleryAttributes = surfaceXYZ; series1.GalleryAttributes = surfaceXYZ; series0.BindingPath = "Score"; series0.BindingPathX = "X"; series1.BindingPath = "Y"; chart1.Series.Add(series0); chart1.Series.Add(series1);
值得注意的是,我們在這里需要兩個系列的XYZ圖表,第二個圖表將會被綁定到Z數(shù)據(jù),但是由于我們希望在上面的表面是以一種二維的方式,我們將它稱為“Y”(在地圖上或是在緯度上)。Y軸表示著我們正在傳遞的值,如果這不是二維的圖表,它將會代表著深度或高度。
在表面多余的代碼,依然會有用,如果在圖表上做一些變動使它變成輪廓。
ChartFX.WPF.View3D view3D = chart1.View3D; view3D.IsEnabled = true; view3D.AngleX = -90; view3D.AngleY = 0; view3D.Projection = Projection.Orthographic; view3D.BackWallVisibility = Visibility.Collapsed; chart1.AxisX.Line.Visibility = Visibility.Hidden; chart1.AxisX.Grids.Major.Visibility = Visibility.Hidden; view3D.Lights.Clear(); System.Windows.Media.Media3D.AmbientLight ambLight = new System.Windows.Media.Media3D.AmbientLight(Color.FromRgb(0xD0, 0xD0, 0xD0)); view3D.Lights.Add(ambLight);
如果你仔細看會發(fā)現(xiàn),這個“Florida shape”看起來有一點扭曲,這個主要是因為我們的輪廓是放置在一個平面上的,而不是我們選擇的地圖的比例設(shè)置。此外,在X軸和Z軸上的最大值并不是在我們地圖上使用的值。以上將會扭曲我們的表面,使得我們的數(shù)據(jù)表現(xiàn)的不切實際,如果想要修復這個問題,可以采用下面的代碼實現(xiàn):
chart1.AxisX.Max = 820; //Height of the bitmap chart1.AxisX.Min = 0; XYZExtension xyzExtension = new XYZExtension(); xyzExtension.AxisZ.Max = 772; //Width of the bitmap xyzExtension.AxisZ.Min = 0; chart1.Extensions.Add(xyzExtension); chart1.View3D.Depth = 94.1463; //Width divided by Height
注意我們使用的是XYZExtension來控制Z軸的最大和最小值,然后設(shè)置我們Z軸和X軸的最大和最小值為地圖的大小,同時還改變了Depth屬性為地圖的比例(值能是最大程度上的接近),這個Depth屬性其實主要是控制Z軸的尺寸。
現(xiàn)在我們需要做的就是把這個地圖置頂,在這里有個小竅門,我們將會創(chuàng)建一個ImageBrush,用來繪制圖表的地部(X軸),以及重置底部的圖表到頂部。
chart1.AxisX.Position = AxisPosition.Far; ImageBrush mapBrush = new ImageBrush(); mapBrush.Stretch = Stretch.Fill; mapBrush.ImageSource = new BitmapImage(new Uri("pack://siteoforigin:,,,/Resources/FloridaMap.png")); chart1.AxisX.Background = mapBrush; chart1.View3D.Wall.Thickness = 1;
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:慧都控件