This is a migrated thread and some comments may be shown as answers.

Setting bar chart bar color?

15 Answers 714 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Dan
Top achievements
Rank 2
Dan asked on 17 Jul 2009, 05:35 PM
I know this is probably the dumb question of the day, but...
How do I set the color of the bars in a bar chart?
In the designer I have the Series Appearance,Appearance,FillStyle,FillSettings,MainColor = CornflowerBlue
and I have the PlotArea,DataTable,Appearance,FillStyle,FillSettings,MainColor = CornflowerBlue
but this cannot be right as my bars are still some aqua blue color.

???
Dan

15 Answers, 1 is accepted

Sort by
0
Giuseppe
Telerik team
answered on 22 Jul 2009, 07:24 AM
Hi Dan,

Besides setting the ChartSeries.Appearance.FillStyle.MainColor, you would need to set the FillType as well. Here is the designer-generated code that produces the desired effect:

chartSeries1.Appearance.FillStyle.FillType = Telerik.Reporting.Charting.Styles.FillType.Solid; 
chartSeries1.Appearance.FillStyle.MainColor = System.Drawing.Color.Red; 


We have attached a sample class library as well.


Sincerely yours,
Manuel
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Dan
Top achievements
Rank 2
answered on 22 Jul 2009, 05:15 PM

Manuel,

The attached class library appears to be empty.  Can you repost?

 

It seems that the chart series items are available only in the ItemDataBound event, so I tried the following code, but it does not affect the color of the chart bars.

 

private

 

void chart1_ItemDataBound(object sender, EventArgs e)

 

{

 

 

 

foreach (ChartSeriesItem item in chart1.Series[0].Items)

 

{

item.Appearance.FillStyle.MainColor =

Color.CornflowerBlue;

 

item.Appearance.FillStyle.FillType = Telerik.Reporting.Charting.Styles.

FillType.Solid;

 

item.Label.Appearance.FillStyle.MainColor =

Color.Black;

 

item.Label.Appearance.FillStyle.FillType = Telerik.Reporting.Charting.Styles.

FillType.Solid;

 

}

}

Dan

0
Steve
Telerik team
answered on 23 Jul 2009, 05:38 AM
Hi Dan,

Actually as explained in this help article, if you want to make any changes to the definition chart item, NeedDataSource event is the event for you. Moving your code to the NeedDataSource event should work as expected.

Please try it and let us know if further help is needed.

Sincerely yours,
Steve
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Dan
Top achievements
Rank 2
answered on 23 Jul 2009, 02:08 PM
Nope.

In chart1_NeedDataSource,  chart1.Series.Count = 0

I cannot set properties on a series that does not yet exist.

Dan
0
Steve
Telerik team
answered on 24 Jul 2009, 07:22 AM
Hello Dan,

Find attached a modified version of the class library from previous post. Note that the bar chart color is set both declaratively (from report designer) and programmatically in NeedDataSource event.

Sincerely yours,
Steve
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Dan
Top achievements
Rank 2
answered on 24 Jul 2009, 01:35 PM
In your example, the series is a hard-coded, static series.  And so, its series items are available for setting of properties in the NeedDataSource event.

However, in my case, the series is generated dynamically via SQL data query into a DataSource which is applied to the chart in the NeedDataSource event routine.  In which case the items are not yet available for property setting at that point.  The series items are only available in the ItemDataBound routine.  And setting the FillStyle properties in the ItemDataBound routine does not affect the bar colors.

Dan
0
Steve
Telerik team
answered on 24 Jul 2009, 02:33 PM
Hi Dan,

You're correct. I'm afraid however that the only solution would be to create the chart series at runtime while setting their color as well, before populating the chart from your db.

Kind regards,
Steve
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Dan
Top achievements
Rank 2
answered on 24 Jul 2009, 03:24 PM
Steve,

If generating the series at runtime is possible, I'm not sure how it is.  My case is:

Two report parameters.
User selects the two parameters.
In NeedDataSource, the report parameters affect the SQL record query, and so, the number of series items is dependent on the report parameters chosen.

