項目過程中所遇到的各種問題記錄——有關MSChart的一些小技巧
完成了有關編輯器篇的內容,接下來記錄下這一年里在有關圖表使用過程中碰到的一些問題及個人的解決方法。
以下是本文所要介紹的內容:
1、MSChart基本概況介紹。
2、開發過程中碰到的問題及解決方法。
一、MSChart基本概況介紹
在開發一些管理系統的時候總會碰到一些需求需要對報表進行圖形化的展示——圖表,在微軟的MSChart沒出來前,.NET的winforms下許多的圖表控件不是要收費就是可使用的圖表類型較少或者各種資料太少(也可能是我了解的太少),不過自從在VS2008上微軟推出了MSChart后,在winforms上進行圖表統計就方便了很多很多。
MSChart分為2個部分,一個是winforms版本,另一個是webform版,并且都提供了相應的示例程序(超過200個示例代碼,并包括C#版本和VB.NET版本,其中內置了多種圖表類型,基本上涵蓋了各行各業的所需的圖表類型),使得開發者可以根據需求快速的找到自己所需的圖表類型,同時查看示例代碼可以馬上上手進行開發,如下圖:
當然本文不是介紹MSChart的具體是如何使用的,上面僅僅是對MSChart進行各簡單性的介紹,本文主要介紹的內容還是在我開發過程中碰到問題。
二、開發過程中碰到的問題及解決方法
現在開始介紹下我所碰到的幾個問題:
1、如果在對于統計的類別數量不可數的情況下,如何解決生成的每個類別有不同的列?
在公司年初開發的一個winforms程序中需要對用戶自己定義的分類數據進行統計,而用戶所創建的分類數量又是不定的(但不能超過10個),這時就碰到個問題:就是MSChart圖表中的列如果想做的好看,吸引眼球需要進行大量的配置,比如:列的顏色、邊框寬度、陰影等等,而每個用戶建立的分類對應著一個列,本來的設想是根據數量動態生成對應的列,但是在實際的開發過程中,如果要保證每個列的樣式達到統一,且顏色等又要區分的話,使用代碼來動態生成太過于復雜。
我就想到了個不是辦法的辦法,就是由于用戶自定義的分類是不可能超過10個的,所以我就事先在圖標中建立好了10個列,根據用戶建立的分類數量來對這些已經建立好的列進行數據填充,而那些沒有填充數據的列就不會出現,這樣的解決辦法雖然比較的傻,但是實際的效果很不錯,畢竟動態創建的列要保證樣式統一需要花時間調試,而且不像直接通過配置創建出來的列那么直觀,見下圖:
2、實現類似于CNZZ流量統計形式的點選分類突出顯示
使用過CNZZ統計的朋友肯定知道,CNZZ對訪問者的來源統計展示形式是一個餅狀展示的,同時通過某塊區域時可以突出顯示這個區域,如下圖:
可以看到,我通過點擊【江蘇省】,將這塊區域突出顯示了,這個功能雖然不起眼,但是在實際公司的使用過程中,比如開會的時候有針對性的介紹某塊內容的時候就會使用到,而如果在winforms下使用MSChart如何實現呢?如果想通過MSChart實現這樣的效果就需要數據列中具體值(DataPoint)的CustomProperties來實現,代碼如下(VB.NET
{
HitTestResult result = chartPerformance.HitTest(e.X, e.Y);
if (result.PointIndex == -1) {
return;
}
bool exploded = (chartPerformance.Series(0).Points(result.PointIndex).CustomProperties == "Exploded=true" ? true : false);
DataPoint point = default(DataPoint);
foreach ( point in chartPerformance.Series(0).Points) {
point.CustomProperties = "";
}
if (exploded) {
return;
}
//點擊具體列
if (result.ChartElementType == ChartElementType.DataPoint) {
DataPoint dPoint = chartPerformance.Series(0).Points(result.PointIndex);
dPoint.CustomProperties = "Exploded = true";
if (((List<ModelClass>)dPoint.Tag).Count == 0) {
return;
}
}
//點擊圖例
if (result.ChartElementType == ChartElementType.LegendItem) {
DataPoint dPoint = chartPerformance.Series(0).Points(result.PointIndex);
dPoint.CustomProperties = "Exploded = true";
if (((List<ModelClass>)dPoint.Tag).Count == 0) {
return;
}
}
}
這段代碼的主要步驟是:
1、為圖表控件增加一個MouseDown事件
2、獲取圖表控件當前點擊的坐標,并判斷是否存在
3、判斷點擊的對象是具體的列還是圖例,然后為點擊的圖例增加相應的屬性:CustomProperties = "Exploded = true";
具體的效果如下:
可以看到圖表中,【優】列已經被分離突出顯示了。此時我們還可以為這個表增加一些類似于網頁開發中的MouseOver、MouseLeave效果,以達到更好的用戶體驗,如下圖:
可以看到圖片上【中】列和圖例上的上面明顯有一層格子狀網線,這樣可以告訴使用者當先所選的列,實現代碼如下:
{
HitTestResult result = chartPerformance.HitTest(e.X, e.Y);
if (result == null) {
return;
}
DataPoint point = default(DataPoint);
foreach ( point in chartPerformance.Series(0).Points) {
point.BackSecondaryColor = Color.Black;
point.BackHatchStyle = ChartHatchStyle.None;
point.BorderWidth = 1;
}
if (result.ChartElementType == ChartElementType.DataPoint | result.ChartElementType == ChartElementType.LegendItem) {
this.Cursor = Cursors.Hand;
DataPoint dPoint = chartPerformance.Series(0).Points(result.PointIndex);
dPoint.BackSecondaryColor = Color.White;
dPoint.BackHatchStyle = ChartHatchStyle.Percent25;
dPoint.BorderWidth = 2;
}
else {
this.Cursor = Cursors.Default;
}
}
這段代碼的實現步驟是:
1、獲取當前點擊的坐標。
2、遍歷所有具體的點及圖例為其增加一個背景樣式,及鼠標手勢。