Charting for WPF, V2.0

The list below describes recent changes and additions to MindFusion.Charting for WPF:

Support for Multiple Axes

The chart can now render multiple axes at each side of the plot area. To enable that, add a new Axis instance to the XAxes collection properties for bottom axes, to YAxes collection for left-hand axes, and X2Axes / Y2Axes for respectively top and right sides. The old AxisSettings class and XAxisSettings / YAxisSettings objects have been removed, and now their properties are set independently for each Axis instance in the collections.

Multiple axes in the WPF chart control.

Multiple axes in the WPF chart control.

Improved Zooming

Selected area with width smaller than MinZoomSpan does not evoke any action in the control. In addition, the new ZoomChanged event fires whenever zoom occurs and provides useful data for the zoom action with its ZoomChangedArgs.

Cross Hair Improvements

The cross hair control has been improved with several new properties, a method and an event. The properties are:

The new CrossHairPosition method returns the current location of the cross hair. For more precise handling of cross hair movements a new event is available – CrossHairPositionChanged.

Cross hair is drawn in a WPF column chart.

Cross hair is drawn in a WPF column chart.

Greatly Improved 3D Charts

3D charts have received plenty of improvements, new properties and performance optimizations: PointMergeThreshold – The property sets the radius of an area around a given point where no other points are drawn. The result is better performance especially in charts with numerous points, which happen to be close to one another. Of points with similar coordinates only a single one is rendered, the rest are omitted.

InterpolationType.None – A new InterpolationType has been added to the InterpolationType enum, which does not interpolate but adds data directly and connects the points with triangulation.

The SurfaceType enum has been replaced with three bool properties, which makes the API easier to understand and use.

ScatterFaceSize – the property regulates the size of the polygons that build a 3D scatter. Bigger values lead to bigger polygons, which results in faster performance and rougher scatter mesh. Effect3D.ShaderEffect – the property can be applied to all 3D chart elements, including scatters and performs much faster.

3D surface chart with color map and wire frame.

3D surface chart with color map and wire frame.

Exporting Images

Two new methods have been added for exporting the chart as an image – CreateImage and ExportImage.

Custom Formatting of Labels in Real-time Charts

A new property has been added to the RealTimeChart library – Axis.LabelFormatProvider. Use it to specify custom formatting of numeric labels. If required, you can specify format arguments for your format classes with Axis.LabelFormat.

Direct download of the trial version is available from here:

Download MindFusion.Charting for WPF 2.0 Trial Version

You are welcome to contact us with any questions, problems or inquiries about the Charting for Wpf control or any other of our products. MindFusion has always put special emphasis on providing excellent customer support and we usually answer your inquiries in a few hours of receiving them.

About MindFusion.Charting for Wpf: A programming component that combines powerful charting capabilities with an elegant API and easy use. Among the features of the control are fully customizable grid, positive and negative values on all chart axes, 3D charts, gauges and many more – read a detailed list here.

The control provides detailed documentation and various samples that demonstrate how to customize every type of chart. It supports a wide range of 2D and 3D charts including bar, line, radar, bubble pie etc. You can add tooltips, define themes, perform hit testing, zoom and more.

ContainerNode fold / unfold animations

In this post we’ll show how to animate container’s fold and unfold operations using some event handling and custom drawing. You can download the complete project here:

AnimatedFold.zip

The sample code will demonstrate several features of the Diagram control and .NET:

  • use LINQ to collect contained items
  • handle fold/unfold events
  • custom draw from DrawForeground event
  • draw items from custom drawing code

Let’s start by creating some items and containers when the form loads:

private void Form1_Load(object sender, EventArgs e)
{
    var ctr = diagram.Factory.CreateContainerNode(20, 20, 100, 100, true);
    var node1 = diagram.Factory.CreateShapeNode(30, 35, 15, 15);
    var node2 = diagram.Factory.CreateShapeNode(80, 45, 15, 15);
    diagram.Factory.CreateDiagramLink(node1, node2);

    ctr.Add(node1);
    ctr.Add(node2);

    var ctr2 = diagram.Factory.CreateContainerNode(20, 20, 100, 100, true);
    ctr2.Add(ctr);
}

We’ll use LINQ extensions methods to find all items within a ContainerNode, including ones contained recursively in child containers:

List<DiagramItem> GetDescendents(ContainerNode container)
{
    var nodes = diagram.Nodes.Where(
        container.ContainsRecursively);

    var links = diagram.Links.Where(l =>
        nodes.Contains(l.Origin) ||
        nodes.Contains(l.Destination));

    return
        nodes.Cast<DiagramItem>().Concat(
        links.Cast<DiagramItem>()).ToList();
}

Add handlers for ContainerFolded and ContainerUnfolded events that will start animation for the container:

