<
telerik:RadTabItem
Name
=
"StatusTab"
Header
=
"Status Summary"
IsSelected
=
"True"
MouseUp
=
"StatusTab_MouseUp"
>
<
Grid
>
<
telerik:RadGridView
Margin
=
"47.773,61.105,0,0"
Name
=
"gridStatus"
AutoGenerateColumns
=
"False"
ColumnWidth
=
"Auto"
telerik:StyleManager.Theme
=
"Vista"
CanUserDeleteRows
=
"False"
CanUserInsertRows
=
"False"
ActionOnLostFocus
=
"None"
Height
=
"Auto"
VerticalAlignment
=
"Top"
Width
=
"Auto"
HorizontalAlignment
=
"Left"
>
<
telerik:RadGridView.Columns
>
<
telerik:GridViewDataColumn
Header
=
"Name"
DataMemberBinding
=
"{Binding Key}"
Width
=
"auto"
/>
<
telerik:GridViewDataColumn
Header
=
"Description"
DataMemberBinding
=
"{Binding Value.Description}"
Width
=
"auto"
/>
<
telerik:GridViewDataColumn
Header
=
"State"
DataMemberBinding
=
"{Binding Value.State}"
Width
=
"auto"
/>
</
telerik:RadGridView.Columns
>
</
telerik:RadGridView
>
</
Grid
>
</
telerik:RadTabItem
>
private
void
OnTimerTick(
object
sender, EventArgs e)
{
this
.nowTime =
this
.nowTime.AddMilliseconds(500);
this
.UpdateData(
this
.nowTime);
this
.SetUpAxisXRange(
this
.nowTime);
this
.Data =
null
;
this
.Data =
this
.cpuData;
}
if
(e.Element == ExportElement.Cell)
{
if (e.Value is SurveyDetail)
{
SurveyDetail surveyDetail = (SurveyDetail)e.Value;
if (e.Context is Telerik.Windows.Controls.GridViewDataColumn)
{
Telerik.Windows.Controls.
GridViewDataColumn dc = (Telerik.Windows.Controls.GridViewDataColumn)e.Context;
if (dc.Name == "dcCPUJobCode")
{
StringBuilder sb = new StringBuilder();
foreach (CPUJobCode cpuJobCode in surveyDetail.SurveyJobCode.CPUJobCodes)
{
sb.Append(
string.Format("{0} {1} \n", cpuJobCode.JobCode, cpuJobCode.JobTitle));
}
e.Value = sb.ToString();
}
}
}
}
Hi, I am currently working over the chart control which should fulfill the following requirements:
I checked if your RadChartView control was able to deal with this task and fell in trouble with several issues. I hope that reasons for such a behavior come from my lack of understanding how charting should be implemented, so we will be able to rely on your control if only we would have those issues fixed. Instead of attaching the whole project, I will try to provide enough information for you in the code snippets.
I need to show from 1 to 10 parameters of different types.
When each parameter is updated i add new value in the corresponding array this way:
ParameterInfo._log.Add(val, DateTime.Now);
public
class
ParameterRecord
{
private
object
_value;
private
DateTime _date;
}
public
class
ParameterInfo : ViewModelBase
{
private
ObservableCollection<ParameterRecord> _log;
private
string
_type;
}
The first problem is
'How can I provide simple x-axis panning capabilities for the live chart?'
I have a timer which updates the chart each 500 milliseconds. It basically fixes the Maximum and Minimum properties of the x-axis:
chart.HorizontalAxis.Minimum = now.Subtract(_horizontalScaleLength);
chart.HorizontalAxis.Maximum = now;
In this way the auto-pan to the last moment works alright but there's no possibility to pan the chart.
It's obvious that if I want to provide the panning to the very initial moment when the chart was shown, I shall leave
chart.HorizontalAxis.Minimum == initialDateTime;
I see two possibilities to fix this issue:
The second problem is
'How much points should i add to the data source? How much points is it able to carry?'
At first I tried to add the values every time the timer event is figured (i.e. each 500 milliseconds) However it turned out to be a bad idea. The chart started to go slower and almost stopped with the time. It had about 5000 data points just for 1 minute. I suppose that either there shouldn't be very much points in the data source or I should dynamically filter only the visible segment of a big array. Do you see the latter way convenient enough?
So I turned to the other option, I added new data points to the appropriate series only when their values change. Unsurprisingly, the result looked like a saw (attached file telerik letter - zig-zag trackball.gif)
So I had to add two values when the new value arrives and move the second one further to prolongate the horizontal segment until the next change:
if
(oldValue != newValue)
{
lg.Add(
new
ParameterRecord(newValue, DateTime.Now));
// the point that will remain
lg.Add(
new
ParameterRecord(newValue, DateTime.Now));
// the point that will be prolongated
}
else
{
lg.RemoveAt(lg.Count - 1);
lg.Add(
new
ParameterRecord(oldValue, DateTime.Now));
// prolongate the horizontal line
}
I want you to know if this is a convenient way because it leads to the problem with the TrackBallInfo. Because there are no data points, in between the moments of the value change, the TrackBallInfo snaps to the closest data point instead of displaying the actual value under the mouse pointer. This is not desired (look at the attachment telerik letter - trackball glitch.gif)
I also have troubles with the dynamical setting of the bunch of y-axes in the code behind, but I didn't try enough by myself yet because it's crucial to know if Telerik's solution is able to deal with just the issues described here.
Thank you,
Andrey
<telerik:RadGridView x:Name="radGrid" Margin="5,5,5,5" ItemsSource="{Binding PersonViews}" RowIndicatorVisibility="Collapsed" AutoGenerateColumns="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" FontSize="14">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Name}" Header="Name" />
<telerik:GridViewDataColumn DataMemberBinding="{Binding Location}" Header="Location"/>
<telerik:GridViewComboBoxColumn ItemsSourceBinding="{Binding Occupation}"
UniqueName="Uniq"
SelectedValueMemberPath="ID"
DisplayMemberPath="Occupation" Header="Occupation"/>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.ComponentModel;
using
System.Collections.ObjectModel;
namespace
GridComboBindingTest
{
class GridViewModel : INotifyPropertyChanged
{
private ObservableCollection<PersonView> _personViews;
public GridViewModel()
{
PersonViews =
new ObservableCollection<PersonView>();
PersonView gridView = new PersonView();
gridView.Location =
"Chicago";
gridView.Name =
"Fred";
PersonOccupation tc = new PersonOccupation();
tc.ID = 1;
tc.Occupation =
"Programmer";
gridView.Occupation =
new ObservableCollection<PersonOccupation>();
gridView.Occupation.Add(tc);
tc =
new PersonOccupation();
tc.ID = 2;
tc.Occupation =
"Sales";
gridView.Occupation.Add(tc);
tc =
new PersonOccupation();
tc.ID = 3;
tc.Occupation =
"Tech";
gridView.Occupation.Add(tc);
PersonViews.Add(gridView);
gridView =
new PersonView();
gridView.Location =
"NY";
gridView.Name =
"Joe";
tc =
new PersonOccupation();
tc.ID = 1;
tc.Occupation =
"Cook";
gridView.Occupation =
new ObservableCollection<PersonOccupation>();
gridView.Occupation.Add(tc);
tc =
new PersonOccupation();
tc.ID = 2;
tc.Occupation =
"Chef";
gridView.Occupation.Add(tc);
tc =
new PersonOccupation();
tc.ID = 3;
tc.Occupation =
"Tech";
gridView.Occupation.Add(tc);
PersonViews.Add(gridView);
ć
ć
ć
gridView =
new PersonView();
gridView.Location =
"LA";
gridView.Name =
"Sam";
tc =
new PersonOccupation();
tc.ID = 1;
tc.Occupation =
"Tech";
gridView.Occupation =
new ObservableCollection<PersonOccupation>();
gridView.Occupation.Add(tc);
tc =
new PersonOccupation();
tc.ID = 2;
tc.Occupation =
"Student";
gridView.Occupation.Add(tc);
tc =
new PersonOccupation();
tc.ID = 3;
tc.Occupation =
"Writer";
gridView.Occupation.Add(tc);
PersonViews.Add(gridView);
}
ć
public ObservableCollection<PersonView> PersonViews
{
get { return _personViews; }
set
{
if (_personViews != value)
{
_personViews =
value;
RaisePropertyChanged(
"GridViews");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
// take a copy to prevent thread issues
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(
this, new PropertyChangedEventArgs(propertyName));
}
}
}
ć
public class PersonView : INotifyPropertyChanged
{
private ObservableCollection<PersonOccupation> _occupation;
public string Name
{
get;
set;
}
public string Location
{
get;
set;
}
ć
public ObservableCollection<PersonOccupation> Occupation
{
get { return _occupation; }
set
{
if (_occupation != value)
{
_occupation =
value;
RaisePropertyChanged(
"Person");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
// take a copy to prevent thread issues
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(
this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class PersonOccupation : INotifyPropertyChanged
{
private string _occupation;
private int _ID;
public string Occupation
{
get { return _occupation; }
set
{
if (_occupation != value)
{
_occupation =
value;
RaisePropertyChanged(
"Occupation");
}
}
}
public int ID
{
get { return _ID; }
set
{
if (_ID != value)
{
_ID =
value;
RaisePropertyChanged(
"ID");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
// take a copy to prevent thread issues
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(
this, new PropertyChangedEventArgs(propertyName));
}
}
}
}