最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于WPF實現(xiàn)帶明細(xì)的環(huán)形圖表

 更新時間:2022年08月18日 10:57:23   作者:普通的地球人  
這篇文章主要介紹了如何利用WPF繪制帶明細(xì)的環(huán)形圖表?,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)或工作有一定幫助,需要的可以參考一下

效果

明細(xì)用Popup實現(xiàn)的,錄gif時,Popup顯示不出來,不知道為什么,所以靜態(tài)圖湊合看吧

大體思路

圖表使用Arc+Popup實現(xiàn)

圖表分為兩部分,一是環(huán)形部分,一是標(biāo)注的明細(xì)部分.

環(huán)形部分使用Arc圖形表示.需要注意這個Arc是Blend里的圖形.用Blend建項目的話可以直接用,使用VS建項目需要添加引用 Microsoft.Expression.Drawing 在引用管理器=>程序集=>擴展 下(前提是已經(jīng)安裝了Blend)

明細(xì)部分使用Popup控件,IsOpen屬性綁定到Arc的IsMouseOver,也就是鼠標(biāo)進入圓弧的時候,Popup就打開顯示.

Popup內(nèi)部一個橢圓控件當(dāng)作背景,一個文字顯示,一個折線虛線化當(dāng)作指針

然后就是把Popup定位到對應(yīng)圓弧合適的位置去顯示(這里取的是圓弧的中間)

比較抱歉的是樣式比較丑陋,忽略吧,重點看定位.

圓弧部分

Arc有兩個重要的屬性:StartAngle起始角度和EndAngle終結(jié)角度.這兩個屬性決定了圓弧占所在圓環(huán)的比例.

每一個數(shù)據(jù)項就對應(yīng)一個圓弧,把所有圓弧都放到一個容器里,首尾相連

數(shù)據(jù)項的總和為100,那么所有圓弧也就組成一個完整的圓環(huán).

Popup明細(xì)部分

明細(xì)部分分為四種,見圖

橢圓

從圖可知,作為背景的橢圓分為兩種情況,小于180度,橢圓靠容器的右邊對齊,大于180度,靠容器的左邊對齊

也就是代碼的這部分:

Ellipse ell = new Ellipse() { Fill = brush };
//中間點角度小于180 明細(xì)靠右顯示 否則靠左顯示
Grid detailGrid = new Grid() { Width = _popupHeight, HorizontalAlignment = HorizontalAlignment.Right };
if (middleAngle > 180)
{
    detailGrid.HorizontalAlignment = HorizontalAlignment.Left;
}

折線

折線是分為四種,每一個角度區(qū)間都對應(yīng)一種

private Polyline GetPopupPolyline(double middleAngle)
{
    Polyline pLine = new Polyline() { Stroke = new SolidColorBrush(Color.FromRgb(0, 0, 0)), StrokeDashArray = new DoubleCollection(new double[] { 5, 2 }) };
    double x1 = 0, y1 = 0;
    double x2 = 0, y2 = 0;
    double x3 = 0, y3 = 0;
    if (middleAngle > 0 && middleAngle <= 90)
    {
        x1 = 0; y1 = _popupHeight;
        x2 = _popupWidth / 2; y2 = _popupHeight;
        x3 = _popupWidth * 3 / 4; y3 = _popupHeight / 2;
    }
    if (middleAngle > 90 && middleAngle <= 180)
    {
        x1 = 0; y1 = 0;
        x2 = _popupWidth / 2; y2 = 0;
        x3 = _popupWidth * 3 / 4; y3 = _popupHeight / 2;
    }
    if (middleAngle > 180 && middleAngle <= 270)
    {
        x1 = _popupWidth; y1 = 0;
        x2 = _popupWidth / 2; y2 = 0;
        x3 = _popupWidth / 4; y3 = _popupHeight / 2;
    }
    if (middleAngle > 270 && middleAngle <= 360)
    {
        x1 = _popupWidth; y1 = _popupHeight;
        x2 = _popupWidth / 2; y2 = _popupHeight;
        x3 = _popupWidth / 4; y3 = _popupHeight / 2;
    }
    pLine.Points.Add(new Point(x1, y1));
    pLine.Points.Add(new Point(x2, y2));
    pLine.Points.Add(new Point(x3, y3));
    return pLine;
}

