我有一个WPF条形图,我每200ms更新一次。它更新了新数据,但有重影效果。因此,当一个条形从1变为0.5时,原始条形区域会出现一个褪色的条形。我不知道为什么会发生这种情况,但我会将其删除,以便条形图移动干净。
MainWindow.xml
<charting:Chart Grid.Column="0" HorizontalAlignment="Stretch" Margin="6,6,6,6" Name="motorPowerChart" VerticalAlignment="Stretch" Title="Motor Power">
<charting:ColumnSeries IndependentValueBinding="{Binding Key}"
DependentValueBinding="{Binding Value}"
ItemsSource="{Binding}">
</charting:ColumnSeries>
<charting:Chart.Axes>
<charting:LinearAxis Orientation="Y" Minimum="0" Maximum="1" Title="PWM Frequency"/>
</charting:Chart.Axes>
<charting:Chart.LegendStyle>
<Style TargetType="Control">
<Setter Property="Width" Value="0"/>
<Setter Property="Height" Value="0"/>
</Style>
</charting:Chart.LegendStyle>
</charting:Chart>
MainWindow.xml.cs
public partial class MainWindow : Window
{
DispatcherTimer _statusUpdateTimer;
public ObservableCollection<KeyValuePair<string, double>> MotorPowerGraphData = new ObservableCollection<KeyValuePair<string, double>>();
public ObservableCollection<KeyValuePair<string, double>> PIDGraphData = new ObservableCollection<KeyValuePair<string, double>>();
public MainWindow()
{
InitializeComponent();
_statusUpdateTimer = new DispatcherTimer();
_statusUpdateTimer.Interval = new TimeSpan(0, 0, 0, 0, 200);
_statusUpdateTimer.Tick += new EventHandler(updateStatus);
motorPowerChart.DataContext = MotorPowerGraphData;
pidChart.DataContext = PIDGraphData;
}
private void updateStatus(Object myObject, EventArgs myEventArgs)
{
double[] status = SerialCommunications.GetStatus();
MotorPowerGraphData.Clear();
MotorPowerGraphData.Add(new KeyValuePair<String, double>("Motor1", status[0]));
MotorPowerGraphData.Add(new KeyValuePair<String, double>("Motor2", status[1]));
MotorPowerGraphData.Add(new KeyValuePair<String, double>("Motor3", status[2]));
MotorPowerGraphData.Add(new KeyValuePair<String, double>("Motor4", status[3]));
PIDGraphData.Clear();
PIDGraphData.Add(new KeyValuePair<String, double>("Yaw", status[8]));
PIDGraphData.Add(new KeyValuePair<String, double>("Pitch", status[9]));
PIDGraphData.Add(new KeyValuePair<String, double>("Roll", status[10]));
}
任何人都可以帮我吗?
由于
修改
我已经减慢了定时器的速度,所以它每秒滴答一次,并尝试从更新状态函数中输入虚拟数据,我仍然看到相同的行为。它在10Hz看起来更糟糕,因为在下一个渲染到顶部之前,条形没有时间褪色。
这是我的新更新状态功能
int i = 0;
private void updateStatus(Object myObject, EventArgs myEventArgs)
{
/*double[] status = SerialCommunications.GetStatus();
MotorPowerGraphData.Clear();
MotorPowerGraphData.Add(new KeyValuePair<String, double>("M1 " + Math.Round(status[0], 3), status[0]));
MotorPowerGraphData.Add(new KeyValuePair<String, double>("M2 " + Math.Round(status[1], 3), status[1]));
MotorPowerGraphData.Add(new KeyValuePair<String, double>("M3 " + Math.Round(status[2], 3), status[2]));
MotorPowerGraphData.Add(new KeyValuePair<String, double>("M4 " + Math.Round(status[3], 3), status[3]));
PIDGraphData.Clear();
PIDGraphData.Add(new KeyValuePair<String, double>("Yaw " + Math.Round(status[8], 0), status[8]));
PIDGraphData.Add(new KeyValuePair<String, double>("Pitch " + Math.Round(status[9], 0), status[9]));
PIDGraphData.Add(new KeyValuePair<String, double>("Roll " + Math.Round(status[10], 0), status[10]));
IMUGraphData.Clear();
IMUGraphData.Add(new KeyValuePair<String, double>("Yaw " + Math.Round(status[4],0), status[4]));
IMUGraphData.Add(new KeyValuePair<String, double>("Pitch " + Math.Round(status[5], 0), status[5]));
IMUGraphData.Add(new KeyValuePair<String, double>("Roll " + Math.Round(status[6], 0), status[6]));
if (status[7] == 1) batteryStatusLabel.Content = "Battery Level: Charged";
else batteryStatusLabel.Content = "Battery Level: Empty";*/
if (i == 5) i = 0;
else
{
IMUGraphData.Clear();
IMUGraphData.Add(new KeyValuePair<String, double>("Yaw " + i*30, i*30));
IMUGraphData.Add(new KeyValuePair<String, double>("Pitch " + i*-30, i*-30));
IMUGraphData.Add(new KeyValuePair<String, double>("Roll " + i * 15, i * 15));
i++;
}
}
我已将视频上传到youtube,因此您可以在更新时看到图表的样子
修改
我在使用图表控件的Win窗体中尝试了这个并且它工作得很好但是我想使用WPF,因为我想渲染一个根据偏航,俯仰和滚动以及从我读过的内容在空间中旋转的立方体这在WPF中很容易做到
修改
如果没有人知道为什么这不起作用,有人可以推荐一些其他方式来显示我的数据吗?
解
我编辑了这些值而不是删除它们并将它们添加到可观察集合中。
public partial class MainWindow : Window
{
DispatcherTimer _statusUpdateTimer;
public ObservableCollection<KeyValuePair<string, double>> _motorPowerGraphData = new ObservableCollection<KeyValuePair<string, double>>();
public ObservableCollection<KeyValuePair<string, double>> _ratePIDGraphData = new ObservableCollection<KeyValuePair<string, double>>();
public ObservableCollection<KeyValuePair<string, double>> _stabPIDGraphData = new ObservableCollection<KeyValuePair<string, double>>();
public ObservableCollection<KeyValuePair<string, double>> _imuGraphData = new ObservableCollection<KeyValuePair<string, double>>();
public MainWindow()
{
InitializeComponent();
_motorPowerGraphData.Clear();
_motorPowerGraphData.Add(new KeyValuePair<string, double>("M1 0", 0));
_motorPowerGraphData.Add(new KeyValuePair<string, double>("M2 0", 0));
_motorPowerGraphData.Add(new KeyValuePair<string, double>("M3 0", 0));
_motorPowerGraphData.Add(new KeyValuePair<string, double>("M4 0", 0));
_ratePIDGraphData.Clear();
_ratePIDGraphData.Add(new KeyValuePair<String, double>("Yaw 0", 0));
_ratePIDGraphData.Add(new KeyValuePair<String, double>("Pitch 0", 0));
_ratePIDGraphData.Add(new KeyValuePair<String, double>("Roll 0", 0));
_stabPIDGraphData.Clear();
_stabPIDGraphData.Add(new KeyValuePair<String, double>("Yaw 0", 0));
_stabPIDGraphData.Add(new KeyValuePair<String, double>("Pitch 0", 0));
_stabPIDGraphData.Add(new KeyValuePair<String, double>("Roll 0", 0));
_imuGraphData.Clear();
_imuGraphData.Add(new KeyValuePair<String, double>("Yaw 0", 0));
_imuGraphData.Add(new KeyValuePair<String, double>("Pitch 0", 0));
_imuGraphData.Add(new KeyValuePair<String, double>("Roll 0", 0));
_statusUpdateTimer = new DispatcherTimer();
_statusUpdateTimer.Interval = new TimeSpan(0, 0, 0, 0, 200);
_statusUpdateTimer.Tick += new EventHandler(updateStatus);
motorPowerChart.DataContext = _motorPowerGraphData;
ratePIDChart.DataContext = _ratePIDGraphData;
stabPIDChart.DataContext = _stabPIDGraphData;
imuChart.DataContext = _imuGraphData;
}
private void updateStatus(Object myObject, EventArgs myEventArgs)
{
double[] status = SerialCommunications.GetStatus();
_motorPowerGraphData[0] = new KeyValuePair<String, double>("M1 " + Math.Round(status[0], 3), status[0]);
_motorPowerGraphData[1] = new KeyValuePair<String, double>("M2 " + Math.Round(status[1], 3), status[1]);
_motorPowerGraphData[2] = new KeyValuePair<String, double>("M3 " + Math.Round(status[2], 3), status[2]);
_motorPowerGraphData[3] = new KeyValuePair<String, double>("M4 " + Math.Round(status[3], 3), status[3]);
_ratePIDGraphData[0] = new KeyValuePair<String, double>("Yaw " + Math.Round(status[8], 0), status[8]);
_ratePIDGraphData[1] = new KeyValuePair<String, double>("Pitch " + Math.Round(status[9], 0), status[9]);
_ratePIDGraphData[2] = new KeyValuePair<String, double>("Roll " + Math.Round(status[10], 0), status[10]);
_stabPIDGraphData[0] = new KeyValuePair<String, double>("Yaw " + Math.Round(status[8], 0), status[11]);
_stabPIDGraphData[1] = new KeyValuePair<String, double>("Pitch " + Math.Round(status[9], 0), status[12]);
_stabPIDGraphData[2] = new KeyValuePair<String, double>("Roll " + Math.Round(status[10], 0), status[13]);
_imuGraphData[0] = new KeyValuePair<String, double>("Yaw " + Math.Round(status[4],0), status[4]);
_imuGraphData[1] = new KeyValuePair<String, double>("Pitch " + Math.Round(status[5], 0), status[5]);
_imuGraphData[2] = new KeyValuePair<String, double>("Roll " + Math.Round(status[6], 0), status[6]);
if (status[7] == 1) batteryStatusLabel.Content = "Battery Level: Charged";
else batteryStatusLabel.Content = "Battery Level: Empty";
double armed = status[14];
if (armed == 1)
{
armButton.Content = "Disarm";
armedLabel.Content = "Armed: True";
}
else
{
armButton.Content = "Arm";
armedLabel.Content = "Armed: False";
}
double rateMode = status[16];
double stabMode = status[17];
if (rateMode == 1 && stabMode == 0)
{
modeLabel.Content = "Mode: Rate";
modeButton.Content = "Set Mode To Stability";
}
else
{
modeLabel.Content = "Mode: Stability";
modeButton.Content = "Set Mode To Rate";
}
double initialised = status[15];
if (initialised == 1) initialisedLabel.Content = "Initialised: True";
else initialisedLabel.Content = "Initialised: False";
}
答案 0 :(得分:3)
查看WPFToolkit中的源代码,看起来BarDataPoint有一个“Reveal”VisualState,可以从0开始显示不透明度 - >超过0.5秒。我的猜测是,因为你正在为条形图添加和删除KeyValuePairs,工具包正在“揭示”新的BarDataPoints,就像它们是新数据一样。
<VisualStateGroup x:Name="RevealStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.5" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Shown">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="1" Duration="0" />
</Storyboard>
</VisualState>
<VisualState x:Name="Hidden">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="0" Duration="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
我可以想象两种可能的解决方案: