Jump to content
Software FX Community

How to only display certain elements in the legend box.


krb875
 Share

Recommended Posts

I have a multi series graph that actually uses multiple series to show the same graph because of discontinuities in the line.  Here is a link to the print out I am currently generating so you have an idea of what I mean

http://img.photobucket.com/albums/v667/krb875/Summary.jpg?t=1213914483

 I need to create a legend box that is ontop of the current graph with a clear background so that I can maximize space.  Here is the problem, for instance the botton left graph has two red and two blue lines, but I only want 2 entries in the legend box.  I know I can set what shows up in the box with the series.content command.  I am using C# to generate this graph so I would prefer to stick with that if at all possible.  I can create a legendbox right now but it is off to the side and contains two hot and two cold items.  Also a stretch, but is there anyone to link the plots together so that when one is highlighted in the legend box it would show all the Hot or Cold data.

 

thanks for all the help, cant wait for the release!

Link to comment
Share on other sites

>> I have a multi series graph that actually uses multiple series to show the same graph because of discontinuities in the line.

Can you explain how your data looks like (i.e. classes in your data layer or columns in your database)?

We support discontinuities in the line through a predefined value (Chart.Hidden) so you should be able to get the chart want only using 2 series, this will make sure that you do not have to "hack" the legend box or highlight.

Regards,

JuanC

Link to comment
Share on other sites

Im actually using this as a COM object to display data from a VB6 project, as well as future other .NET projects.  I am just reprocessing the data based on the input.  The user is actually calling this function for each seperate "series" even if they are technically the same data.  The reason for this is we are processing multiple regions of a camera and collecting that data. As you can see I am just seperating every other line as Hot and then Cold Data.  There is an overlap between the regions which is why at the interval the points overlap.  I would like to keep this struction because it is not set how many data points each region contains so this gives us flexibility to support many different camera types and other applications, If i use a "hidden" variable I think it will be hard to maintain this, and I am assuming I would have to pass in all the data in one long gather. 

public void plotResponsePlots(double[][] value, int step, int start)

{

for (int k = 0; k < value.Length; k++)

{

this.m_Report.axes_resp.ItemsSource = null;

double location = start;ChartFX.WPF.SeriesAttributes series = new ChartFX.WPF.SeriesAttributes();

List<XYMeasure> dataPts = new List<XYMeasure>();for (int i = 0; i < value[k].Length; i++)

{

dataPts.Add(new XYMeasure(location, value[k]));if (i < value[k].Length - 1)

{

location += step;

}

}

if (k % 2 == 0)

{

series.Fill = System.Windows.Media.Brushes.Red;series.Content = "Hot";

}

else

{

series.Fill = System.Windows.Media.Brushes.Blue;series.Content = "Cold";

}

series.ItemsSource = dataPts;

series.BindingPath = "Y";

series.BindingPathX =

"X";series.Marker.Shape = ChartFX.WPF.MarkerShape.Circle;this.m_Report.axes_resp.Series.Add(series);

}

}

 

 

 

Also before I forget, is there a way to inlay the legend box on the graph instead of to the side so that the graph points going behind the legend.

Kinda like this: (this is the matlab code i am replacing)

http://img.photobucket.com/albums/v667/krb875/MHTWS_0011153_Summary.jpg

 

Link to comment
Share on other sites

This code allows you to place the legend inside the plot area.

<cfx:Chart Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Grid.RowSpan="2" Name="ctlChart1">

<cfx:Chart.PlotArea>

<cfx:PlotAreaAttributes ClipToBounds="false"/>

</cfx:Chart.PlotArea>

<cfx:Chart.LegendBox>

<cfx:LegendBox Visibility="Visible" cfx:Chart.TargetPanel="Inside" DockPanel.Dock="Top" HorizontalAlignment="Right" Margin="4" Background="Yellow">

</cfx:LegendBox>

</cfx:Chart.LegendBox>

</cfx:Chart>

 

Link to comment
Share on other sites

That works great! no my main problem is the legend box, how can i in c# determine which series it adds to the legend box.

 

I would like a method that would check series.content and if they are the same combine them into one series on the legend, or something like that.  Or any other ideas how to get this accomplished

Link to comment
Share on other sites

Obviously you know more about your data but it seems to me that you are clearly plotting 2 series as implied by these statements

"but I only want 2 entries in the legend box"

