I have a WPF chart that I update every 200 ms. It is updated with new data, but the halo effect. Therefore, when the bar changes from 1 to 0.5, a fading strip appears in which the original panel is located. I'm not sure why this is happening, but I have to remove it so that the bars move cleanly.
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]));
}
Can anyone help me with this?
thanks
EDIT
I slowed down the timer so that it ticks once per second and tried to enter dummy data from the update status function, and I still see the same behavior. It looks worse at 10 Hz because the bars do not have time to disappear before the next one appears on top.
Here is my new update status feature
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";
}