Popup的定位

首先以0-90度為例,說明一些基本的東西,見圖

首先Popup默認(rèn)的位置,都是在它容器的左下方的,Popup的左上角和容器的左下角重合.

現(xiàn)在要做的是Popup標(biāo)記為紅點的位置,和圓環(huán)上標(biāo)記為紅點的位置重合.

先來回顧一下小時候?qū)W過的公式:

1.直角三角形 a=r*sinA

2.勾股定理 c^2=a^2+b^2 b=Sqrt(c^2-a^2)

上圖的直角三角形,角A的對邊為a,臨邊為b,斜邊為c.顯然c邊于圓的半徑r相等.注意:因為圓弧是有厚度的,所以取r的時候要減去二分之一的圓弧厚度.

角A是可以通過90度減去圓弧的對應(yīng)的角度求出來的,也就是sinA的值已知了,那么就可以求出a和b的長度,然后就可以去移動Popup了

一.0-90度

X軸:1.向右移動二分之一個容器的width 2.向右移動一個b的距離

Y軸:1.向上移動二分之一個容器的height 2.向上移動一個Popup的height 3.向上移動一個a的距離

二.90-180度

X軸:1.向右移動二分之一個容器的width 2.向右移動一個a的距離

Y軸:1.上移二分之一個圓弧的Thickness,以保證標(biāo)記的起點在圓弧的中央 2.上移一個(r-b)的距離

三.180-270度

X軸:1.向左移動一個b的距離

Y軸:1.上移二分之一個圓弧的Thickness,以保證標(biāo)記的起點在圓弧的中央 2.上移一個(r-a)的距離

四.270-360度

X軸:1.向左移動一個a的距離

Y軸:1.向上移動二分之一個容器的height 2.向上移動一個Popup的height 3.向上移動一個b的距離

代碼部分

private Popup GetPopup(double middleAngle)
{
    /*
     * 生成popup
     * 設(shè)置popup的offset 讓標(biāo)記線的起點 對應(yīng)到圓弧的中間點
     */
    Popup popup = new Popup() { Width = _popupWidth, Height = _popupHeight, AllowsTransparency = true, IsHitTestVisible = false };
    //直角三角形 a=r*sinA 勾股定理 c^2=a^2+b^2 b=Sqrt(c^2-a^2)
    double r = _chartSize / 2 - _arcThickness / 2;
    double offsetX = 0, offsetY = 0;
    if (middleAngle > 0 && middleAngle <= 90)
    {
        double sinA = Math.Sin(Math.PI * (90 - middleAngle) / 180);
        double a = r * sinA;
        double c = r;
        double b = Math.Sqrt(c * c - a * a);
        offsetX = _chartSize / 2 + b;
        offsetY = -(_chartSize / 2 + _popupHeight + a);
    }
    if (middleAngle > 90 && middleAngle <= 180)
    {
        double sinA = Math.Sin(Math.PI * (180 - middleAngle) / 180);
        double a = r * sinA;
        double c = r;
        double b = Math.Sqrt(c * c - a * a);
        offsetX = _chartSize / 2 + a;
        offsetY = -(_arcThickness / 2 + (r - b));
    }
    if (middleAngle > 180 && middleAngle <= 270)
    {
        double sinA = Math.Sin(Math.PI * (270 - middleAngle) / 180);
        double a = r * sinA;
        double c = r;
        double b = Math.Sqrt(c * c - a * a);
        offsetX = -_popupWidth + (r - b) + _arcThickness / 2;
        offsetY = -(_arcThickness / 2 + (r - a));
    }
    if (middleAngle > 270 && middleAngle <= 360)
    {
        double sinA = Math.Sin(Math.PI * (360 - middleAngle) / 180);
        double a = r * sinA;
        double c = r;
        double b = Math.Sqrt(c * c - a * a);
        offsetX = -_popupWidth + (r - a) + _arcThickness / 2;
        offsetY = -(_chartSize / 2 + _popupHeight + b);
    }
    popup.HorizontalOffset = offsetX;
    popup.VerticalOffset = offsetY;

    return popup;
}

