MindFusion Chart Control for WinForms, V4.0 Beta

MindFusion is proud to present you the beta version of Charting for WinForms, V4.0. MindFusion has entirely redesigned the control to create the most agile, lean and smart charting tool on the market. Below is a brief synopsis of the new chart for WinForms component.

New data model
Data that should be drawn in charts is read through an interface called Series, whose instances can be assigned to the Series properties of Chart and SeriesRenderer classes. You could implement this interface in your own model classes to avoid duplicating data. The library includes several pre-defined series classes that let you specify data via IList or array objects. For example, BarSeries lets you specify lists of values, inner labels and top labels, and PointSeries lets you specify data as a list of points.

Radar chart with multiple series.

Radar chart with multiple series.

New rendering model
Chart graphics are drawn inside Plot components by SeriesRenderer -derived objects. Each plot can contain multiple series renderers from same or different types. For example, you can draw area, line and bar graphics in same plot by adding AreaRenderer, LineRenderer and BarRenderer objects to its SeriesRenderers collection. Concrete Chart classes automatically generate a series renderer of appropriate type for their Series.

Dashboard
The Dashboard control can contain multiple plots, axes, legends, images, gauges and text blocks arranged in dynamic layout. Individual components can be added to dashboard’s default RootPanel or LayoutPanel containers, or for more complex layouts add intermediary panels such as GridPanel and StackPanel to the default ones.

The new WinForms Chart  has a built-in dashboard control.

The new WinForms Chart has a built-in dashboard control.

Print and export
The Dashboard control and Chart controls that derive from it expose Print and PrintPreview methods for printing on paper. Call the ExportImage and CreateImage methods to generate bitmap image of the dashboard. The ExportPdf method exports the chart to a PDF (Portable Document Format) file. The ExportSvg method exports the chart to an SVG (Scalable Vector Graphics) file.

Styling
Values of appearance properties can come from several places in the component hierarchy. SeriesRenderer -derived objects can use attributes from their local SeriesStyle, from plot’s SeriesStyle, or from the *Series properties in current Theme. Component classes use either their local properties or ones defined in the theme. By default, appearance properties in SeriesRenderer and Component classes have null values, which makes the drawing code use values from the theme.

You can download the beta version directly from the link below. The archive file contains the control’s libraries, samples in C# and documentation.

Download Chart for WinForms, V4.0 Beta Version

Your feedback is valuable for us. Please use the forum or e-mail support@mindfusion.eu. to share your opinion, ask questions or submit a problem.

About Chart for WinForms: This is a smart WinForms dashboard control that lets you add the perfect chart or gauge to your application in a few easy steps. The control provides an elegant data model, which supports equally well arrays, xml, any .NET data source, lists or any other data model class, that you create by implementing the Series interface.

MindFusion WinForms Chart boasts an innovative rendering model, where each chart graphics is drawn by its own SeriesRenderer on a Plot. Each Plot supports unlimited number of chart or gauge series of any type. Plots, together with axes, legends, gauges, images, and text blocks can be combined in a Dashboard with the built-in dashboard control. Styling the chart is done on various levels – from appearance properties in each SeriesRenderer to more general settings in the Component classes. The control supports themes and comes with a set of stylish themes, which you can customize as you wish or create new ones from scratch.

Persisting the chart is possible in several ways – printing, export to PDF or to Svg images – all of them performed with a single method call.

The newly designed chart control is offered with unchanged prices and license scheme – check it here.

Creating custom CompositeNode components

In this post we’ll examine how CompositeNode components work in MindFusion.Diagramming for Windows Forms, and in the process create a custom radio button component. You can find the completed sample project here: RadioComponent.zip

