Dragging C1DataGrid Data to C1Chart Control Using Column Headers
In this blog article, I am going to showcase a small implementation which shows the interaction between C1Chart and C1DataGrid with the help of C1DragDropManager control from our Silverlight suite. Objective of the blog is to support dragging of Column headers to Chart control to display corresponding Column values as DataSeries. Implementation begins by setting up the C1DataGrid and C1Chart control.
ObservableCollection<MyDataClass> dataList = new ObservableCollection<MyDataClass>();
public void SetupGrid()
{
dataList.Add(new MyDataClass() { ProductName = "Chai", UnitPrice = 18.00, UnitsInStock = 39.00 });
dataList.Add(new MyDataClass() { ProductName = "Chang", UnitPrice = 19.00, UnitsInStock = 17.00 });
dataList.Add(new MyDataClass() { ProductName = "Ikura", UnitPrice = 31.00, UnitsInStock = 31.00 });
dataList.Add(new MyDataClass() { ProductName = "Pavlova", UnitPrice = 17.45, UnitsInStock = 29.00 });
dataList.Add(new MyDataClass() { ProductName = "Tunnbröd", UnitPrice = 9.00, UnitsInStock = 61.00 });
dataList.Add(new MyDataClass() { ProductName = "Gravad lax", UnitPrice = 26.00, UnitsInStock = 11.00 });
dataList.Add(new MyDataClass() { ProductName = "Geitost", UnitPrice = 25.00, UnitsInStock = 50.00 });
dataList.Add(new MyDataClass() { ProductName = "Chocolade", UnitPrice = 12.75, UnitsInStock = 15 });
dataList.Add(new MyDataClass() { ProductName = "Pâté chinois", UnitPrice = 24.00, UnitsInStock = 30 });
c1DataGrid1.ItemsSource = dataList;
c1DataGrid1.LoadedColumnHeaderPresenter += new EventHandler<C1.Silverlight.DataGrid.DataGridColumnEventArgs>(c1DataGrid1_LoadedColumnHeaderPresenter);
}
public void SetupChart()
{
c1Chart1.Data.Children.Clear();
var list = (from prod in dataList select prod.ProductName);
c1Chart1.View.AxisY.Max = 10;
c1Chart1.View.AxisY.AutoMax = false;
c1Chart1.View.AxisY.Min = 0;
c1Chart1.View.AxisY.AutoMin = false;
c1Chart1.View.AxisX.AnnoAngle = 90;
// add a dummy series to the chart
// required to display the Axis Labels
int[] PriceX = { 0, 0, 0, 0, 0, 0, 0, 0 };
DataSeries ds1 = new DataSeries();
ds1.Label = "dummy";
ds1.ValuesSource = PriceX;
c1Chart1.Data.Children.Add(ds1);
//add item names
c1Chart1.Data.ItemNames = list.ToArray();
// Set chart type
c1Chart1.ChartType = ChartType.Column;
}
If you observe the above module to initialize the C1Chart, you will notice that I have added a dummy series. This is required to display Axis Labels initially as they are not visible till we have a DataSeries added to the Series collection. Next we need to add a C1DragDropManager control.
C1.Silverlight.C1DragDropManager dragManager = new C1.Silverlight.C1DragDropManager();
Once you have the C1DragDropManager control, you need to enable the dragging of the ColumnHeaders and Chart Bars(PlotElements).
void c1DataGrid1_LoadedColumnHeaderPresenter(object sender, C1.Silverlight.DataGrid.DataGridColumnEventArgs e)
{
if (e.Column.Index > 0)
dragManager.RegisterDragSource(e.Column.HeaderPresenter, C1.Silverlight.DragDropEffect.Copy, ModifierKeys.None);
}
void ds1_PlotElementLoaded(object sender, EventArgs e)
{
PlotElement pe = sender as PlotElement;
dragManager.RegisterDragSource(pe, C1.Silverlight.DragDropEffect.Copy, ModifierKeys.None);
}
Next we setup the Chart and Grid controls as drop source as well.
dragManager.RegisterDropTarget(c1Chart1, true);
dragManager.RegisterDropTarget(c1DataGrid1, true);
Now remains the final implementation to add the DataSeries on the basis of dragged Column Header.
void dragManager_DragDrop(object source, C1.Silverlight.DragDropEventArgs e)
{
// Add the Series for the field dragged on the Chart control
if (e.DropTarget.GetType().Equals(typeof(C1.Silverlight.Chart.C1Chart)))
{
string draggedfield = (((C1.Silverlight.DataGrid.DataGridColumnHeaderPresenter)(e.DragSource)).Content as TextBlock).Text;
var fieldValues = new List<double>();
// Get the Series values from the ObservableCollection
if (draggedfield == "UnitPrice")
fieldValues = (from val in dataList select val.UnitPrice).ToList();
else
fieldValues = (from val in dataList select val.UnitsInStock).ToList();
if (c1Chart1.Data.Children.Count == 1 && c1Chart1.Data.Children[0].Label == "dummy")
c1Chart1.Data.Children.Clear();
// Check if series has already been added in Chart
foreach (DataSeries ds in c1Chart1.Data.Children)
if (ds.Label == draggedfield)
return;
// add series to the chart
DataSeries ds1 = new DataSeries();
ds1.Label = draggedfield;
ds1.ValuesSource = fieldValues.ToList();
ds1.PlotElementLoaded += new EventHandler(ds1_PlotElementLoaded);
c1Chart1.Data.Children.Add(ds1);
// Reset the Axis Min and Max as per
// the values of new DataSeries
double fldMin = fieldValues.Min();
if (fldMin < c1Chart1.View.AxisY.Min)
c1Chart1.View.AxisY.Min = fldMin;
double fldMax = fieldValues.Max();
if (fldMax > c1Chart1.View.AxisY.Max)
c1Chart1.View.AxisY.Max = fldMax;
}
// Remove the series for the Chart bar dragged on to the Grid
else
{
c1Chart1.Data.Children.Remove((e.DragSource as PlotElement).DataPoint.Series);
if (c1Chart1.Data.Children.Count == 0)
SetupChart();
}
}
Download the attached sample applications for complete implementation. Download C# Sample Download VB.Net Sample