差不多主要的就是這些了.到這.畫圖有點累.

源碼下載:ArcChart.zip

到此這篇關(guān)于基于WPF實現(xiàn)帶明細(xì)的環(huán)形圖表 的文章就介紹到這了,更多相關(guān)WPF環(huán)形圖表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解c# 中的DateTime

    詳解c# 中的DateTime

    這篇文章主要介紹了c# 中的DateTime的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • .NET?Core使用C#掃描并讀取圖片中的文字

    .NET?Core使用C#掃描并讀取圖片中的文字

    本文詳細(xì)講解了.NET?Core使用C#掃描并讀取圖片中的文字,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • Unity實現(xiàn)移動端手勢解鎖功能

    Unity實現(xiàn)移動端手勢解鎖功能

    這篇文章主要為大家詳細(xì)介紹了Unity實現(xiàn)移動端手勢解鎖功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • c#添加圖片、文本水印到PDF文件

    c#添加圖片、文本水印到PDF文件

    這篇文章主要介紹了如何用c#給PDF文件添加文本、圖片水印,文中代碼非常詳細(xì)供大家學(xué)習(xí)參考,感興趣的朋友可以了解下
    2020-06-06
  • Unity實現(xiàn)虛擬搖桿

    Unity實現(xiàn)虛擬搖桿

    這篇文章主要為大家詳細(xì)介紹了Unity實現(xiàn)虛擬搖桿,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C# 擴展方法的使用

    C# 擴展方法的使用

    這篇文章主要介紹了C# 擴展方法的使用,幫助大家更好的理解和學(xué)習(xí)c#編程語言,感興趣的朋友可以了解下
    2020-12-12
  • c#使用netmail方式發(fā)送郵件示例

    c#使用netmail方式發(fā)送郵件示例

    這篇文章主要介紹了c#使用netmail方式發(fā)送郵件的示例,大家參考使用吧
    2014-01-01
  • C#實現(xiàn)簡單的計算器功能完整實例

    C#實現(xiàn)簡單的計算器功能完整實例

    這篇文章主要介紹了C#實現(xiàn)簡單的計算器功能,結(jié)合完整實例形式分析了C#實現(xiàn)常見的數(shù)學(xué)運算、進制轉(zhuǎn)換等相關(guān)操作技巧與界面布局方法,需要的朋友可以參考下
    2017-08-08
  • c#字符串使用正則表達式示例

    c#字符串使用正則表達式示例

    這篇文章主要介紹了c#字符串使用正則表達式示例,需要的朋友可以參考下
    2014-02-02
  • C#結(jié)合SMTP實現(xiàn)郵件報警通知的實現(xiàn)示例

    C#結(jié)合SMTP實現(xiàn)郵件報警通知的實現(xiàn)示例

    這篇文章主要介紹了C#結(jié)合SMTP實現(xiàn)郵件報警通知的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評論

鲁山县| 德阳市| 丹巴县| 万荣县| 龙胜| 南宫市| 富宁县| 潍坊市| 西宁市| 昂仁县| 土默特右旗| 陆良县| 木兰县| 宁化县| 衡东县| 揭东县| 黑水县| 伊金霍洛旗| 甘孜县| 合江县| 桃源县| 万宁市| 梁山县| 六枝特区| 曲松县| 法库县| 镇康县| 哈密市| 阿鲁科尔沁旗| 额敏县| 芮城县| 东明县| 神农架林区| 海口市| 霸州市| 安宁市| 邯郸县| 沙洋县| 峨眉山市| 孝昌县| 黄龙县|