When is the series created in this case?

In NeedDataSource, can I add series1, and add the appropriate number of series items, set their color, then assign the DataSource to the chart?

Thanks.
Dan

ps: Is there a reason why I cannot assign the color properties in the ItemDataBound routine?
0
Accepted
Chavdar
Telerik team
answered on 27 Jul 2009, 03:08 PM
Hello Dan,

You can create and customize the chart entirely in the NeedDataSouce event of the Chart report item. Consider the following example:

private void chart1_NeedDataSource(object sender, EventArgs e) 
        { 
            DataTable table = new DataTable(); 
            table.Columns.Add("Value"typeof(double)); 
            table.Columns.Add("Color"typeof(Color)); 
            table.Rows.Add(new object[] { 1.0, Color.Red }); 
            table.Rows.Add(new object[] { 1.5, Color.Green }); 
            table.Rows.Add(new object[] { 2.0, Color.Blue }); 
            table.Rows.Add(new object[] { 3.2, Color.Yellow }); 
 
            Telerik.Reporting.Processing.Chart chart = (Telerik.Reporting.Processing.Chart)sender; 
            Telerik.Reporting.Chart chartDef = (Telerik.Reporting.Chart)chart.ItemDefinition; 
            Telerik.Reporting.Charting.ChartSeries series = new Telerik.Reporting.Charting.ChartSeries(); 
 
            foreach (DataRowView rowView in table.DefaultView) 
            { 
                Telerik.Reporting.Charting.ChartSeriesItem seriesItem = new Telerik.Reporting.Charting.ChartSeriesItem(); 
                seriesItem.YValue = (double)rowView["Value"]; 
                seriesItem.Appearance.FillStyle.FillType = Telerik.Reporting.Charting.Styles.FillType.Solid; 
                seriesItem.Appearance.FillStyle.MainColor = (Color)rowView["Color"]; 
                series.AddItem(seriesItem); 
            } 
 
            chartDef.Series.Clear(); 
            chartDef.Series.Add(series); 
        } 

Note that when creating the series and the series items programmatically you do not have to set the DataSource property.

Sincerely yours,
Chavdar
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Dan
Top achievements
Rank 2
answered on 30 Jul 2009, 01:17 PM
Guys,
The problem here is with using the standard databinding, using NeedDataSource, into the chart which is the convenient way to populate the chart data from the database data.  Here is your ProcessItem code:

protected override void ProcessItem()
{
    this.chart.RaiseNeedDataSource(this, EventArgs.Empty);
    Chart chart = ((IChartComponent) this.chart).Chart;
    if (chart.DataManager.DataSource != this.dataSource)
    {
        chart.DataManager.DataSource = this.dataSource;
        chart.DataManager.DataBind();
    }
    chart.ImageFormat = ImageFormat.Emf;
    this.chartImage = chart.GetImage(this.chart.Width.Pixels, this.chart.Height.Pixels);
}

The DataSource is bound and then the chart image is immediately created.  There is no way to adjust the Appearance properties of the series.  It would be convenient to add an event or change the flow of the current events (i.e. put ItemDataBound BEFORE the chart.GetImage call) so that a user of your architecture could adjust necessary properties before the chart image is rendered.

Your suggestion above is to manually populate the chart series in the NeedDataSource routine.  Alternatively, I have used this method.  Add an ItemDataBound routine which does the formatting using the Appearance properties of the chart items and then calls the ProcessItem() method of the chart using reflection to generate the chart image again.