void OnContainerFolded(object sender, NodeEventArgs e)
{
    var container = (ContainerNode)e.Node;
    StartAnimation(container, true);
}

void OnContainerUnfolded(object sender, NodeEventArgs e)
{
    var container = (ContainerNode)e.Node;
    StartAnimation(container, false);
}

The StartAnimation method stores a list of items that should be redrawn during animation and a few other animation attributes:

void StartAnimation(ContainerNode container, bool fold)
{
    var bounds = container.Bounds;
    var scaleCenter = new PointF(
        (bounds.Left + bounds.Right) / 2, bounds.Top);

    // collect items that will be unfolded
    animatedItems = GetDescendents(container);

    // animation will also draw this rectangle as background
    ctrBounds = bounds;
    ctrBounds.Size = container.UnfoldedSize;
    ctrBounds.Y += container.CaptionHeight;
    ctrBounds.Height -= container.CaptionHeight;

    // start animation timers
    Animate(scaleCenter, fold);

    if (!fold)
    {
        // temporarily fold back when animating unfold operation
        // so that contained items stay invisible
        container.Folded = true;
        toUnfold = container;
    }
}

The Animate method starts a timer whose Tick event invalidates the DiagramView and stops the timer when final frame has been reached:

void Animate(PointF scaleCenter, bool scaleDown)
{
    if (scaleDown)
    {
        frameCounter = maxFrames;
        frameIncrement = -1;
    }
    else
    {
        frameCounter = 0;
        frameIncrement = +1;
    }
    this.scaleCenter = scaleCenter;

    animationTimer = new Timer();
    animationTimer.Tick += OnAnimationTimer;
    animationTimer.Interval = duration / maxFrames;
    animationTimer.Start();
}

void OnAnimationTimer(object sender, EventArgs e)
{
    frameCounter += frameIncrement;
    diagramView.Invalidate();
    if (frameCounter == 0 || frameCounter == maxFrames)
    {
        animationTimer.Stop();
        animationTimer.Dispose();
        animationTimer = null;
        animatedItems = null;

        if (toUnfold != null)
        {
            toUnfold.Folded = false;
            toUnfold = null;
        }
    }
}

Add a DrawForeground event handler that applies scale transform proportional to current frame of animation and draws the container’s descendants stored in animatedItems list:

void OnDrawForeground(object sender, DiagramEventArgs e)
{
    if (animatedItems != null && frameCounter > 0)
    {
        var options = new RenderOptions();
        var g = e.Graphics;

        // apply scale corresponding to current frame
        var scale = (float)frameCounter / maxFrames;
        g.TranslateTransform(scaleCenter.X, scaleCenter.Y);
        g.ScaleTransform(scale, scale);
        g.TranslateTransform(-scaleCenter.X, -scaleCenter.Y);

        // draw container background
        g.FillRectangle(Brushes.White, ctrBounds);
        g.DrawRectangle(Pens.Black, ctrBounds);

        // draw contained items
        foreach (var item in animatedItems)
            item.Draw(e.Graphics, options);
    }
}

Same technique can be applied to animate collapse and expand operations on tree branches. To implement that, handle NodeExpanded and NodeCollapsed events instead, and collect items reachable recursively from the branch’ root by following outgoing links.

The code above uses MindFusion’s .NET API and can be used with Windows Forms, WPF, Silverlight and ASP.NET diagramming components. The Java API for Android and desktop Swing application will look similar, with setter method calls instead of property assignments.

You can download the trial version of any MindFusion.Diagramming component from this page.

Enjoy!

Line Chart With Multiple Axes in WPF

A common scenario when building charts is the ability to render multiple series bound to multiple axes, each one with its own scale. To deal with this issue, MindFusion.Charting for WPF control has added support for multiple axes of all types – X, Y, Y2, X2 and in this post we’ll look how to add and customize them and how to create series bound to a given axis.

The sample imitates a production chart, where three different scales measure three different values – work output, capital and energy consumption – all of which presumably participate in producing a single unit of a product. On the right side we have a single Y2 axis, which measures the amount of units produced. The X-axis displays the time scale. Let’s look at the chart elements, one by one.

I. The Y-Axes

The Y-axes, as all axes in the chart are an instance of the Axis class and are added to the appropriate collection property. The Axis class defines all types of useful properties needed to customize an axis. We define the three axes in XAML:

