转 Chart

Charts are fun and apparently useful.  They give people the ability to relate information quickly and effectively.  They show trends and patterns through the use of polygons in different locations and of varying sizes.  Most will probably agree with me on what I have said so far except for the fun part.  If you have ever tried to make your own chart, it is definitely not fun.  If you succeed, it will look primitive at best and unless you spent a great deal of resources to architect it to be easily extensible, any changes you require down the road will only add more code and bloat your custom control.  That is why using our UltraChart control, included in both NetAdvantage for Windows Forms or NetAdvantage for ASP.NET, will make your job much simpler and will impress stubborn crowds with minimal effort.

Where to start...

This post is going to show you the steps required to get familiar with our chart and will show some of the extensibility built into our UltraChart control.  Now, before I continue, I want to mention that anything I talk about here will apply to both WinChart and WebChart.  Since both are built on the same core code base, your WinChart code will affect your WebChart in the same manner and vice versa.  Also, I will use UltraChart to refer to both WinChart and WebChart.  A warning, this post is fairly long.  Even though this post shows the evolution of an UltraChart as we continue to add to it, you may jump around as each part does not depend on another.  Finally, it would be useful to bring in the following namespaces in your using statements:

using Infragistics.UltraChart.Core.Primitives;

using Infragistics.UltraChart.Resources.Appearance;

using Infragistics.UltraChart.Core;

ChartType

I usually learn by doing.  So let's do by dragging on a chart control onto your design surface.  One of the first properties you should get aquainted with is the ChartType property.  This property will dictate the type of chart that is shown to the user to visualize your data.  There are many different values for the ChartType enumeration, Line, Bar, Column, Funnel, Candle, Bubble, Treemap, Radar, Heat Map, Pie, Histogram, and Gantt to name some.  In addition, there are 3D and 2D variations to some of these charts.  For learning purposes, I am going to pick the 2D Column Chart.  Complete list here for 2D and 3D.

chartstep0

Data.DataSource

So, we know how we want to visualize the data.  But what good is a chart if it has nothing to plot?  There are many ways to provide the UltraChart data.  You can use an array, class derived from CollectionBase, DataSet, DataView, DataTable, IBindingList, IList, XML file, or Series object.  We are going to use a DataTable in this sample, but you can click on any of the above types to go to a help article that walks you through  consuming the other types of data sources. 

Another step completed.  We know where we are going to get the data from and which ChartType will render that data.  But, we do not know what kind of arrangement of data or the datatypes the chart expects.  This brings us to..

Chart Data Requirements

Here are the requirements for 2D and 3D charts.  You will see that there are various requirements for each chart type.  Some are more demanding than others.  And it's a good thing the Column chart is not one of those demanding types as it only requires one numeric column.  So let's create a DataTable with one numeric column.  We should be good to go, right?  Yes, if you want a chart to render.  No, if you want to render in a specific way.  By saying no, I am not talking about little tweaks to make the chart to look perfect, but instead you not only need to know what kind of data is necessary but how the UltraChart will interpret that data.  In the "ChartTypes" section of the documentation, there are "Working with (insert ChartType here) Data" articles under each ChartType.  These articles will give you a sample DataTable and a rendered chart to show you how the data will be represented by that specific chart type.  Here's the article for the 2D Column Chart.  Based on that example, I created the DataTable shown below.

Code for my DataTable that I will be using:

DataTable dt = new DataTable();

dt.Columns.Add("Month", typeof(string));

dt.Columns.Add("Leads", typeof(int));

dt.Columns.Add("Sales", typeof(int));

dt.Rows.Add("January", 120, 50);

dt.Rows.Add("February", 90, 44);

dt.Rows.Add("March", 70, 22);

dt.Rows.Add("April", 66, 21);

dt.Rows.Add("May", 80, 42);

dt.Rows.Add("June", 85, 48);

ultraChart1.Data.DataSource = dt;

ultraChart1.Data.DataBind();

Here is what my Chart looks like:

image

Minor Customizations (201)

Now that you should be able to make a chart of any type, let's go into some minor customizations that each of those charts may require.

Custom Axis Range

By default, the axis will scale based on the lowest and highest values, 21 and 120 in this case.  If you wanted to set it to show from 0 to 200, you can do that by setting the RangeType to Custom, RangeMax to 200, and RangeMin to 0  on the Y axis.

