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>

浙公网安备 33010602011771号