<chart:LineChart.YAxes>
    <chart:AxesCollection>
        <chart:Axis MinValue="0" Interval="5" MaxValue="60" LabelFormat="F0" Tick="3" Title="kWh/day" TitleRotationAngle="270" LabelStroke="Red" TitleStroke="Red"></chart:Axis>
        <chart:Axis MinValue="0" Interval="300" MaxValue="2100" Title="Capital (USD)" Tick="3" TitleRotationAngle="270" LabelStroke="Purple" TitleStroke="Purple"></chart:Axis>
        <chart:Axis MinValue="100" Interval="2.5" MaxValue="130" Title="Work Productivity (%)" CustomLabelPosition="AutoScalePoints" AxisCrossingPoint="100.0" LabelType="CustomText" Tick="3" TitleRotationAngle="270" LabelStroke="Green" TitleStroke="Green"></chart:Axis>
    </chart:AxesCollection>
</chart:LineChart.YAxes>

The property names easily describe what is set: the minimum and maximum values on each of the three axes, the title, the stroke for the labels and the title, the interval and the length of the axis ticks. Let’s note that the type of labels for the last Y-axis is “CustomText” – this means we will specify the labels explicitly rather than allow the control to generate them as with the other two axes – they don’t set a label type and the default value (the auto scale) is rendered.

Here is how we define the labels:

double start = 100.0;

    //130 is the last number at the axis
    while (start <= 130)
    {
        string l = start.ToString("F1") + "%";
        chart.YAxes[2].Labels.Add(l);
        start += 2.5;
    }

II. The Y2 Axis

The Y2-axis is just one and it is entirely declared in XAML:

<chart:LineChart.Y2Axes>
    <chart:AxesCollection>
        <chart:Axis MinValue="0" Interval="1000" MaxValue="12000" Tick="3" LabelFormat="F0" TitleRotationAngle="270" Title="Units"></chart:Axis>
     </chart:AxesCollection>
</chart:LineChart.Y2Axes>

The label format is set with the standard .NET numeric strings – in this case it is a floating number without trailing zeros. In this axis, as well in the other Y-axes you might have noticed that we use the TitleRotationAngle property. This property rotates the title label at an arbitrary angle between 0 and 360. In our case we want the label drawn vertically, to conserve space.

III. The Series

The series are created in code. They specify scatter type because we want each series to have markers at data points. The YAxis property specifies the Y-axis, which a given Series is bound to. Finally, we specify the tool tip type because we want to have a tool tip when the mouse hovers a data point.

 LineSeries series0 = new LineSeries();
 series0.YAxis = chart.YAxes[0];
 series0.ScatterType = ScatterType.Square;
 series0.ScatterFills = new BrushCollection() { Brushes.Pink };
 series0.ScatterStrokes = new BrushCollection() { Brushes.Red };
 series0.Strokes = new BrushCollection() { Brushes.Red };
 series0.ToolTipType = ToolTipType.ChartData;

The data is random generated numbers. We use the Axis.XData and Axis.YData properties to set it.

 for (int i = 0; i < 30; i++)
     {
        series0.XData.Add(i * 6);
        data1.Add(rand.NextDouble() * 60.0);     
      }

      data1.Sort();
      series0.YData = new DoubleCollection(data1);
      //don't forget to add the series
      chart.Series.Add(series0);

Last but not least – don’t forget to add the series to the Series collection property of the chart. With that our chart is ready – here is the result:

Charting for WPF: Multiple Axes and Series

Charting for WPF: Multiple Axes and Series

You can download the sample with the chart libraries from here:

WPF Chart With Multiple Axes Sample Download

If you have any questions regarding the chart component use the forum, email or the help desk to contact MindFusion. More information about Charting for WPF, which includes a premium 3D charting library and a Real time charting library optimized to handle huge data sets can be found here.

Diagramming for ASP.NET, V5.5

Here is the list of the recent changes and additions to MindFusion WebForms Diagram control:

Resize table columns and rows

Note: This feature is not available in ImageMap mode.

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.

Diagramming for ASP.NET: Table Nodes

Diagramming for ASP.NET: Table Nodes

Canvas mode improvements

  • Shape library files and ShapeLibraryLocation properties of DiagramView and ShapeListBox can now be used in Canvas mode.
  • Items can now be deleted using Backspace key when running on Mac.
  • Caption divider line in TableNode and ContainerNode is now rendered clipped when caption height is smaller than corner radius.
  • The TooltipDelay property specifies the delay in milliseconds before showing tooltips.
  • The Orientation property of NodeListView lets you set the view’s orientation to Horizontal or Vertical (members of Orientation enum).
  • Fixed overlaps in client-side TreeLayout when arranging nodes of different sizes.
  • Fixed a bug where deserialization of custom item classes worked correctly only if their names contained Node or Link suffix.
  • MsAjaxLocation and JQueryLocation properties let you change the location of external script libraries.
Diagramming for ASP.NET: Node Shapes

Diagramming for ASP.NET: Node Shapes

