krb875 Posted June 19, 2008 Report Share Posted June 19, 2008 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! Quote Link to comment Share on other sites More sharing options...
JuanC Posted June 20, 2008 Report Share Posted June 20, 2008 >> 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 Quote Link to comment Share on other sites More sharing options...
krb875 Posted June 20, 2008 Author Report Share Posted June 20, 2008 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 Quote Link to comment Share on other sites More sharing options...
krb875 Posted June 24, 2008 Author Report Share Posted June 24, 2008 JuanC, did you have any ideas of how to get this accomplished? Quote Link to comment Share on other sites More sharing options...
krb875 Posted June 25, 2008 Author Report Share Posted June 25, 2008 I still have not been able to get the legend to edit out the extra series or to display itself over the graph instead of on the side. Did anything with the new release help here? Thanks Quote Link to comment Share on other sites More sharing options...
BMWSauberF1 Posted June 26, 2008 Report Share Posted June 26, 2008 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> Quote Link to comment Share on other sites More sharing options...
krb875 Posted June 26, 2008 Author Report Share Posted June 26, 2008 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 Quote Link to comment Share on other sites More sharing options...
JuanC Posted June 26, 2008 Report Share Posted June 26, 2008 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 Quote Link to comment Share on other sites More sharing options...
krb875 Posted June 26, 2008 Author Report Share Posted June 26, 2008 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. Quote Link to comment Share on other sites More sharing options...
krb875 Posted June 26, 2008 Author Report Share Posted June 26, 2008 Also i got the latest hotfix and cant get this to work I made blank constructor in my XYMeasure class that does not set the values to anything but by default it is set to 0,0, and it places all the points there. Quote Link to comment Share on other sites More sharing options...
JuanC Posted June 27, 2008 Report Share Posted June 27, 2008 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 Quote Link to comment Share on other sites More sharing options...
krb875 Posted June 30, 2008 Author Report Share Posted June 30, 2008 JuanC, I got the latest build 3097, how do I set the double's to nullabe so they will be a hidden value? Quote Link to comment Share on other sites More sharing options...
krb875 Posted June 30, 2008 Author Report Share Posted June 30, 2008 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; } } } } Quote Link to comment Share on other sites More sharing options...
krb875 Posted June 30, 2008 Author Report Share Posted June 30, 2008 Thanks alot, this works I had a problem with my reference! I appreciate all the help Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.