ultraChart1.Axis.Y.RangeType = Infragistics.UltraChart.Shared.Styles.AxisRangeType.Custom;

ultraChart1.Axis.Y.RangeMax = 200;

ultraChart1.Axis.Y.RangeMin = 0;

Chart after modification:

image

ColorModel

There are many different ways to control the coloring scheme of chart elements.  To do so you want to modify the ColorModel.ModelStyle property to the setting you wish to use.  I am going to demonstrate the CustomLinear setting in this sample but you can see the other various ways to modify the appearance being used here.

ultraChart1.ColorModel.ModelStyle = Infragistics.UltraChart.Shared.Styles.ColorModels.CustomLinear;

ultraChart1.ColorModel.CustomPalette = new Color[]{Color.Orange, Color.Orchid, Color.PapayaWhip};

Chart after modification:

image

Legend

It really isn't too necessary in this sample.  But there are cases where a legend can make a chart much more readable.  To make use of a legend, simply set it to be visible and set its location like so:

ultraChart1.Legend.Visible = true;

ultraChart1.Legend.Location = Infragistics.UltraChart.Shared.Styles.LegendLocation.Bottom;

Chart after modification:

image

TitleTop

You may also want to give your chart a title and you can make use of our TitleTop, TitleBottom, TitleLeft, and TitleRight properties.  You will want to set the Visible property to true and the Text property for what you wish to display.

ultraChart1.TitleTop.Visible = true;

ultraChart1.TitleTop.Text = "Leads and Sales for Q1 and Q2 of 2008";

Chart after Modification:

image

Modifications that Require More than 3 Lines of Code (301)

There are also some modifications that are not as simple as flipping a property.  These require using some of the events of the UltraChart and some knowledge of elements that make up one of these charts.

Changing the Color of an Item Based on a Condition (2D only)

To change the color of an element, known as a Primitive in the UltraChart world, you want to handle the ChartDrawItem event.  In this event, you can check the properties and settings of the current primitive to see if you want to make any modifications.  Here are some common properties  and conditions you would look at:

  • e.HasData - if the Primitive being drawn is tied to any data
  • e.Primitive.Path - Path is a string that signifies where a element lies
    • Border.Title.Top is for the Primitive for TitleTop
    • Border.Title.Grid.Y is for something on the Y Axis
    • Border.Title.Legend is for something in the Legend
  • e.Primitive.Value - value associated with the given element, usually the data value for a bar or line
  • certain type of primitive - some types of primitives
    • if (e.Primitive is Polyline)

      {

          //do this

      }

private void ultraChart1_ChartDrawItem(object sender, Infragistics.UltraChart.Shared.Events.ChartDrawItemEventArgs e)

{

    //try casting the current primitive

    //being drawn to a Box

    Box b = e.Primitive as Box;

    //if current primitive is not a

    //box, return

    if (b == null)

    {

        return;

    }

    //if path is null

    if (b.Path == null)

    {

        //if the value is below 30

        if ((double)b.Value < 30)

        {

            //change the fill and fillstopcolor to red

            //setting both since gradients are being used

            b.PE.Fill = Color.Red;

            b.PE.FillStopColor = Color.Red;

        }

    }

}

Chart after Modification:

image

Adding Text to the Bars/Columns/Points (2D only)

Charts can be used for getting a general feel for the data or getting exact figures.  If the latter is required, you would make use of a ChartTextAppearance object and add it to to the ChartText collection for that ChartType.  For a column chart, it would be chart.ColumnChart.ChartText.  For a line chart, it would be chart.LineChart.ChartText.

ChartTextAppearance cta = new ChartTextAppearance();

cta.Visible = true;

//-2 signifies all rows or all columns

cta.Row = -2;

cta.Column = -2;

ultraChart1.ColumnChart.ChartText.Add(cta);

 

Chart after Modification:

image

Adding Various Primitives to the Chart (2D only)

Sometimes you need to add extra elements that are not provided in the data source or even if the data was available, the chart would not interpret that extra information in the manner necessary.  To clarify, imagine if you needed to add a target line to your sales chart.  If this value was in your table, your column chart would try to make a column out of it as there is no way to specify that value as a target line.  Since this line is not directly related to your data, you would have to draw this line in yourself.  To do that, you would handle the FillSceneGraph event, create primitives and add them to the SceneGraph.