CompositeNode was created as alternative of the ControlNode class, which lets you present any Windows Forms control as a diagram node. ControlNode has many advantages, such as letting you design the hosted user controls using Visual Studio designer, reusing them in other parts of the user interface, and including complex framework or third-party controls as their children. From the fact that each user control creates a hierarchy of Win32 windows come some disadvantages too:

  • ControlNodes cannot mix with other diagram elements in the Z order but are always drawn on top
  • performance deteriorates if showing hundreds of nodes
  • mouse events might not reach the diagram if hosted controls capture mouse input
  • print and export might not be able to reproduce the appearance of hosted controls without additional work (handling PaintControl event)

On the other hand, CompositeNode does all its drawing in DiagramView control’s canvas and is not affected by the issues listed above. CompositeNode lets you build node’s UI by composing hierarchy of components derived from ComponentBase class. Pre-defined components include layout panels, read-only or editable text fields, images, borders, buttons, check-boxes and sliders. If the UI component you need isn’t provided out of the box, you could still implement it as a custom class that derives from ComponentBase or more specific type and overriding the GetDesiredSize, ArrangeComponents and Draw methods. Lets see how that works using a RadioButtonComponent as an example.

Derive RadioButtonComponent from CheckBoxComponent so we reuse its IsChecked and Content properties:

class RadioButtonComponent : CheckBoxComponent
{
}

CompositeNode relies on a dynamic layout system that lets components determine their size by overriding GetDesiredSize method, and arranging children in allocated size by means of ArrangeComponents method. For radio button we’ll call its base class to measure content size and add enough space for drawing the radio graphics element (a circle) horizontally, while fitting it in measured height:

float RadioSize(SizeF size)
{
	return Math.Min(size.Width, size.Height);
}

public override SizeF GetDesiredSize(SizeF availableSize, IGraphics graphics)
{
	var s = base.GetDesiredSize(availableSize, graphics);
	s.Width += RadioSize(s);
	return s;
}

ArrangeComponents calls the base class to arrange its content on the right side of available space:

public override void ArrangeComponents(RectangleF availableSpace, IGraphics graphics)
{
	var radioSize = RadioSize(availableSpace.Size);
	availableSpace.X += radioSize;
	availableSpace.Width -= radioSize;
	base.ArrangeComponents(availableSpace, graphics);
}

Now override Draw and render standard radio button graphics on the left side of the component, and content on the right side:

public override void Draw(IGraphics graphics, RenderOptions options)
{
	var radioSize = RadioSize(Bounds.Size);
	var r = radioSize / 2 - 1;
	var cr = r - 1;

	graphics.FillEllipse(Brushes.White, Bounds.X + 1, Bounds.Y + 1, 2 * r, 2 * r);
	using (var pen = new System.Drawing.Pen(Color.Black, 0.1f))
		graphics.DrawEllipse(pen, Bounds.X + 1, Bounds.Y + 1, 2 * r, 2 * r);
	if (IsChecked)
		graphics.FillEllipse(Brushes.Black, Bounds.X + 2, Bounds.Y + 2, 2 * cr, 2 * cr);

	GraphicsState s = graphics.Save();
	graphics.TranslateTransform(radioSize - 1 + Bounds.X, Bounds.Y);
	Content.Draw(graphics, options);
	graphics.Restore(s);
}

We’ll want only one radio from a group to be selected. For our purposes we can count all radio buttons placed inside same stack panel as part of same group. Override the OnClick method to unselect all buttons in parent panel and select the clicked one:

protected override void OnClicked(EventArgs e)
{
	var parentStack = Parent as StackPanel;
	if (parentStack != null)
	{
		foreach (var child in parentStack.Components)
		{
			var radio = child as RadioButtonComponent;
			if (radio != null)
				radio.IsChecked = false;
		}
	}
	this.IsChecked = true;
}

That’s it, the radio button component is ready with just a screenful of code 🙂 Let’s check how it works by creating an OptionNode class that shows a group of radio buttons and exposes a property to access or change selected one:

class OptionNode : CompositeNode
{
}

You could create the stack panel and radio buttons from code if you need more dynamic configuration, e.g. one with variable number of radio buttons. For this example we’ll just load a fixed template consisting of four buttons from XML:

const string Template = @"
	<simplepanel>

        <shape name="" shape""="" shape="" roundrect""="">

		<border padding="" 2""="">

			<stackpanel name="" radiogroup""="" orientation="" vertical""="" spacing="" 1""="" horizontalalignment="" center""="">
				<radiobuttoncomponent padding="" 2""="">
					<radiobuttoncomponent.content>
						<text text="" option="" 1""="" font="" verdana,="" 3world,="" style="Bold&quot;&quot;">
					</text></radiobuttoncomponent.content>
				</radiobuttoncomponent>
				<radiobuttoncomponent padding="" 2""="">
					<radiobuttoncomponent.content>
						<text text="" option="" 2""="" font="" verdana,="" 3world,="" style="Bold&quot;&quot;">
					</text></radiobuttoncomponent.content>
				</radiobuttoncomponent>
				<radiobuttoncomponent padding="" 2""="">
					<radiobuttoncomponent.content>
						<text text="" option="" 3""="" font="" verdana,="" 3world,="" style="Bold&quot;&quot;">
					</text></radiobuttoncomponent.content>
				</radiobuttoncomponent>
				<radiobuttoncomponent padding="" 2""="">
					<radiobuttoncomponent.content>
						<text text="" option="" 4""="" font="" verdana,="" 3world,="" style="Bold&quot;&quot;">
					</text></radiobuttoncomponent.content>
				</radiobuttoncomponent>
			</stackpanel>

		</border>

    </shape></simplepanel>";

The template can be loaded using the XmlLoader class. We’ll also store a reference to the stack panel so we can access its child radio buttons:

public OptionNode()
{
	Load();
}

public OptionNode(Diagram d)
	: base(d)
{
	Load();
}

private void Load()
{
	Components.Add(XmlLoader.Load(Template, this, null));

	radioGroup = FindComponent("RadioGroup") as StackPanel;
}

StackPanel radioGroup;

Now implement a SelectedOption property that lets us select a radio button by its index. Define it as nullable integer so we can represent missing select too:

public int? SelectedOption
{
	get
	{
		for (int i = 0; i < radioGroup.Components.Count; i++)
		{
			var radioButton = (RadioButtonComponent)radioGroup.Components[i];
			if (radioButton.IsChecked)
				return i;
		}
		return null;
	}
	set
	{
		for (int i = 0; i < radioGroup.Components.Count; i++)
		{
			var radioButton = (RadioButtonComponent)radioGroup.Components[i];
			radioButton.IsChecked = value == i;
		}
	}
}

Let’s try it – create a few nodes and run the application, you’ll see the screen shown below:

var node1 = new OptionNode();
node1.Bounds = new RectangleF(20, 20, 30, 40);
node1.SelectedOption = 0;
diagram.Nodes.Add(node1);

var node2 = new OptionNode();
node2.Bounds = new RectangleF(90, 20, 30, 40);
node2.SelectedOption = 1;
diagram.Nodes.Add(node2);

var node3 = new OptionNode();
node3.Bounds = new RectangleF(20, 80, 30, 40);
node3.SelectedOption = null;
diagram.Nodes.Add(node3);

var node4 = new OptionNode();
node4.Bounds = new RectangleF(90, 80, 30, 40);
node4.SelectedOption = 3;
diagram.Nodes.Add(node4);

for (int i = 0; i < diagram.Nodes.Count - 1; i++)
	diagram.Factory.CreateDiagramLink(
		diagram.Nodes[i], diagram.Nodes[i + 1]);

Radio buttons in MindFusion diagram nodes

To be fair, this kind of nodes is simple enough to implement using standard TableNode class where radio button graphics are either custom drawn or set as Image inside table cells in first column, and text displayed in second column. However the radio buttons can be mixed with other components in CompositeNodes to implement more complex user interfaces than ones possible with tables.

