WPF 云图

    /// <summary>
    /// 颜色温度对应表
    /// </summary>
    public class ColorTable
    {
        public int Value { get; set; }
        public int R { get; set; }
        public int G { get; set; }
        public int B { get; set; }
        public double Alpha { get; set; }

        public ColorTable()
        {
            Value = R = G = B = 0;
            Alpha = 255;
        }

        public ColorTable(int value, int r, int g, int b, double alpha = 255)
        {
            Value = value;
            R = r;
            G = g;
            B = b;
            Alpha = alpha;
        }
    }

  

    /// <summary>
    /// 温湿度结构
    /// </summary>
    public class HumiTemp
    {
        public HumiTemp()
        {
            X = 0;
            Y = 0;
            MgrObjId = "";
            Id = "";
            Value = 0;
        }
        public HumiTemp(double x, double y, string mgrobjid, string id, double value = 0)
        {
            X = x;
            Y = y;
            MgrObjId = mgrobjid;
            Id = id;
            Value = value;
        }
        public double X { get; set; }
        public double Y { get; set; }
        /// <summary>
        /// 管理对象ID
        /// </summary>
        public string MgrObjId { get; set; }
        /// <summary>
        /// 属性ID
        /// </summary>
        public string Id { get; set; }
        /// <summary>
        /// 外部传入值
        /// </summary>
        public double Value { get; set; }
    }

  

    /// <summary>
    /// CloudChart.xaml 的交互逻辑
    /// </summary>
    public partial class CloudChart : UserControl
    {
        private static readonly DependencyProperty ColorListProperty = DependencyProperty.Register("ColorList", typeof(List<ColorTable>), typeof(CloudChart), new PropertyMetadata(new List<ColorTable>()));
        private static readonly DependencyProperty HTListProperty = DependencyProperty.Register("HTList", typeof(List<HumiTemp>), typeof(CloudChart), new PropertyMetadata(new List<HumiTemp>()));
        private static readonly DependencyProperty CabWidthProperty = DependencyProperty.Register("CabWidth", typeof(double), typeof(CloudChart), new PropertyMetadata(double.NaN));
        private static readonly DependencyProperty CabHeightProperty = DependencyProperty.Register("CabHeight", typeof(double), typeof(CloudChart), new PropertyMetadata(double.NaN));

        public CloudChart()
        {
            InitializeComponent();
            //SetValue(HTListProperty, new List<HumiTemp>());
            //SetValue(ColorListProperty, new List<ColorTable>());
            HTList = new List<HumiTemp>();
            ColorList = new List<ColorTable>();
        }

        private bool isRealTimeValue;

        /// <summary>
        /// 是否是实时值
        /// </summary>
        public bool IsRealTimeValue
        {
            get { return isRealTimeValue; }
            set { isRealTimeValue = value; }
        }

        /// <summary>
        /// 配置信息
        /// </summary>
        public List<HumiTemp> HTList
        {
           set { SetValue(HTListProperty, value); }
            get { return (List<HumiTemp>)GetValue(HTListProperty); }
        }

        /// <summary>
        /// 颜色表
        /// </summary>
        public List<ColorTable> ColorList
        {
           set { SetValue(ColorListProperty, value); }
            get { return (List<ColorTable>)GetValue(ColorListProperty); }
        }

        /// <summary>
        /// 机柜宽度
        /// </summary>
        public double CabWidth
        {
            set { SetValue(CabWidthProperty, value); }
            get { return (double)GetValue(CabWidthProperty); }
        }

        /// <summary>
        /// 机柜高度
        /// </summary>
        public double CabHeight
        {
            set { SetValue(CabHeightProperty, value); }
            get { return (double)GetValue(CabHeightProperty); }
        }

        /// <summary>
        /// 计算每个点的实时值
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="list"></param>
        /// <returns></returns>
        private double GetPointRealTimeValue(double x, double y, List<HumiTemp> list)
        {
            double R = 0, S = 0;
            foreach (var ht in list)
            {
                double temp = GetRealTimeValue(ht);
                if (x == ht.X && y == ht.Y)
                    return temp;
                //计算系数
                double ratio = 1 / ((x - ht.X) * (x - ht.X) + (y - ht.Y) * (y - ht.Y));
                S += ratio * temp;
                R += ratio;
            }
            return S / R;
        }

        /// <summary>
        /// 读取实时值
        /// </summary>
        /// <param name="ht"></param>
        /// <returns></returns>
        private double GetRealTimeValue(HumiTemp ht)
        {
            double value;
            if (double.TryParse(WcfClient.Instance.GetData(ht.MgrObjId, ht.Id), out value))
                return value;
            return double.NaN;
        }

        /// <summary>
        /// 根据外部传入值计算每个点的值
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="list"></param>
        /// <returns></returns>
        private double GetPointOutsideValue(double x, double y, List<HumiTemp> list)
        {
            double R = 0, S = 0;
            foreach (var ht in list)
            {
                double temp = GetOutsideValue(ht);
                if (x == ht.X && y == ht.Y)
                    return temp;
                //计算系数
                double ratio = 1 / ((x - ht.X) * (x - ht.X) + (y - ht.Y) * (y - ht.Y));
                S += ratio * temp;
                R += ratio;
            }
            return S / R;
        }

        /// <summary>
        /// 读取外部传入值
        /// </summary>
        /// <param name="ht"></param>
        /// <returns></returns>
        private double GetOutsideValue(HumiTemp ht)
        {
            return ht.Value;
        }

        /// <summary>
        /// 温度(值)转换成颜色值
        /// </summary>
        /// <param name="temperature"></param>
        /// <returns></returns>
        private Color ValueToColor(double temperature, List<ColorTable> colorList)
        {
            int Tlength = colorList.Count;
            if (Tlength == 0)
                return Colors.Red;
            int i;
            for (i = 0; i < Tlength; i++)
            {
                if (colorList[i].Value > temperature)
                    break;
            }
            if (i == 0)
                return Color.FromRgb((byte)(colorList[0].R), (byte)(colorList[0].G), (byte)(colorList[0].B));
            else if (i == Tlength)
                return Color.FromRgb((byte)(colorList[i - 1].R), (byte)(colorList[i - 1].G), (byte)(colorList[i - 1].B));

            double ratio = (temperature - colorList[i - 1].Value) / (colorList[i].Value - colorList[i - 1].Value);
            int rSpan = colorList[i].R - colorList[i - 1].R;
            int gSpan = colorList[i].G - colorList[i - 1].G;
            int bSpan = colorList[i].B - colorList[i - 1].B;
            double r = (colorList[i - 1].R + rSpan * ratio);
            double g = (colorList[i - 1].G + gSpan * ratio);
            double b = (colorList[i - 1].B + bSpan * ratio);
            return Color.FromRgb((byte)r, (byte)g, (byte)b);
        }


        /// <summary>
        /// 更新界面
        /// </summary>
        public void Update()
        {
            Show();
        }

        /// <summary>
        /// 获取坐标点的值
        /// </summary>
        private double GetData(double x, double y, List<HumiTemp> list)
        {
            double ret = 0;
            if (IsRealTimeValue == true)
            {
                ret = GetPointRealTimeValue(x, y, list);
            }
            else
            {
                ret = GetPointOutsideValue(x, y, list);
            }
            return ret;
        }

        /// <summary>
        /// 控件初始化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            if (CabHeight > 0 && CabWidth > 0)
            {
                double d1 = Height / CabHeight;
                double d2 = Width / CabWidth;
                //取得控件和真实机柜的比例尺 
                double scale = d1 > d2 ? d2 : d1;
                img.Height = scale * CabHeight;
                img.Width = scale * CabWidth;
            }
            InitColorTable();
        }

        /// <summary>
        /// 初始化颜色表
        /// </summary>
        public void InitColorTable()
        {
            colorStack.Children.Clear();
            ValueStack.Children.Clear();
            foreach (ColorTable item in ColorList)
            {
                Rectangle rect = new Rectangle();
                rect.Width = 25;
                rect.Height = 25;
                rect.Fill = new SolidColorBrush(Color.FromRgb((byte)item.R, (byte)item.G, (byte)item.B));
                colorStack.Children.Add(rect);
                Label lb = new Label();
                lb.Width = 25;
                lb.Height = 25;
                lb.Content = item.Value;
                ValueStack.Children.Add(lb);
            }
        }

        /// <summary>
        /// 显示云图
        /// </summary>
        private void Show()
        {
            if (double.IsNaN(img.Width) || img.Width == 0 || double.IsNaN(img.Height) || img.Height == 0)
            {
                UserControl_Loaded(this, new RoutedEventArgs());
            }
            //防止用户并未初始化
            if (!double.IsNaN(img.Width) && !double.IsNaN(img.Height))
            {
                // Create the bitmap, with the dimensions of the image placeholder.
                WriteableBitmap wb = new WriteableBitmap((int)img.Width, (int)img.Height, 96, 96, PixelFormats.Bgra32, null);
                // Define the update square (which is as big as the entire image).
                Int32Rect rect = new Int32Rect(0, 0, (int)img.Width, (int)img.Height);
                byte[] pixels = new byte[(int)img.Width * (int)img.Height * wb.Format.BitsPerPixel / 8];
                for (int y = 0; y < wb.PixelHeight; y++)
                {
                    for (int x = 0; x < wb.PixelWidth; x++)
                    {
                        int alpha = 255;
                        int red = 0;
                        int green = 0;
                        int blue = 0;

                        double value = GetData(x, y, HTList);
                        Color c = ValueToColor(value,ColorList);
                        red = c.R;
                        green = c.G;
                        blue = c.B;

                        int pixelOffset = (x + (wb.PixelHeight - y - 1) * wb.PixelWidth) * wb.Format.BitsPerPixel / 8;
                        pixels[pixelOffset] = (byte)blue;
                        pixels[pixelOffset + 1] = (byte)green;
                        pixels[pixelOffset + 2] = (byte)red;
                        pixels[pixelOffset + 3] = (byte)alpha;
                    }

                    int stride = (wb.PixelWidth * wb.Format.BitsPerPixel) / 8;
                    wb.WritePixels(rect, pixels, stride, 0);
                }
                // Show the bitmap in an Image element.
                img.Source = wb;
            }
        }
    }

 