private void chart1_ItemDataBound(object sender, EventArgs e)
{
 Telerik.Reporting.Processing.Chart chart = (sender as Telerik.Reporting.Processing.Chart);
 if (chart != null)
 {
  Telerik.Reporting.Chart ch = chart.ItemDefinition as Telerik.Reporting.Chart;
  // adjust chart properties
  foreach (Telerik.Reporting.Charting.ChartSeries series in (ch as Telerik.Reporting.Charting.IChartComponent).Chart.Series)
  {
   series.Appearance.FillStyle.FillType = Telerik.Reporting.Charting.Styles.FillType.Gradient;
                      series.Appearance.FillStyle.MainColor = Color.FromArgb(18, 97, 146);
   series.Appearance.FillStyle.SecondColor = Color.FromArgb(199, 233, 254);
   foreach (Telerik.Reporting.Charting.ChartSeriesItem item in series.Items)
   {
                         item.Label.TextBlock.Appearance.TextProperties.Color = Color.Black;
   }
  }
  // fire ProcessItem() again to regenerate chart image now that we have changed our appearances
  MethodInfo meth = chart.GetType().GetMethod("ProcessItem", BindingFlags.NonPublic | BindingFlags.Instance);
  meth.Invoke(chart, null);
 }
}

Then make sure to not query the database for the chart data a second time in NeedDataSource:

 

 

private int boundCount = 0;

 

private void chart1_NeedDataSource(object sender, EventArgs e)
{
     boundCount++;
     if (boundCount % 2 == 1)
     {
         try
         {
             string commandText = "select database query";
             SqlDataAdapter adapter = new SqlDataAdapter(commandText, localConnectionstring);
             DataSet ds = new DataSet();
             adapter.Fill(ds);
             (sender as Telerik.Reporting.Processing.Chart).DataSource = ds.Tables[0].DefaultView;
          }
          catch (Exception ex)
          {
                    log1.WriteError(ex);
          }
    }
}

 

0
Steve
Telerik team
answered on 30 Jul 2009, 01:41 PM
Hello Dan,

We're very much aware of the limitations imposed by the current chart item. As you have probably noticed, it is the only report item that does not use the reporting data engine and this is one of the reasons why it cannot be databoud from the report designer. Improving the reporting chart item is in our TODO list and we hope that we would soon have the time to work in that direction.
For the time being, creating the series and the series items programmatically (excluding your approach which is a bit of a hack using reflection) is the only workaround.

Kind regards,
Steve
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Dan
Top achievements
Rank 1
answered on 06 Aug 2009, 11:11 PM
Hi Dan,

Thankyou for posting this. Very useful. Searched for ages trying to find a solution.

Regards,
Dan H
0
Michael Epley
Top achievements
Rank 1
answered on 12 Sep 2010, 05:59 PM
Thanks for the reflection Tip Dan, I was looking everywhere for a solution to this.
0
Deva
Top achievements
Rank 1
answered on 26 Apr 2011, 09:21 PM
Thanks Dan, That worked like a charm, setting the colors in code for us in the NeedDataSource, when we were creating our series did not work at all...

-Deva
0
Rob
Top achievements
Rank 1
answered on 05 Jan 2012, 11:40 PM
Thanks Dan, huge help. This opens up a whole spectrum of much-need functionality. I applied the same concept to create a chart with a dynamic size that adjusts to the size of your dataset. 

private void yourOwnChartName_ItemDataBound(object sender, EventArgs e)
        {
            Telerik.Reporting.Processing.Chart chart = (sender as Telerik.Reporting.Processing.Chart);
            if (chart != null)
            {
                //adjust size of chart.
//Basically start with a minimum size to display the axes. In this case it's 30, which corresponds roughly to a third of an inch
            //Add to the size of the chart based on how many items are in your dataset.
               //In this example, I add roughly a third of an inch for every item.
                chart.Height = new Unit(30 + yourOwnChartName.Series[0].Items.Count * 30);

                // fire ProcessItem() again to regenerate chart image now that we have changed our appearances
                System.Reflection.MethodInfo meth = chart.GetType().GetMethod("ProcessItem", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                meth.Invoke(chart, null);
            }
        }

My chart was assigned a dataset via the designer, so I didn't need to implement the NeedDataSource method.
Tags
General Discussions
Asked by
Dan
Top achievements
Rank 2
Answers by
Giuseppe
Telerik team
Dan
Top achievements
Rank 2
Steve
Telerik team
Chavdar
Telerik team
Dan
Top achievements
Rank 1
Michael Epley
Top achievements
Rank 1
Deva
Top achievements
Rank 1
Rob
Top achievements
Rank 1
Share this question
or