ImageMap mode improvements

  • Image generator implementation changed from Page to IHttpHandler , this makes it more lightweight avoiding the full page life-cycle.
  • Image generation is now implemented by the built-in ImageHandler class inside MindFusion.Common.WebForms assembly and it no longer requires adding external .aspx file to the project. Instead, it can be listed in web.config file:
    XML
    
    <handlers>
        <add name="ImageHandler" path="ImageGen.ashx" verb="GET"
            type="MindFusion.Common.WebForms.ImageHandler, MindFusion.Common.WebForms"/>
    </handlers>
    
    
  • For convenience, there is still optional ImageGen.ashx provided as external file for easier set-up of the project (add existing file instead of changing web.config).
  • ZoomControl no longer draws using <canvas> element when running in ImageMap mode, but uses ImageHandler to generate bitmaps.

API changes

ZoomControl can now be used with other MindFusion components and has been moved to MindFusion.Common.WebForms namespace and assembly.

Here is a direct link to download the trial version:

Download MindFusion.Diagramming for ASP.NET, V5.5 Trial Version

Technical support
MindFusion support team is happy to assist you with any questions you might have about Diagramming for ASP.NET or any other of our products. You can leave a message at the discussion board, use the help desk or e-mail support@mindfusion.eu.. We strive to provide competent and detailed answers to your questions within hours of receiving them.

About Diagramming for ASP.NET: An advanced WebForms programming component that offers all the functionality that is needed for creating, styling and presenting attractive flowcharts, hierarchies, trees, graphs, schemes, diagrams and many more. The control offers numerous utility methods, path finding and cycle detection, rich event set and many useful user interaction features like tool tips, multiple selection, copy/paste to/from Windows clipboard and many more.

NetDiagram offers more than 100 predefined node shapes, scrollable tables, 13 automatic layouts and many more. You can check the online demo to see some of the features in action. The control includes many samples, detailed documentation and step-by-step tutorials. Every features is duly documented and there’s plenty of code to copy. The component is not only powerful and scalable, but easy to learn and fun to use.

A Monthly Calendar in Java With Events and Recurring Appointments

This is a step-by-step guide that teaches you how to:

  • Setup the MindFusion Scheduler for Java library to display a single
    month calendar.
  • Attach and handle an event when the user clicks a calendar cell.
  • Create and setup recurrent events/appointments.
  • Perform custom drawing on a specific cell.

The sample builds a monthly calendar, which responds to a user click on a calendar cell by creating a recurrent appointment. The appointment is repeated on each subsequent day of the week for unlimited number of months.

When the user selects a given calendar cell (the 6th day of the month), a special icon appears. The icon is rendered using custom drawing.

Note: In this tutorial we use the words “appointment” and “event” interchangeably. Let’s start:

1. How to Setup the Calendar

All packages of the calendar are included in a single *.jar file – JPlanner.jar In our sample we will reference the following packages:

import com.mindfusion.common.*;
import com.mindfusion.common.Rectangle;
import com.mindfusion.drawing.*;
import com.mindfusion.drawing.awt.AwtImage;
import com.mindfusion.scheduling.*;
import com.mindfusion.scheduling.awt.*;
import com.mindfusion.scheduling.model.*;

For detailed reference about the packages and the classes of the schedule library check the online help.

Here are the first settings for our schedule:

  calendar = new AwtCalendar();
  calendar.beginInit();
  //set the current time
  calendar.setCurrentTime(DateTime.now());
  DateTime today = DateTime.today();
  //set the current date
  calendar.setDate(today);
  // Select the current date
  calendar.getSelection().set(DateTime.today());

We create a new calendar and signal that initialization starts. The time and date shown at the application start are the current date and time. We also select the cell with the current date.

Let’s make the calendar show exactly one month:

calendar.setCurrentView(CalendarView.SingleMonth);

By default each cell in a single month view has its header size set to 0, which makes the current date show in the center of the cell. As a consequence any events in the cell won’t have space to be rendered.

Java Scheduler: the header takes all the cell's height

Java Scheduler: the header takes all the cell’s height

Since we plan to create appointments on user click, we must push the header to the top and free cell space for drawing the events. This is very easy to do, just set:

calendar.getMonthSettings().getDaySettings().setHeaderSize(20);

Now the header is 20 px. and the rest will be for our appointments.

Java Scheduler: the header is 20px.

Java Scheduler: the header is 20px.

For now we are ready initializing the calendar.

calendar.endInit();

2. Handling User Clicks.

User clicks are handled with the dateClick event. We need an instance of the CalendarAdapter and there we associate the dateClick event with a method – onDateClicked. The event is fired when a date is selected.

 calendar.addCalendarListener(new CalendarAdapter(){
            public void dateClick(ResourceDateEvent e) {
                onDateClicked(e);
            }

        });

3. Create an Appointment and a Recurrence.

The first part of our event handler method is:

protected void onDateClicked(ResourceDateEvent e) {

    int dayIndex = e.getDate().getDayOfWeek();

    Appointment item = new Appointment();
    item.setStartTime(e.getDate());
    item.setEndTime(e.getDate());
    item.setHeaderText(events[dayIndex]);
    item.getStyle().setBrush(brushes[dayIndex]);

Here we create an Appointment and set its start and end date to the date which was clicked. The ResourceDateEvent keeps data about the date, the resource, if any and other useful information. The header text is the text, which will be rendered at the appointment. The style object contains appearance data for the cell and we use the setBrush
method to change the background of the appointment.

The second part of the method creates the Recurrence object:

      recurrence = new Recurrence();
      recurrence.setPattern(RecurrencePattern.Weekly);
      recurrence.setDaysOfWeek(getDayOfWeek(dayIndex));
      recurrence.setStartDate(e.getDate());
      recurrence.setRecurrenceEnd(RecurrenceEnd.Never);
      item.setRecurrence(recurrence);

The recurrence is once a week. There’s additional work to be done when we set the day of the week with setDaysOfWeek. The method accepts as an argument one of the DaysOfWeek enumeration values and we have to convert the index of the day to such value.

private int getDayOfWeek ( int i ) {

        switch (i) {
            case 1:
                return DaysOfWeek.Monday;
            case 2:
                return DaysOfWeek.Tuesday;
            case 3:
                return DaysOfWeek.Wednesday;
            case 4:
                return DaysOfWeek.Thursday;
            case 5:
                return DaysOfWeek.Friday;
            case 6:
                return DaysOfWeek.Saturday;
        }

        return DaysOfWeek.Sunday;

    }

Finally, let’s add the item with the recurrence pattern to the schedule items collection:

 calendar.getSchedule().getItems().add(item);

4. Custom Drawing a Cell’s Header

The last thing that needs to be done is to draw the icon on the special 6th day of each month. We will perform item drawing and we add to the calendar initialization code this line:

 calendar.setCustomDraw(CustomDrawElements.CalendarItem);

Now we are ready to handle the draw event:

   //add a listener for custom draw
       calendar.addCalendarListener(new CalendarAdapter()
        {
            @Override()
            public void draw(DrawEvent e) {
                onDraw(e);
            }
        });

Below is the first part of the handler method:

 private void onDraw(DrawEvent e)
    {
 if(e.getDate().getDay() == 6 )
            {
                java.awt.Image img = null;

                try {
                    // Read the image file from an input stream
                    InputStream is = new BufferedInputStream(
                            new FileInputStream("../cake.png"));
                    img = ImageIO.read(is);

                } catch (IOException ioe) {
                }

Here we read an image from an InputStream. The calendar method for drawing images requires mindfusion.scheduling.AwtImage and we must convert the java image:

AwtImage awtImage = new AwtImage(img);

Then we get the bounds of the drawing area and render the image:

   //gets the bounds of the drawing area
    Rectangle r = e.getBounds();
             
   //draw the image
   e.getGraphics().drawImage(awtImage, e.getBounds().getLeft(), e.getBounds().getTop(), 32, 32);

 }

The image is 32 x 32 pixels and gets clipped in the appointment.

Java Scheduler: the appointment's height is not enough.

Java Scheduler: the appointment’s height is not enough.

We’ll have to resize the item header to give it more space:

calendar.getItemSettings().setSize(32);

And now everything works just fine:

MindFusion Java Calendar: Month View with Events

MindFusion Java Calendar: Month View with Events

The sample is available for download from here:

Monthly Calendar in Java with Recurrent Appointments and Events

About Scheduling for Java Swing: A programming class library written entirely in Java that lets you build the most sophisticated schedules, calendars and task managers fast and easy. The component boasts a comprehensive feature set that includes custom-typed events, undo/redo functionality, scrolling, tool tips and much more. You can choose among six view styles, which are easy to change and customize. The appearance of each schedule is completely customizable and supports themes, user-assigned mouse cursors and a variety of font, pen and brush options.

A detailed list with the features of the tool is available at the Scheduling for Java Swing features page. The trial version includes a variety of samples and you have plenty of sample code to study. Online documentation with useful tutorials is also available.

The library is royalty-free, source-code is also available. You can see a list of the current prices here. Check the discount page for a list of the available discounts.

Diagramming for JavaScript, V2.5

The new release of MindFusion Diagramming library for JavaScript contains some useful new features and improvements. Below are the details:

Resize of 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.

JavaScript Table Nodes: Resize

JavaScript Table Nodes: Resize

Shape libraries

The ShapeLibrary class lets you use custom geometric shapes created using MindFusion ShapeDesigner tool. Call its loadFromXml method to load a library XML file. getShapes returns an array of the loaded Shape objects. The ShapeLibraryLocation property of NodeListView creates a prototype ShapeNode object for each shape from the specified library.

Miscellaneous

  • TextStroke and TextStrokeThickness properties of DiagramItem let you set color and thickness of text outlines.
  • Items can now be deleted using Backspace key when running on Mac.
  • Caption divider line in TableNode and ContainerNode is now rendered clipped when caption height is smaller than corner radius.
  • The TooltipDelay property specifies the delay in milliseconds before showing tooltips.
  • The Orientation property of NodeListView lets you set the view’s orientation to Horizontal or Vertical .
  • MindFusion.Common.js contains code shared with other JavaScript libraries by MindFusion. It must be loaded before the MindFusion.Diagramming.js script.

Fixed bugs

  • Fixed overlaps in TreeLayout when arranging nodes of different sizes.
  • Anchor points indices were not serialized and could be reset to different values when loading from JSON.
  • Deserialization of custom item classes worked correctly only if their names contained Node or Link suffix.

Registered customers with an active upgrade subscription can download the licensed version from the clients area on our site.

A trial version is available for direct download from the following link:

Download MindFusion Diagramming Library for JavaScript, V2.5

We are glad to receive any comments, suggestions and feedback. You can write us at e-mail support@mindfusion.eu or use the help desk. You can use the JsDiagram section on MindFusion forum to post questions about the tool.

About Diagramming for JavaScript Library: Written 100% in JavaScript, this tool uses HTML5 Canvas to draw impressive diagrams, schemes, flowcharts, trees and many more. It is browser independent, easy to use and integrate into any web application. JsDiagram supports a variety of predefined node shapes, customizable links, rich event set and many appearance options.

The user interaction model includes resizing / moving / selecting and modifying any diagram element. The tool boasts an elegant API, which is documented in details as well numerous step-by-step guides and tutorials. Various samples are provided to let you learn quickly how to use the most important features of the library – check them here. JsDiagram is not only the perfect choice for creating any type of diagram in the browser – it can also arrange it the way you wish with a mouse click using one of its automatic graph layout algorithms. For more details about the features of the component, please visit the Diagram for JavaScript page.

Diagramming for WinForms, V6.3.4 Released

MindFusion popular diagram control for WinForms has a new version. Here is a list of the new features:

Street maps

MapNodes can render street maps in OpenStreetMap format. Call FromXml method of MapContent to load an .osm file. The pens and brushes used for drawing the map are stored within the StreetMapPens and StreetMapBrushes collections in the static StreetMapFeatures class. You can define additional pens and brushes for drawing and painting certain map features by using MapContent’s AddPen and AddBrush methods.

Diagramming for WinForms: Map Nodes

Diagramming for WinForms: Map Nodes

Miscellaneous

  • Support for .NET 2 has been dropped; the minimum supported .NET framework version now is 3.5.
  • Distribution now includes a set of digitally-signed assemblies.
  • Undo/redo records for in-place edit operations are now created automatically. They are represented by instances of the EditTextCmd class.
  • CompositeNode supports vertical scrolling in EditComponent (only via keyboard).
  • Support for FromPage and ToPage properties of PrinterSettings.
  • CreateBarcodeNode methods added to the Factory class.
  • The BarcodeNodeStyle property of Diagram defines the default appearance of BarcodeNodes.
  • Improved speed when dragging large hierarchies of grouped nodes.
  • Fix for not restoring ColumnStyle value when cancelling or undoing TableNode column resize operations.

The trial version is available for direct download from the link below:

Diagramming for WinForms, V6.3.4 Trial Version Download

Your comments and feedback about the new version is welcomed. You can use the Diagramming for WinForms 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 12 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.

Diagramming for ActiveX, V4.9.2 Beta

We are running beta tests on the new version of MindFusion ActiveX Flowchart Control. Below is a list of the new features and add-ons:

Resize table columns and rows
Columns and rows of a Table node 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 TableColumnResized and TableRowResized events when the operation completes.

License keys
There is no separate trial build of the control’s libraries anymore. Instead, set the LicenseKey property to disable the component’s evaluation mode and stop displaying trial messages. License key strings are now listed on the Keys & Downloads page at MindFusion’s customer portal. Keys for MindFusion.Diagramming Pack will now work for ActiveX control too.

Miscellaneous

  • Table nodes can be roots of collapsible tree branches too. The Table class now provides Expandable and Expanded properties, and Expand and Collapse method. The control raises TableCollapsed and TableExpanded events when a table-rooted branch is collapsed or expanded.
  • SvgExporter.ExportString method returns a string containing the SVG markup;
  • fixed crash in integrated SvgExporter;

If you are interested in testing the beta version, please download this archive containing the control’s dll file:

http://mindfusion.eu/_beta/fcx492.zip

Technical support
MindFusion puts special effort in providing excellent customer support to all developers who use our components. You can write at the forum, help desk or use e-mail support@mindfusion.eu. All questions are usually answered within hours of being received.

About MindFusion.Diagramming for ActiveX: An ActiveX programming component that lets you create with ease every type of diagram, flowchart, scheme, chart, hierarchy, tree etc. The control supports rich user interaction model with advanced features like tool tips, grid alignment, docking points for nodes, scrolling and zooming and many more. FlowChartX implements 7 automatic layouts as well arrow routing. The appearance if each flowchart is completely customizable. Nodes can hold both images and text, their Z-order can be changed and there are tens of predefined shapes to choose from. Nodes support aero and glass visual effects.

The control also includes detailed documentation and many samples for a variety of languages and platforms. You can find more about the features of the tool at the features page or check the licensing scheme and the prices here.

Diagramming for Java Swing, V4.1.4 Released

MindFusion is happy to announce the new version of the Java Diagramming library. The release offers useful new features and improvements.

What’s New in Version 4.1.4

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.

Java Diagram Library: Table Nodes

Java Diagram Library: Table Nodes

License keys

There is no separate trial build of the control’s JAR archive provided anymore. Instead, call the setLicenseKey method of DiagramView to disable the component’s evaluation mode and stop displaying trial messages. setLicenseKey > is static and you can call it just once before creating any views. License key strings are now listed on the Keys & Downloads page at MindFusion’s customer portal.

Miscellaneous

  • Undo/redo records for in-place edit operations are now created automatically.
  • KeepInsideDiagram constraint 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 DashBackground property of HandlesVisualStyle.
  • Improved mouse capture for composite controls hosted inside ControlNodes.
  • StartPoint and EndPoint properties provide a shortcut to setting the first and last control points of a DiagramLink.

Fixed bugs

  • Fixed text clipping problem when magnifier is over TreeViewNode.
  • Links to contained nodes were left visibly disconnected from them after deleting a folded ContainerNode.
  • Lasso selection could not select strictly horizontal or vertical straight-line links when IncludeItemsIfIntersect is disabled.

The trial version is available for download from the following link:

Download MindFusion.Diagramming for Java Swing, V4.1.4 Trial Version

Technical support
MindFusion puts special effort in providing high quality technical support to all its clients and evaluators. You can post your questions about Diagramming for Java or any other of our components at the forum, help desk or at support@mindfusion.eu. All support inquiries are usually answered within hours of being received.

About Diagramming for Java Swing: MindFusion.Diagramming for Java Swing provides your Java application with all necessary functionality to create and customize a diagram. The library is very easy to integrate and program. There are numerous utility methods, rich event set, more than 100 predefined shapes. The tool supports a variety of ways to render or export the diagram, advanced node types like TreeView nodes, hierarchical nodes, tables, container nodes and many more. There are 15 automatic layouts, various input / output options and fully customizable appearance. A detailed list with JDiagram’s features is uploaded here. You can check the online demo to see some of the functionality implemented.

Diagramming for Java Swing is royalty free, there are no distribution fees. Licenses depend on the count of developers using the tool – check here the prices.

Display Petri nets using MindFusion diagram component.

In this post we show how to build a Petri net using MindFusion.Diagramming for WinForms. Petri nets are used to model and study distributed systems. A net contains places, transitions and arcs. A place represents possible state of the system, and a transition represents the change from one state to another. Arcs connect places to transitions and show the flow direction.

First, create a new .NET Windows Forms project and add a Model.cs file to it where we’ll define Petri net model classes

public class Net
{
	public List<Place> Places { get; set; }
	public List<Transition> Transitions { get; set; }
	public List<Arc> Arcs { get; set; }

	public Net()
	{
		Places = new List<Place>();
		Transitions = new List<Transition>();
		Arcs = new List<Arc>();
	}
}

public class Node
{
	public string Label { get; set; }
}

public class Place : Node
{
	public int Tokens { get; set; }
}

public class Transition : Node
{
}

public class Arc
{
	// Arcs run from a place to a transition or vice versa,
	// never between places or between transitions.

	public Arc(Place input, Transition output)
	{
		Input = input;
		Output = output;
	}

	public Arc(Transition input, Place output)
	{
		Input = input;
		Output = output;
	}

	public Node Input { get; private set; }
	public Node Output { get; private set; }

	public int Multiplicity { get; set; }
}

Now we can create a simple Petri net:

Net CreateSampleNet()
{
	var net = new Net();

	var p1 = new Place { Label = "P1", Tokens = 1 };
	var p2 = new Place { Label = "P2", Tokens = 0 };
	var p3 = new Place { Label = "P3", Tokens = 2 };
	var p4 = new Place { Label = "P4", Tokens = 1 };

	net.Places.AddRange(new[] { p1, p2, p3, p4 });

	var t1 = new Transition { Label = "T1" };
	var t2 = new Transition { Label = "T2" };

	net.Transitions.AddRange(new[] { t1, t2 });

	var a1 = new Arc(p1, t1);
	var a2 = new Arc(t1, p2);
	var a3 = new Arc(t1, p3);
	var a4 = new Arc(p2, t2);
	var a5 = new Arc(p3, t2);
	var a6 = new Arc(t2, p4);
	var a7 = new Arc(t2, p1);

	net.Arcs.AddRange(new[] { a1, a2, a3, a4, a5, a6, a7 });

	return net;
}

Next, drop a DiagramView and Diagram objects on the form which we’ll use to visualize the net. Add the following method to create diagram elements representing the model objects, and run LayeredLayout to arrange them:

void BuildDiagram(Net net)
{
	var nodeMap = new Dictionary<Node, DiagramNode>();

	var placeBounds = new RectangleF(0, 0, 16, 16);
	var transBounds = new RectangleF(0, 0, 6, 20);

	foreach (var place in net.Places)
	{
		var node = diagram.Factory.CreateShapeNode(placeBounds);
		node.Text = place.Label;
		node.TextFormat.LineAlignment = StringAlignment.Far;
		node.Shape = Shapes.Ellipse;
		node.Tag = place.Tokens;
		node.CustomDraw = CustomDraw.Additional;
		nodeMap[place] = node;
	}

	foreach (var trans in net.Transitions)
	{
		var node = diagram.Factory.CreateShapeNode(transBounds);
		node.Text = trans.Label;
		node.TextFormat.LineAlignment = StringAlignment.Far;
		node.Shape = Shapes.Rectangle;
		nodeMap[trans] = node;
	}

	foreach (var arc in net.Arcs)
	{
		var link = diagram.Factory.CreateDiagramLink(
			nodeMap[arc.Input], nodeMap[arc.Output]);
		link.Tag = arc.Multiplicity;
		link.HeadShape = ArrowHeads.PointerArrow;
	}

	var layout = new LayeredLayout();
	layout.Orientation = Orientation.Horizontal;
	layout.StraightenLongLinks = true;
	layout.Arrange(diagram);
}

We will use the DrawNode custom draw event to render marks associated with each place. Another possibility is to create a custom node class and override its Draw method.

void OnDrawNode(object sender, DrawNodeEventArgs e)
{
	var node = e.Node;
	var g = e.Graphics;

	if (node.Tag is int)
	{
		var tokens = (int)node.Tag;
		var cx = node.Bounds.Width / 2;
		var cy = node.Bounds.Height / 2;

		if (tokens == 1)
		{
			float r = cx / 2;
			DrawMark(cx, cy, r, g);
		}
		else if (tokens == 2)
		{
			float r = 2 * cx / 5;
			DrawMark(cx / 2, cy, r, g);
			DrawMark(3 * cx / 2, cy, r, g);
		}
		else if (tokens == 3)
		{
			float r = cx / 3;
			float y2 = 4 * cy / 3;
			DrawMark(cx, 2 * cy / 5, r, g);
			DrawMark(cx / 2, y2, r, g);
			DrawMark(3 * cx / 2, y2, r, g);
		}
	}
}

void DrawMark(float x, float y, float r, IGraphics g)
{
	g.FillEllipse(Brushes.Black, x - r, y - r, r * 2, r * 2);
}

Finally, set some appearance properties and call the methods above to build the diagram:

public MainForm()
{
	InitializeComponent();

	diagram.ShadowsStyle = ShadowsStyle.None;
	diagram.DiagramLinkStyle.Brush = new MindFusion.Drawing.SolidBrush(Color.Black);
	diagram.ShapeNodeStyle.Brush = new MindFusion.Drawing.SolidBrush(Color.White);
	diagram.ShapeNodeStyle.FontSize = 10f;
	diagram.ShapeNodeStyle.FontStyle = FontStyle.Bold;

	var textAbove = new[]
	{
		new LineTemplate(-100, -100, 200, -100),
		new LineTemplate(200, -100, 200, 0),
		new LineTemplate(200, 0, -100, 0),
		new LineTemplate(-100, 0, -100, -100)
	};
	Shapes.Ellipse.TextArea = textAbove;
	Shapes.Rectangle.TextArea = textAbove;

	var net = CreateSampleNet();
	BuildDiagram(net);
}

The final result is displayed below.
Petri net diagram

The complete sample project is available for download here:
PetriNet.zip

For more information on Petri nets, see this Wikipedia article:
http://en.wikipedia.org/wiki/Petri_net

All MindFusion.Diagramming libraries expose the same programming interface, so most of the sample code shown above will work with only a few modifications in WPF, ASP.NET, Silverlight and Java versions of the control.

Enjoy!