Code to add a red target line to a column chart:

private void ultraChart1_FillSceneGraph(object sender, Infragistics.UltraChart.Shared.Events.FillSceneGraphEventArgs e)

{

    //gets the X and Y axis

    IAdvanceAxis x = (IAdvanceAxis)e.Grid["X"];

    IAdvanceAxis y = (IAdvanceAxis)e.Grid["Y"];

    //checks if axis exist

    if (x != null)

    {

        //figures out the coordinate to draw

        //a line at y=100

        int target = 100;

        int yVal = (int)y.Map(target);

        //note: the x axis is a string axis

        //that means that 0 stands for the first

        //column and 50 stands for the 50th

        //column               

        int xStart = (int)x.Map(0);

        int xEnd = (int)x.Map(50);

        //creates the line primitive based

        //on the coordinates

        Line l = new Line(new Point(xStart, yVal), new Point(xEnd, yVal));

        //sets the color of the line

        l.PE.Stroke = Color.Red;

        //adds it to the scene

        e.SceneGraph.Add(l);

    }

}

Chart after Modification:

image 

Customizations that are Considered Advanced (401)

There are certain changes that are not necessarily difficult but take a few steps to complete.  I will go into a couple of them here.

Custom Labels

There are many areas of text in a chart, whether it is axis tickmark labels, series labels, items labels, chart text, or tooltips.  These can be configured to show different text based on a FormatString property off that object.  There are some tokens that you can make use of such as <DATA_VALUE> or <ITEM_LABEL> (complete list here) but they do not encompass other more complex scenarios.  That's where the IRenderLabel interface comes in.  It allows you to customize any of the text on a chart that is configurable via the FormatString property.

To implement this feature, you have to have a class that implements IRenderLabel.  This interface has one member, ToString, which will be responsible for returning the string you want displayed given the context being passed in.  In this method, you will have access to things like the value of the element you are setting the text for, the row and column the element corresponds to in your table, and even things like the item and series labels that correspond to the given element.  Using this information, which is passed in as a hashtable, you can determine your output string and simply return that string.  This string will then show up in your chart.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Infragistics.UltraChart.Resources;

namespace WinChart101

{

    class CustomToolTips:IRenderLabel

    {

        #region IRenderLabel Members

        public string ToString(System.Collections.Hashtable context)

        {

            return (string)context["ITEM_LABEL"] +": "+ ((double)context["DATA_VALUE"]).ToString("#")+ " Thousand";

        }

        #endregion

    }

}

Once you have your class set up, you have to hook it up to your chart.  You can do that by doing the following:

//Create a hash table. This table will be used to associate a

//IRenderLabel object with a particular format string

Hashtable myHashTable = new Hashtable();

//Add a custom label string.

//The first param is the string

//The second param is the IRenderLabel object which will translate the string into the text the user will see on the screen.

//Note that this example is only creating one custom label. You can create as many different custom labels as you want.

//For each custom label, create a seperate IRenderLabel class and

//add an entry to the hash table linking the custom label string to the renderer.

myHashTable.Add("MyLabel", new CustomToolTips());

//Attach the Hash table to the Chart

this.ultraChart1.LabelHash = myHashTable;

//Assign the custom label to the ToolTip

this.ultraChart1.Tooltips.Format = Infragistics.UltraChart.Shared.Styles.TooltipStyle.Custom;

this.ultraChart1.Tooltips.FormatString = "<MyLabel>";

old Chart Tooltips:

image

NEW Chart Tooltips:

image

Note: This could have been done just by using the following:

this.ultraChart1.Tooltips.Format = Infragistics.UltraChart.Shared.Styles.TooltipStyle.Custom;

this.ultraChart1.Tooltips.FormatString = "<ITEM_LABEL>: <DATA_VALUE:#> Thousand";

The above was to show how you can set your chart to use a class that implements IRenderLabel.  Typically, you would use this for when the context is not readily available, ie. when data is in another table.

Composite Charts (2D only)

