Home Forums WinForms controls Xceed Chart for WinForms Dynamically set color of bars in a BarSeries?

Viewing 11 posts - 1 through 11 (of 11 total)
  • Author
    Posts
  • User (Old forums)
    Member
    Post count: 23064
    #19227 |

    I’m currently evaluating xCeed for use in a program where a gauge is needed. I have a dataset which must be graphed over a min-max range, and within that range an average must be highlighted.

    To do this I’m currently using a 2D bar chart with a single BarSeries, where:

    – The width of the X axis is the possible range of my data

    – All bars within the min/max that’s calculated are filled in with the same value and color

    – An average is calculated

    – The data will be collected continuously, so the bar representing the average will need to be updated continuously as the average moves.

    Is there a way, as my averages are calculated to be at some X coordinate, to set the bar at just that coordinate to a different color than the rest of the bars?

    Imported from legacy forums. Posted by Victor (had 2250 views)

    Diane [Xceed]
    Moderator
    Post count: 1353

    Hi Victor,

    I’m not sure I completely understand what you mean. Could you provide a screen shot showing the look you would like to achieve? Thank you.

     

    Imported from legacy forums. Posted by Diane [Xceed] (had 431 views)

    User (Old forums)
    Member
    Post count: 23064

    I can’t provide a screen shot, because I haven’t been able to make this work.

    In short, assume I have a BarSeries of 100 bars named “bars”, which have a default color. Also assume there’s a bar I need to highlight, where the index of the bar to highlight constantly changes based on my data. Is there a way to reference the color elements of each bar in a bar series by index so I can constantly update the bar to highlight?

    I can explicitly set the values of buckets with the following code:

    bars.Values[<index>] = <value>

    Can I do the same with the color of a bar? 

    Imported from legacy forums. Posted by Victor (had 422 views)

    Diane [Xceed]
    Moderator
    Post count: 1353

    Hi Victor,

    I meant a screen shot like something modified in paint to demonstrate the look you wanted to get as an end result, but the description you gave allowed me to better understand.

    You can change the FillMode on the series’s Appearance to be ‘DataPoints’, that should allow you to assign different colors to each bar.

    For an example, please refer to the Standard 2D Bar Chart in the Chart Explorer. There’s a “Different Fill Effects” checkbox in the options on the right side (see attached screen shot).

     

    Imported from legacy forums. Posted by Diane [Xceed] (had 451 views)

    User (Old forums)
    Member
    Post count: 23064

    I’ve looked at this example, and it doesn’t appear to fit my application.

    Even if I set bars.Appearance.FillMode = AppearanceFillMode.DataPoints, the example shows no way to set the colors of the bars other than in the BarSeries.Add() constructor, which I don’t believe will be efficient for my application.

    My application:

    – Assumes a fixed number of bars, anywhere from 1 to 64k (2^0 through 2^16).

    – Creates those bars and initializes them to DBValue.Null when the chart is initially drawn

    – Collects data in real-time from a piece of hardware extremely fast, and wants update the bars values continuously.

    – Wants to look at the collected data set on each pass, process it, and highlight the bar representing the average.

    While the example you provided shows how to set a bar’s fill color when the bar is constructed, my data collection / value update / average value highlight algorithm takes place in a tight loop, and I need to be able to set the fill color of a bar that already exists on every pass, because the average will move as the data sets are processed.

    Any assistance you can provide here would be greatly appreciated. Other packages I’ve evaluated so far for our application aren’t as fast as Xceed from a rendering standpoint, and so I very much want to use this package. However, if I can’t get the support I need in this particular instance, it will be a show-stopper.

    I’ll try to put together some screenshots to show what I’m looking for. 

    Imported from legacy forums. Posted by Victor (had 360 views)

    User (Old forums)
    Member
    Post count: 23064

    Diane,

    Here’s some more details on our application, and some screen shots:

    We read values from registers in our hardware in real-time and perform a histogram of those registers.  As an example, I’ve created a 2D Bar Chart that represents the values we might read from an 8-bit register. In this demo, instead of reading from our actual hardware, I’m creating Gaussian random data to create a nice bell curve quantized over 256 bars (8-bit, 2^8 = 256). See here:

    http://tinypic.com/r/15n88q1/6

    As a visual cue, I’d also like to highlight the average, like so:

    http://tinypic.com/r/20g1s46/6

    However, I can’t just set the bucket to a different fill color when it’s created; because we’re continuously collecting and processing data, I have to be able to change the bucket that’s highlighted as the average on-the-fly, and reset the previously highlighted average to the default fill color.

    In addition, often our users will want to perform this histogram analysis on multiple registers at one time (20-30). In order to reduce clutter on the screen, we implement gauges. Imagine the above histogram turned on its edge, where we define the same number of bars in X, with constant height in Y, using colors to represent important values (average, +1 std. deviation, -1 std. deviation, min, max, etc.), like this:

    http://tinypic.com/r/2rgdmqg/6

    I hope this helps you to understand my application, why I need to be able to dynamically change individual bar color, and if there’s some other way to accomplish this if changing individual bar color on-the-fly isn’t possible.

    Imported from legacy forums. Posted by Victor (had 404 views)

    Diane [Xceed]
    Moderator
    Post count: 1353

    Hi Victor,

    Once you set the Series’ FillMode to AppearanceFillMode.DataPoints, you can dynamically change the color of a DataPoint by changing the color in the Series’ FillEffects collection. All the collections are synced, so for example, the FillEffect at index 18 will correspond to the DataPoint for the value at index 18, etc. Also, you must make sure to call ChartControl.Refresh to make sure the chart redraws itself.

     

    Imported from legacy forums. Posted by Diane [Xceed] (had 373 views)

    User (Old forums)
    Member
    Post count: 23064

    Diane,

    Your suggestion didn’t work for me. Using the following code fragment, where AppearanceFillMode is set to “DataPoints” for this chart in the designer:

     

    Chart gauge;

    BarSeries bars;

    Int32 avg = 10; 

    gauge = (Chart)chartControl1.Charts[0];

    bars = (BarSeries)gauge.Series[0];

    bars.BarFillEffect[avg].Color = Color.Red;

     

    The last line of the above code returns a compiler error:

    ” Cannot apply indexing with [] to an expression of type ‘Xceed.Chart.Standard.FillEffect'”

    Any ideas why I can’t reference BarFillEffect by index? 

    Imported from legacy forums. Posted by Victor (had 273 views)

    Diane [Xceed]
    Moderator
    Post count: 1353

    Hi Victor,

    The BarFillEffect is not a collection, but rather a single FillEffect that will be applied to all bars. In your scenario, you need to modify the FillEffects collection.

    For example:

       // Index is zero-based, so this will change the color of the 2nd bar in my graph
       bars.Appearance.FillEffects[1] = new FillEffect(Color.DeepPink);

     

    Imported from legacy forums. Posted by Diane [Xceed] (had 293 views)

    User (Old forums)
    Member
    Post count: 23064

    Diane,

    This doesn’t appear to be working either, as I’m getting a out of bounds exception on the above statement.

    I need to be able to continuously update the color of whichever bar represents the average. This will be done in a loop, and I’m pretty sure I don’t want to be creating new FillEffect objects in a data processing loop, when I can create them ahead of time. I’m attempting to do the following:

    During initialization…

     

    for (int i = 0; i < 256; i++)

    {

        bars.Add(0, i.ToString());

        bars.Values[ i ] = DBNull.Value;

        bars.Appearance.FillEffects[ i ] = new FillEffect(Color.CornflowerBlue);

    }

     

    … later on in another thread, I’m trying this:

    for (int i=0; i < 256; i++)

    {

        bars.Values[ i ]= <whatever my latest values are>; 

    }

    bars.Appearance.FillEffects[avg].Color = Color.Red;

     

    which gives me the following compiler error on the last line.

    “‘object’ does not contain a definition for ‘Color’ and no extension method ‘Color’ accepting a first argument of type ‘object’ could be found” 

    So again, is there a way to reference an existing FillEffect by index, so I can change its FillEffect.Color attribute?

      

     

    Imported from legacy forums. Posted by Victor (had 439 views)

    User (Old forums)
    Member
    Post count: 23064

    Diane,

    I believe I have a solution which may work now. Changing the above code to the following appears to be working:

     

    During initialization…

     

    for (int i = 0; i < 256; i++)

    {

        bars.Add(0, i.ToString());

        bars.Values[ i ] = DBNull.Value;

        bars.Appearance.FillEffects.Add(new FillEffect(Color.CornflowerBlue));

    }

     

    … later on in another thread, I’m trying this:

    FillEffect effect; 

    for (int i=0; i < 256; i++)

    {

        bars.Values[ i ]= <whatever my latest values are>; 

    }

    effect = (FillEffect)bars.Appearance.FillEffects[128];

    effect.Color = Color.Red;

     

    Thanks very much for all the support to this point.

     

    Imported from legacy forums. Posted by Victor (had 2613 views)

Viewing 11 posts - 1 through 11 (of 11 total)

You must be logged in to reply to this topic.