<UserControl x:Class="MobileHT.CloudChart"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d"  Loaded="UserControl_Loaded"  d:DesignHeight="600" d:DesignWidth="400" Width="400" Height="600">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="26"></RowDefinition>
            <RowDefinition Height="26"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Image Grid.Row="3" Name="img" IsHitTestVisible="False" Margin="2" ></Image>
        <StackPanel  Name="colorStack" Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="0" Margin="2">
        </StackPanel>
        <StackPanel Name="ValueStack"  Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="1" Margin="2">
        </StackPanel>
    </Grid>
</UserControl>

  

  

 

获取数据有使用外部DLL,可参考以上代码,做任何值的云图。(上述为温度云图或者湿度云图)

 

效果图:

效果图配置代码:

        <my:CloudChart x:Name="cloud2" Height="300" Width="200"  CabHeight="300" CabWidth="200" IsRealTimeValue="False" Margin="365,85,53,294">
            <my:CloudChart.HTList>
                <my:HumiTemp Id="0" MgrObjId="0" />
                <my:HumiTemp Id="1" MgrObjId="1" X="20" Y="30"  Value="19"/>
                <my:HumiTemp Id="2" MgrObjId="2"  X="30" Y="60" Value="20"/>
                <my:HumiTemp Id="3" MgrObjId="3" X="40" Y="90" Value="21"/>
                <my:HumiTemp Id="4" MgrObjId="4"  X="50" Y="100" Value="22"/>
                <my:HumiTemp Id="5" MgrObjId="5"  X="60" Y="110" Value="27"/>
                <my:HumiTemp Id="6" MgrObjId="6"  X="80" Y="120" Value="24"/>
                <my:HumiTemp Id="7" MgrObjId="7"  X="100" Y="130" Value="25"/>
                <my:HumiTemp Id="8" MgrObjId="8" X="120" Y="150" Value="26"/>
                <my:HumiTemp Id="9" MgrObjId="9"  X="140" Y="160" Value="28"/>
                <my:HumiTemp Id="9" MgrObjId="9"  X="160" Y="200" Value="30"/>
                <my:HumiTemp Id="9" MgrObjId="9"  X="180" Y="230" Value="33"/>
                <my:HumiTemp Id="9" MgrObjId="9"  X="270" Y="200" Value="35"/>
            </my:CloudChart.HTList>
            <my:CloudChart.ColorList>
                <my:ColorTable Value="19" R="0" G="0" B="255" Alpha="255"></my:ColorTable>
                <my:ColorTable Value="22" R="100" G="149" B="237" Alpha="255"></my:ColorTable>
                <my:ColorTable Value="25" R="100" G="100" B="220" Alpha="255"></my:ColorTable>
                <my:ColorTable Value="28" R="127" G="0" B="212" Alpha="255"></my:ColorTable>
                <my:ColorTable Value="30" R="173" G="255" B="47" Alpha="255"></my:ColorTable>
                <my:ColorTable Value="32" R="255" G="165" B="0" Alpha="255"></my:ColorTable>
                <my:ColorTable Value="35" R="255" G="69" B="0" Alpha="255"></my:ColorTable>
            </my:CloudChart.ColorList>
        </my:CloudChart>

  

posted @ 2013-08-30 15:51  三叶草╮  阅读(757)  评论(0编辑  收藏  举报