Composite charts are comprised of various 2D chart layers placed either next to or overlapping each other.  Essentially, you can take a candle chart layer, representing the high and low prices, and a column chart layer,representing the volume, and place them on a single chart control making use of the CompositeChart ChartType.  To create one of these charts you would have to create the following:

  • ChartArea - canvas where charts are placed
  • AxisItem - represents the X or Y axis, requirements based on the ChartType of the ChartLayerAppearance
  • ChartLayerAppearance - represents the ChartType layer, ie ColumnChart or ScatterChart
  • Series - provides data to each layer, types of Series that should be used with various ChartTypes

One thing to note, when working with a composite chart you have to provide data through the use of Series objects.  Series objects are essentially just a single set of data, that can be bound or not bound.  To help visualize what it would represent, think of each line being a series object in a LineChart and the orange columns being one series while the purple columns being another series in my column chart example above.  Also, these Series objects can be used with all chart types, not just composite.

Since the code for creating these is quite long, I am not including any code for them here.  You can take a look at the walkthroughs in our documentation where there are complete articles on creating these charts through the wizard, designer, and code.

Examples of Composite Charts (pictures only)

Composite Chart w/ Composite Legend:

comp1

Multiple Y-Axis w/ Line Layers:

comp2

Area and Line Chart in Top Area w/ Spline and Spline Area Chart on Bottom Area:

comp3 

Pop Quiz!

"Huh?" Don't "huh" me.  What would a university be without pop quizzes? (that wasn't the pop quiz)

  1. How do you specify different icons for the scatter chart?
  2. How can I set up my chart to have drill down (where you can click on a chart element to get a chart with further detailed information)?
  3. How can I set up the chart to allow zooming/scaling?
  4. How to I get a chart into a PDF document?
  5. How can I use the chart to plot just one or two values effectively? (think gauges, like a thermometer)

Answers (no looking before attempting the questions!)

So, how'd you do?  Don't feel too bad if you didn't know any of the them. I really didn't cover any of those topics.  I just was showing you that there are lots more to charts and this post does not cover everything that has to do with chart.  If you come up with any more questions that you can't find the answer to after reviewing the documentation, community site, and knowledge base, make use of the resources you have available, our support team and the forums.  For the questions above, here are the answers. 

  1. Each ChartType has a different set of properties that affect it.  In the "ChartTypes" section of the documentation, there are "(insert ChartType here) - Specific Properties" articles under each ChartType.  For the ScatterChart, there is a Icon property that controls which icon is used.
  2. You can implement the IDrillDown interface.  Help articles that explains this here.
  3. Different answers for Win or Web
    1. Win - can be set for x, y or both

      ultraChart1.Axis.X.ScrollScale.Visible = true;

      ultraChart1.Axis.X.ScrollScale.Scale = .5;

    2. Web - must set at design time so that the control will copy over the necessary scrollbar images

      UltraChart1.EnableScrollBar = true;

  4. There is a RenderPdfFriendlyGraphics method that you would call passing in a graphics object off the pdf. (Note: Requires a reference to the Infragistics.Documents assembly)
    1. Report r = new Report();

      ultraChart1.RenderPdfFriendlyGraphics(r.AddSection().AddCanvas().CreateGraphics());

  5. Kind of a trick question, you could just give it that one value and it would plot just fine.  However, you are probably better off using a gauge.  There are three different variations, radial, linear, or digital.  Like the UltraChart, you can also layer different types of gauges on top of each other (think your car speedometer that has an odometer also).

Graduation Day

If you read and understood every topic in this post, you have enough information to make most of the charts you will need in your application.  Congratulations, you are now a graduate of Chart University.  You will not be getting a paper diploma nor a diploma at all for that matter, just charts that will effectively convey information without causing too much stress.

Windows Forms sample uses the following:

-Infragistics NetAdvantage 2008 Volume 2 CLR 2.0

-Visual Studio 2008

Minimum requirements:

-Infragistics NetAdvantage (various version depending on feature being used)

Get Windows Forms Sample here.

ASP.NET sample uses the following:

-Infragistics NetAdvantage 2008 Volume 2 CLR 3.5

-Visual Studio 2008

Minimum requirements:

-Infragistics NetAdvantage (various version depending on feature being used)

Get ASP.NET Sample here.

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值