"Also a stretch, but is there anyone to link the plots together so that when one is highlighted in the legend box it would show all the Hot or Cold data"

Because of this I think using 2 series will be beneficial for your particular chart, I modified your plotResponsePlots function as follows

public void plotResponsePlots (Chart chart, double[][] value, int step, int start)

{

  chart.ItemsSource =

null;   List<XYMeasure> dataHot = new List<XYMeasure>();

  List<XYMeasure> dataCold = new List<XYMeasure>();

  double location;

  for (int k = 0; k < value.Length; k++) {

  List<XYMeasure> dataPts = ((k % 2) == 0) ? dataHot : dataCold;   if (dataPts.Count != 0) {

  // Start line from previous value

 

location = ((double) dataPts[dataPts.Count - 1].X) + step;

  // Add an empty XYMeasure, this will provide the line break

 

dataPts.Add(new XYMeasure());

}

else

 

location = start; for (int i = 0; i < value[k].Length; i++) {

  dataPts.Add(

new XYMeasure(location, value[k]));

  location += step;

  }

  }

  ChartFX.WPF.

SeriesAttributes seriesHot = new SeriesAttributes();

  seriesHot.Fill = System.Windows.Media.

Brushes.Red;

  seriesHot.Content =

"Hot";

  seriesHot.Marker.Shape = ChartFX.WPF.

MarkerShape.Circle;

  assignSeriesData(dataHot, seriesHot);

  ChartFX.WPF.

SeriesAttributes seriesCold = new SeriesAttributes();

  seriesCold.Fill = System.Windows.Media.

Brushes.Blue;

  seriesCold.Content =

"Cold";

  seriesCold.Marker.Shape = ChartFX.WPF.

MarkerShape.Circle;

  assignSeriesData(dataCold, seriesCold);

  chart.Series.Add(seriesHot);

  chart.Series.Add(seriesCold);

}

public void assignSeriesData (List<XYMeasure> dataPts, ChartFX.WPF.SeriesAttributes series)

{

  series.BindingPath =

"Y";

  series.BindingPathX =

"X";

  series.ItemsSource = dataPts;

}

I tested it with code like this

double[][] data = new double[4][];

data[0] =

new double[] { 10, 12, 14 };

data[1] =

new double[] { 8, 10, 12 };

data[2] =

new double[] { 10, 12, 14, 12, 10, };

data[3] =

new double[] { 8, 10, 12, 11, 9 };

plotResponsePlots(chart1, data, 1, 1);

Note that you might need a new hotfix (send email to wpf at softwarefx dot com) as we recently fixed an issue related to reading data from nullable values. We will investigate other ways to hide series from the legendbox but I truly think creating 2 series will work best for you. 

Hope this helps

JuanC

Link to comment
Share on other sites

I explored this way to do it the problem is that I will be calling each of these functions over 5 times each, meaning i have to seperate and create a seperate XYMeasure and a sepereate series for each, instead of doing it as I was earlier. I can def do it this way it just will be a mess. This might not seem like such a bad thing for the example you have shown but when My temp refs plot has 7 lines over 6 regions (42 series calls) it makes the code hugely wasteful.  I think the best way would be to have some sort of option that if you set your Content to the same name on a chart.  like series1.content = "Hot"; series2.content="hot" have a way to toggle whetehr or not you want the chart to combine these into one series rather than keeping them seperate, but inserting a blank datapoint between each existing series. 

Link to comment
Share on other sites

Please note that to use the suggested approach you have to make sure that

- XYMeasure fields and properties are nullable, i.e. double?

- You must be using ChartFX.WPF build 3093 or later, you can request a hotfix sending a message to wpf at softwarefx dot com

Regards,

JuanC

Link to comment
Share on other sites

The following is my XYMeasure code, but when I call add XYMeasure() it seems to put the point at 0,0 anyways.

 

using

System;

using

System.Collections.Generic;

using

System.Linq;

using

System.Text;

using

ChartFX.WPF;namespace IRTECH.ModCal.FileIO

{

public class XYMeasure

{

private Nullable<double> m_x;

private Nullable<double> m_y;public XYMeasure()

{

m_x = null;m_y = null;

}

public XYMeasure(Nullable<double> x, Nullable<double> y)

{

m_x = x;

m_y = y;

}

public Nullable<double> X

{

get { return m_x; }set { m_x = value; }

}

public Nullable<double> Y

{

get { return m_y; }set { m_y = value; }

}

}

 

}

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...