For more information on MindFusion flow diagramming libraries for various desktop, web and mobile platforms, see MindFusion.Diagramming Pack page.

Enjoy!

Nested DataRanges in MindFusion Report Application

In this tutorial we are going to build a report with nested data ranges. In our case, we are going to retrieve all categories from the sample Norhtwind database. For each category we will get all products in it, which is the nested data range.

I. Preparing the Project

We create a new WinForms project and add a new DataSet from the Nortwind database. We choose all fields from the Categories and Products tables. Then we add a new item from the menu “Project -> Add -> New Item -> MindFusion Report” from the dialog that appears.

Adding the MindFusion Report item.

Adding the MindFusion Report item.

Drag and drop the nwindDataSet, CategoriesTableAdapter and ProductsTableAdapter on the report form. Finally, in the code behind fill the two adapters:

 productsTableAdapter1.Fill(nwindDataSet1.Products);
 categoriesTableAdapter1.Fill(nwindDataSet1.Categories); 

II. The Categories DataRange

We create the first data range by right clicking on the newly created report. There we see “Create Data Range from Data Source”. We choose the categories table and two fields – CategoryName and Picture. When the data range is generated we resize the picture to make it bigger.

Create DataRange context menu.

Create DataRange context menu.

III. Running the Report

We would use MindFusion ReportViewer to preview what we’ve done so far. We drag it from the Toolbox and place it on the form, which shows when the application runs. We compile the project and see that the Report1 class that we’ve created appears in the Toolbox, under the Data tab. This means we can create instances of our report just by drag and drop. We drag the Report1 icon and drop it on Form1. We have a report11 instance, which we assign to the Report property of the ReportView in the property grid.

Dragging the Report1 item.

Dragging the Report1 item.

Finally, we run the report:

report11.Run();

IV. The Nested DataRange

It’s time to create the second DataRange. We right-click the Report1 form and choose again “Create DataRange from Data Source.” This time we choose the Products table and we choose ProductName, UnitsInStock and UnitPrice fields. This time we check the “Generate Header” checkbox at the bottom. The second DataRange is ready. Nesting it is very easy. We resize the first DataRange to make it wider and just drag and drop the second DataRange in it. What is important is to set the MasterDetailRelation property. It must be the name of the relation between the two tables that provide data for the two DataRange-s. We can see it by clicking on the nwindDataSet -> “Edit DataSet with Designer. There we click on the relation between or two tables and see it is called “CategoriesProducts”. We place this name as a value to the MasterDetailRelation property.

Master detail relationship between the Products and Categories table.

Master detail relationship between the Products and Categories table.

V. Run the report

We run the report and see that everything is in place: the categories are listed with their picture, each category lists all its products.

VI. Style Adjustments

Finally let’s add some appearance optimizations that will make the report look better and thus be easier to read. First, we make the background of the Category label darker.

Then we make the product lines with alternating colors. This is done in the property grid for the dataRange2 object -> AlternatingBackground property.

We add a light gray border to the first data range with the Border property editor and we add a bottom margin of 30 mm. Here is the final look of the report:

Nested DataRange-s: the final report.

Nested DataRange-s: the final report.

You can download the sample from this link:

Download Nested DataRanges MindFusion Reporting Sample

More about MindFusion Reporting for WinForms component can be found here.

WPF Diagram Control, V3.3.1 and WinForms Diagram Control, V6.3.3

MindFusion is pleased to announce the new releases of two of its popular flowchart control: Diagramming for WinForms, V6.3.3 and Diagramming for WPF, V3.3.1. Both releases have similar new features, which are listed below:

Resize table columns and rows
Columns and rows of a TableNode can now be resized interactively if its AllowResizeColumns or AllowResizeRows properties are enabled. In order to resize, move the mouse pointer to the border line on column’s right side or row’s bottom side until it shows resize cursor and start dragging. The control raises TableColumnResizing and TableRowResizing events to let you validate new size or prevent resizing some elements. The TableColumnResized and TableRowResized events are raised after the operation completes.

