This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
Hi There, We want be able to put some label inside a scatter or bubble series as shown in the attached image, how can we do that? We are planning to use version 7.0, will the fixes in version 6.0 be available on version 7.0? Thanks, Gordon |
|
|
Hello Gordon You should be able to do this by setting a custom SymbolStyle (ScatterSeries), or BubbleStyle (BubbleSeries) to customize the look to include the numbers. The DataContext of the rendered data points is the model object from the ItemsSource collection. So if your model objects have some kind of index property that provides this label value, you could simply bind to that. The legend would need to be custom built because a single ScatterSeries only provides a single legend item. Let me know if you have further questions about this. -Jason Fauchelle |
|
|
Hi Jason, I can overlay a textblock on top of the path to make it work by binding the textblock.Text to the data points label, but how can i make the binding works for legend? The following is what I did to change On SymbolStyleBase:
and the image looks like in the file attached. I want the Lengend also show the numbers, how do we do that? Thanks, Gordon |
|
|
Hello Gordon The symbols displayed in the legend don't have any data to bind to - it doesn't make sense for them to have X/Y values, they are just place holders. The easiest way to achieve the result you want would be to not use the built-in legend, and instead, display a stack panel of custom items that render the numbers you want. Another approach would be to set the LegendIconTempate of the series to be a circle displaying some value. Remember that scatter series only has a single legend item though, from your previous image it looked like you might want a legend item for each data point. This is why displaying your own custom legend visual would be easier, but another alternative would be to extend the Scatter series class and override the LegendItems property to return multiple items, each which could rendered a different number. -Jason Fauchelle |
|
|
Hi Jason, Binding to the Y there is just to do the demo. I will have a Property Label with my Data Point class, so it will bind to the label. Each data point will have different Label value. Option #1) For the idea "display a stack panel of custom items that render the numbers you want.", the problem is that if I want to have it in different position, I cannot use the the built-in legend position to set it like other plots do (or I have write a lot of code to do it, synchronize the legend position will be hard) Option #2) For the idea "extend scatterseries and override the LegendItems" sounds like a good one, but when "LegendItems" get called from UpdateLegend() function, the DataSeries does not have any data points, (the DataPoints.Count is 0) so how do we know the number of the legend object to create and how do we binding or get the label value. So sample would be very helpful. How do we even put the label on icon template? Option #3) Since for this kind plots, I will not have more than 300 points, Even though it will be very silly, I can create a lot of scatter series, each series will only have one point, but how to bind to the Label value for the datapoint on the legend? (I have already used the DataSeries.Tag.) My preferred order of solving this problem would be option #2), #3) and #1). Thanks, Gordon |
|
|
Hello Gordon For #2, I forgot to mention you'll need to listen to when the items source changes in some way, and then call the OnLegendItemsChanged method which will cause the legend to be updated. This will mean that the data points will be available so you can iterate the ItemsSource and add a legend item for each one (inside the LegendItems property). For each item to display a label, you could either build the template in code as you create each LegendItem, or you could set the DataContext of each LegendItem to be the label that you want to display, and then bind to the DataContext value in the template. Let me know if you have further questions as you work on this. -Jason Fauchelle |
|
|
Hi Jason, In when the ItemsSource changed event fired up, the LegendIconTemplate is still null and cannot override the function OnLegendIconTemplateChanged() since it is defined as internal. Is that possible to make it over-ridable outside? also, the constructor of LegendItem(string label, DataTemplate iconTemplate, Brush iconBrush, DataSeries dataSeries) is not available outside. Thanks, Gordon |
|
|
Hello Gordon Those members will be public/protected for you to access in the next nightly build. -Jason Fauchelle |
|
|
Thanks, Jason. Will it be in version 7 nightly build, we planning to upgrade it next week. Gordon |
|
|
Yes, all fixes and improvements will be in the version 7 nightly builds. -Jason Fauchelle |
|
|
Hi Jason, How do we create new LegendIconTemplate from existing one? Since we need to have its own LegendIconTemplate for each data point in order for the databinding to work properly. Thanks, Gordon |
|
|
Hello Gordon You should just be able to set the DataContext or Tag property of each LegendItem instance to be the value that you want to display. That way, you'd only need a single LegendIconTemplate which binds to the DataContext or Tag value. If you do need to create a different template for each item, it may be easier to build the templates up from scratch rather than reading an existing template to create new ones. -Jason Fauchelle |
|
|
Hi Jason, Since the LegendIconTemplate has to bind to each data point, that's why we need to have different instace for each point. Otherwise, it will not work. Thanks, Gordon |
|
|
Hi Jason, LegendItem class does not have any Tag or DataContext property, how can I set them? I guess I need to derive the MylegendItem from your LegendItem class and add Tag property if Legend class will recognize it (checking your source code from version 6.0, it seemed it is doable) I am using WPF Element verssion 7 nightly build. Since I don't have access for the OnItemsSourceChanged event (in the constructor, the itemsSource is still null, so I have no way to do) or rights to override the functions ItemsSourceCollectionChanged or BindingListListChanged, I cannot add number of LegendItems according to the number of points, So I have to mix option #2 and #3 to accomplish our user's request. To summarize what I need to do: 1) Derive from Scatter Series and override LegendItems (use the new class from step 2)) 2) Derive from LegendItem and add a property Label and Bind this Label to the Symbol's TextBlock mentioned previously 3) Every single point is a scatterseries , i.e. if you have 20 points, you will create 20 scatter series The only thing I am afraid is that if I have a lot of data points, the plots will be very slow. If you see anything not feasible, please let me know. Thanks, Gordon |
|
|
Hello Gordon Indeed there is too much missing to continue with this approach. I recommend trying to implement #1. One way to do this would be to provide a custom legend style, but instead of binding to the ItemsSource of the legend, the style could bind to the ItemsSource of your first series. This would allow you to continue using all the features of a legend such as being able to set the LegendPosition property. Here is a simple code sample that demonstrates this. (You may also want to switch to a horizontal layout when the position it Top or Bottom). The main thing to notice in this code is how the ItemsSource of the ItemsControl is being set.
You will also need to make a LegendItemTemplate resource as referenced in the above code. The data context of the template will be raw data that you are plotting on the chart. From your raw data you should be able to get the number you want to display, as well as a label. I hope that gets you further along. Let me know if you have any questions. -Jason Fauchelle |
|
|
Thanks, Jason. This approach seems better than my approach. I will try to see if I can make it work... Gordon |
|
|
Hi Jason, I don't know what I have done wrong, here is code I put:
and
It is has that number of legend as in series #1, but I don't have the icon and the LegendLabel shown (see picture attached) |
|
|
Hello Gordon Since the data context of the items will now be the raw data being plotted, rather than LegendItem objects, you will not have access to LegendIconTemplate and LegendLabel properties in the LegendItemTemplate. Instead, you need to create a template that binds to properties on the raw plotted data. Here is an example of one such template, styled similar to one of you original images:
You'll want a property on your raw plotted data to provide the number that you want to display here. Then replace "Binding X" in the above code with an appropriate binding to that property. -Jason Fauchelle |
|
|
Thanks, Jason. It works for single ScatterSeries. My problem is that if I have more than 1 scatterseries and I want to do that for all the series. I tried the following:
When I ran it, it gives me the following error: System.Windows.Data Error: 26 : ItemTemplate and ItemTemplateSelector are ignored for items already of the ItemsControl's container type; Type='ScatterSeries' If you can help it would be great. |
|
|
Hi Gordon, I'm not sure I've come across this issue before, but in any case, it would be best not to set the ItemsSource of an ItemsControl to be a list of the actual series. This is because the series are visual elements which are already part of the visual tree which could potentially cause the application to crash. I have come up with an alternative solution for you though: Create a converter to convert the list of series to a list of the raw data points. Here is an example of such converter:
Now in your legend style, you can use this as the ItemsControl (Where SeriesToItems is an instance of the above converter):
Hope that helps. -Jason Fauchelle |
|
|
Thanks, Jason. I did not think the series is visual element. You have been very helpful as usual. Gordon |
|
|
Hi Gordon, Certainly understandable, I too would think series wouldn't be a visual element, but it turns out this is required in order for xaml bindings to work on the series properties. Great to hear my solution helped out. -Jason Fauchelle |
|