我正在尝试创建一个测量系统,可以使用LiveCharts测量Y轴上的值和X轴上的时间。
我使用不断变化作为创建图形的基础,但我希望我的 X 轴从 0 秒开始,而不是像示例中那样从当前时间开始。我已经尝试了如何使用 Livecharts 使 x 轴从 0 开始并具有 2 秒的步长,而不是盯着程序启动的一秒?但我无法让它与我的程序一起使用。我想做他们在上面链接的线程中所做的同样的事情,但无法让它工作。
我的输出/外观
代码隐藏:
public void init()
{
var mapper = Mappers.Xy<ValueRandomizerForTest>().X(model =>
model.DateTime.Ticks).Y(model => model.Valuefordate);
Charting.For<ValueRandomizerForTest>(mapper);
ChartValues = new ChartValues<ValueRandomizerForTest>();
DateTimeFormatter = value => new
DateTime((long)value).ToString("ss");
AxisStep = TimeSpan.FromSeconds(1).Ticks;
AxisUnit = TimeSpan.TicksPerSecond;
SetAxisLimits(DateTime.Now);
}
public void read()
{
var r = new Random();
while (isreading)
{
Thread.Sleep(550);
var now = DateTime.Now;
var test = now.Second;
_trend = r.Next(1, 100);
if(ChartValues.Count == 0)
{
}
ChartValues.Add(new ValueRandomizerForTest
{
DateTime = now,
Valuefordate = _trend
});
SetAxisLimits(now);
//lets only use the last 150 values
if (ChartValues.Count > 150)
{
ChartValues.RemoveAt(0);
}
}
}
public void SetAxisLimits(DateTime now)
{
AxisMax = now.Ticks + TimeSpan.FromSeconds(1).Ticks; //Axis is moving 1 second ahead
AxisMin = now.Ticks - TimeSpan.FromSeconds(5).Ticks;
}
ValuerandomizerFortest Class:
public DateTime DateTime { get; set; }
public TimeSpan Time { get; set; }
public double Valuefordate { get; set; }
public double AxisStep { get; set; }
public double AxisUnit { get; set; }
private double _axisMax;
private double _axisMin;
public double AxisMax
{
get
{
return _axisMax
}
set
{
_axisMax = value;
NotifyPropertyChanged("AxisMax");
}
}
public double AxisMin
{
get { return _axisMin; }
set
{
_axisMin = value;
NotifyPropertyChanged("AxisMin");
}
}
XAML:
<Window x:Class="WPFDemo.Views.GraphViewer"
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFDemo.Views"
mc:Ignorable="d"
Title="GraphViewer" Height="700" Width="950">
<Grid >
<Grid Margin="759,10,10,588.4" RenderTransformOrigin="0.51,0.526">
<Button Content="Random"
Margin="6"
Padding="6"
Command="{Binding randomer}">
</Button>
</Grid>
<!--<Grid Height="80" Width="200" Margin="50, -20,600,500">
-->
<!--<ComboBox ItemsSource="{Binding list}" Margin="-32,-10,32,20">
-->
<!--<ComboBox.ItemTemplate>
-->
<!--<DataTemplate>
<TextBlock Text="{Binding Name}">
</TextBlock>
</DataTemplate>-->
<!--
</ComboBox.ItemTemplate>-->
<!--
</ComboBox>-->
<!--<Button Content="Updater"
Command="{Binding ClickCommand}">
</Button>-->
<!--
</Grid>-->
<Grid Height="500" Width="940" Margin="4,100,0,28.4">
<lvc:CartesianChart Grid.Row="1" AnimationsSpeed="0:0:0.3" Hoverable="False" DataTooltip="{x:Null}">
<lvc:CartesianChart.Series>
<lvc:LineSeries Values="{Binding ChartValues}"
PointGeometry="{x:Null}"
LineSmoothness="1"
StrokeThickness="6"
Stroke="#F34336"
Fill="Transparent"/>
</lvc:CartesianChart.Series>
<lvc:CartesianChart.AxisX>
<lvc:Axis x:Name="XAxis" LabelFormatter="{Binding DateTimeFormatter}"
MaxValue="{Binding AxisMax}"
MinValue="{Binding AxisMin}"
Unit="{Binding AxisUnit}">
<lvc:Axis.Separator>
<lvc:Separator Step="{Binding AxisStep}" />
</lvc:Axis.Separator>
</lvc:Axis>
</lvc:CartesianChart.AxisX>
</lvc:CartesianChart>
</Grid>
</Grid>
</Window>
查看内联注释:
private long startTimeTicks;
public void init()
{
var mapper = Mappers.Xy<ValueRandomizerForTest>().X(model =>
model.DateTime.Ticks).Y(model => model.Valuefordate);
Charting.For<ValueRandomizerForTest>(mapper);
ChartValues = new ChartValues<ValueRandomizerForTest>();
DateTimeFormatter = value => new
DateTime((long)value).ToString("ss");
AxisStep = TimeSpan.FromSeconds(1).Ticks;
AxisUnit = TimeSpan.TicksPerSecond;
var currentTime = DateTime.Now;
startTimeTicks = currentTime.Ticks; // store start time
SetAxisLimits(currentTime);
}
public void read()
{
var r = new Random();
while (isreading)
{
Thread.Sleep(550);
var now = DateTime.Now;
var test = now.Second;
_trend = r.Next(1, 100);
if(ChartValues.Count == 0)
{
}
ChartValues.Add(new ValueRandomizerForTest
{
DateTime = now - new TimeSpan(startTimeTicks),
Valuefordate = _trend
});
SetAxisLimits(now);
//lets only use the last 150 values
if (ChartValues.Count > 150)
{
ChartValues.RemoveAt(0);
}
}
}
public void SetAxisLimits(DateTime now)
{
long offsetTicks = now.Ticks - startTimeTicks; // compute offset ticks from program start (at call from init() this calculation will be equal to 0)
AxisMin = Math.Max(offsetTicks - TimeSpan.FromSeconds(5).Ticks, 0);
AxisMax = AxisMin + TimeSpan.FromSeconds(6).Ticks; // Set max according to min
}