Barcode nodes
The BarcodeNode class displays EAN, UPC or QR barcodes as node’s content. In-place edit operations let users enter new numeric codes for 1D codes or text strings for QR codes. The barcode format is specified via the Format property, the encoded number or text is set via Content, and color of 1D bars / 2D modules via BarColor.

Barcode diagram nodes

Barcode diagram nodes

New Features in Diagramming for WPF, V3.3.1

ShapeDesigner improvements

  • The ShapeDesigner control supports undo. Call its Undo or Redo methods to respectively undo or redo a change done to the designed shape.
  • ZoomFactor property added to ShapeDesigner. It also supports interactive zoom in/out via mouse wheel.
  • The SelectedElement property exposes the graphic element currently selected in ShapeDesigner canvas. You can bind to its stroke and brush properties to create alternative user interface for editing element attributes.

Miscellaneous

  • NodeConstraints.KeepInsideDiagram prevents a node from leaving diagram boundaries during user interaction (the older RestrictItemsToBounds property does not stop nodes from leaving diagram area but returns them to original position if dropped outside).
  • dashed selection frames are now drawn in two colors and should be visible on both the default white background and custom darker backgrounds. You can change the second dash color via HandlesVisualStyle.DashBackground property.
  • set the WhileModifying flag in RoutingOptions.TriggerRerouting to reroute links while users drag their end points.
  • custom connection point classes can now override ConnectionPoint.NearestAnchorPoint to implement custom anchor point selection logic; the method is now also called at the beginning of interactive link creation.

New in Diagramming for WinForms, V6.3.3

Miscellaneous

  • the component now selects better end points for auto-routed links when using WhileCreating and WhileModifying routing modes;
  • custom connection point classes can now override ConnectionPoint.NearestAnchorPoint to implement custom anchor point selection logic; the method is now also called at the beginning of interactive link creation.
  • NodeConstraints.KeepInsideDiagram prevents a node from leaving diagram boundaries during user interaction (the older RestrictItemsToBounds property does not stop nodes from leaving diagram area but returns them to original position if dropped outside).
  • SvgNode supports SVG images with vector-effect=’non-scaling-stroke’ stroke attributes.
  • improved default Pen for dash-frame selection handles style. Dashed frames should now be visible on both the default white background and custom darker backgrounds.
  • ZoomControl can now be used with other components by MindFusion and has been moved to MindFusion.Common.WinForms assembly and namespace.

You are welcome to download the trial version for each control from the following links:

Diagramming for WinForms, V6.3.3 Trial Version Download

Diagramming for WPF, V3.3.1 Trial Version Download

If you have questions or run into problems using the components you can use the Diagramming components forum, the help desk or write us at support@mindfusion.eu. Our support team will be pleased to help you.

About MindFusion.Diagramming for WinForms: A programming component that provides any WinForms application with a full set of features for creating and customizing all types of diagrams, flowcharts, schemes, hierarchies, trees, graphs etc. The control provides numerous ways to save and load a diagram, six auxiliary controls and more than 10 automatic graph layout algorithms. Diagram elements include scrollable tables, container nodes, multi-segment arrows, custom diagram item types and many more. Further details here.

Diagramming for WinForms is a royalty-free component, clients get 12 month upgrade subscription when buying a license. The source code is also available for purchase. Visit the buy page for a list with the current license prices.

About MindFusion.Diagramming for Wpf: Designed and developed to be easy to integrate, use, and customize, this native WPF flowchart component places at your disposal every single feature you would ever need to create diagrams, graphs, schemes, org charts, DB relationships, genealogy trees, class hierarchies and many more. Its long list of style options gives you complete control over the appearance of the diagram. With a set of eight automatic layouts you are sure to find the arrangement that suits perfectly your WPF application.

The diagram control boasts a long list of events, properties and methods for user interaction, item creation, data input and output. You can read the full features list here. The online demo shows samples that demonstrate various capabilities of the control. The licensing scheme and prices are uploaded at the buy page. Source code is also available.

Layout Management with the WinForms Dock Control

In this post we will show you how to build a sample application with customizable layout based on the WinForms Dock control, which is part of MindFusion WinForms pack. You can find further details about the control at its web page.

For the purpose of the demonstration we’ve chosen an entertaining topic – a cooking recipes electronic book. Our book so far has only three recipes, all for sweets. Lets start by looking at the

I. Architecture of the sample.

The sample has two custom classes – Ingredient and Recipe. Each Ingredient has quantity, name and an image, which illustrates it. The Recipe class holds a strongly typed list with Ingredient objects, the title for each recipe, an image for the recipe, an icon for the recipe and preparation instructions.

The application consists of the dock control, which contains four DockItem-s : for the recipes, for their images, for their ingredients and with the preparation instructions. Any dock item can be dragged, dropped, aligned, minimized, hidden etc.

The API of the cook book application

The API of the cook book application

II. The Dock Control.

We create an empty WinForms project and add the Dock control from the toolbox. The dock control fills the entire client area:

this.dockControl1.Dock = System.Windows.Forms.DockStyle.Fill;         
this.dockControl1.Location = new System.Drawing.Point(0, 0);           
this.dockControl1.Size = new System.Drawing.Size(784, 562);

These properties are set in the Property grid.

Each dock item is created with a title and id, which helps us identify it.

titleItem = new DockItem() { Header = "Recipe Name", Id = "Name" };
titleItem.DockStyle = DockStyle.Left;      
titleItem.Content = GetContent("Name");

The DockStyle property is responsible for the initial layout of the dock item. You can choose among various dock styles – fill, bottom, top and more.

The GetContent method is very important. It prepares the controls that will be placed into each dock item and returns the appropriate one according to the parameter.

Once the dock item is created, let’s not forget to add it:

dockControl1.Items.Add(titleItem);

III. Creating the Content.

Let’s see how the content for a dock item is created. Let’s take the grid with the ingredients. It is identified with the “Ingredients” id:

private Control GetContent(string contentType)
{
  Control control = null;
  ....
  else if (contentType == "Ingredients")
         {                
             grid = new DataGridView();
             grid.DefaultCellStyle.BackColor = Color.FromArgb(247, 226, 189);
             grid.Dock = DockStyle.Fill;
             grid.MultiSelect = false;
             grid.DataSource = selectedRecipe.Ingredients;
             grid.RowTemplate.MinimumHeight = 35;
            
             grid.RowHeadersWidthSizeMode =
            DataGridViewRowHeadersWidthSizeMode.DisableResizing;
             grid.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
             grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
             grid.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
             grid.BackgroundColor = Color.FromArgb(253, 244, 247);

             control = grid; 
         }
...
return control;

The idea is clear: you create the control, which will be rendered in the dock item and assign it to DockItem.Content. Here we make different customization for the grid – we change the color of table rows, adjust the height, turn off multiple row select and more.

IV. Changing the Content.

We change the content by handling the SelectedIndexChanged event for the ListView, which lists our recipes. When the user selects a new list item, we extract its Recipe and change the content of the other DockItem-s:

selectedRecipe = recipes[recipesListView.SelectedIndices[0]];
tb.Text = selectedRecipe.Preparation;
grid.DataSource = selectedRecipe.Ingredients;
pictureBox.Image = Image.FromFile(selectedRecipe.ImageUrl);

Here is the final output of the sample application:

MindFusion WinForms Dock COntrol

A Sample electronic cook book based on MindFusion WinForms Dock Control

You can download the sample directly from this link:

MindFusion WinForms Layout Control Sample: Electronic Cook Book in C#

MindFusion WinForms Layout Control Sample: Electronic Cook Book in VB.NET

Enjoy the fast, easy and straight-forwarded manner in which you can create a WinForms application with a flexible layout and multiple panels.