---
title: "Gantt Chart Trick: How To Visualize Operations With Short Durations"
description: "In our Gantt chart trick we describe how to equip your .NET Gantt chart timescale with a \"magnifying glass\" to zoom into operations´ details."
---

[Production Scheduling Tips & Tricks for Microsoft Dynamics 365 Business Central ](https://blog.netronic.com)

# [Gantt Chart Trick: How To Visualize Operations With Short Durations](https://blog.netronic.com/gantt-chart-trick-how-to-visualize-operations-with-very-short-durations)

 Written by [Alfred Göhlich](https://blog.netronic.com/author/alfred-göhlich) | Jan 28, 2015 12:30:00 PM

Does this sound familiar? You have to visualize plenty of operations with short durations and have to cover both a short-term and a long-term planning horizon with one view in your Gantt scheduling appplication? There are two options of how to display the time scale. You could choose between

1. A very **detailed** time scale, offering the advantage of making the single operations clearly visible but, on the other hand only showing a very short period, thus losing the overview.
2. A **rough** time scale offering a good overview of a longer period, while however affecting the accuracy of details.

In our series of [Gantt chart tricks](https://blog.netronic.com/topic/xgantt-development-tricks) we describe how to create advanced planning and scheduling charts with our .NET Gantt control [VARCHART XGantt](https://www.netronic.com/products/varchart-xgantt/overview.html). Read in this blog post how to enhance the time scale function to realize a **magnifiying glass** letting you keep track of the longer period while at the same time zooming into a selected time window to show every detail of the operations.

### **Time Scale with Magnifying Glass Function**

Define a rough time scale, select a group of operations and switch to a detailed time scale only for the period containing the selected operations. The following steps are needed:

Step 1) Initial situation: The time scale lies within a **planning horizon of several days**.

 

 

The operations circled in red could lead the planner to the **assumption** that they consist **only of three operations**. 

 

Step 2) To check this, the planner **selects** these operations **with** the so called rectangle **rubber band**. 

In the background, VARCHART XGantt switches to a detailed time resolution for the selected period and it becomes immediately clear that there are **lots of operations located within this time window**:

 

 

Step 3) Clicking in the **white area of the diagram switches off** the time scale magnifying glass and the planner sees the former overview again.

 

## Hands-on step-by-step-guide how to achieve this with VARCHART XGantt

Create a time scale with three sections:

 

The labeling of the time scale section *DetailedArea* has to be more detailed than those of the other two, e.g., markings every ten minutes in contrast to hourly markings for the other time scale sections.

Layers with two filters are needed for displaying operations in the detailed time scale section and in the other two sections:

 

Add the data field *Tasks:NodeZoomed* to your node data table. It will be set at runtime.

Create two date lines to use as optical divider of the three time scale sections:

 

The following code is needed:

  

      //Global variables

      List<string> zoomedNodesIDs = new List<string>();

 

      DateTime earliestStart;

      DateTime latestEnd;

 

      double oldUnitWidthEx0;

      double oldUnitWidthEx1;

      double oldUnitWidthEx2;

 

      bool diagramLeftClicked = false;

 

      VcDateLine dateLine1;

      VcDateLine dateLine2;

 

      int sectionIndex;

 

```
      private void Form1_Load(object sender, EventArgs e)
```

```
      {
```

```
         //Add the following code after you have loaded your data into XGantt:
```

```
         ts.get_Section(1).StartDate = vcGantt1.TimeScaleStart;
```

```
         ts.get_Section(2).StartDate = vcGantt1.TimeScaleStart;
```

```
 
```

```
         dateLine1 = vcGantt1.DateLineCollection.DateLineByName("DateLine1");
```

```
         dateLine2 = vcGantt1.DateLineCollection.DateLineByName("DateLine2");
```

```
 
```

```
         oldUnitWidthEx0 = ts.get_Section(0).UnitWidthEx;
```

```
         oldUnitWidthEx1 = ts.get_Section(1).UnitWidthEx;
```

```
         oldUnitWidthEx2 = ts.get_Section(2).UnitWidthEx;
```

```
      }
```

```
 
```

```
 
```

```
      private void vcGantt1_VcNodesMarking(object sender, VcNodesMarkingEventArgs e)
```

```
      {
```

```
         if (e.NodeCollection.Count > 0)
```

```
         {
```

```
            DateTime startDate;
```

```
            DateTime endDate;
```

```
 
```

```
            VcCalendar cal = vcGantt1.CalendarCollection.Active;
```

```
            VcTimeScale ts = vcGantt1.TimeScaleCollection.Active;
```

```
 
```

```
            earliestStart = DateTime.MaxValue;
```

```
            latestEnd = DateTime.MinValue;
```

```
 
```

```
            //Reset all
```

```
            ts.get_Section(1).StartDate = vcGantt1.TimeScaleStart;
```

```
            ts.get_Section(2).StartDate = vcGantt1.TimeScaleStart;
```

```
            ts.get_Section(0).UnitWidthEx = oldUnitWidthEx0;
```

```
            ts.get_Section(1).UnitWidthEx = oldUnitWidthEx1;
```

```
            ts.get_Section(2).UnitWidthEx = oldUnitWidthEx2;
```

```
 
```

```
            //Compute start and end date for zoomed timescale section
```

```
            foreach (VcNode node in e.NodeCollection)
```

```
            {
```

```
               startDate = (DateTime)node.get_DataField(eTasks.Start);
```

```
               endDate = (DateTime)node.get_DataField(eTasks.End);
```

```
 
```

```
               if (startDate < earliestStart)
```

```
                  earliestStart = startDate;
```

```
 
```

```
               if (endDate > latestEnd)
```

```
                  latestEnd = endDate;
```

```
            }
```

```
 
```

```
            //Round to hours
```

```
            earliestStart = earliestStart.AddMinutes(-1 * earliestStart.Minute);
```

```
            latestEnd = latestEnd.AddMinutes(-1 * latestEnd.Minute).AddHours(1);
```

```
 
```

```
            //Set new section start dates
```

```
            ts.get_Section(2).StartDate = latestEnd;
```

```
            ts.get_Section(1).StartDate = earliestStart;
```

```
 
```

```
            vcGantt1.FitRangeIntoView(earliestStart, latestEnd, 120);
```

```
            ts.get_Section(0).UnitWidthEx = oldUnitWidthEx0;
```

```
            ts.get_Section(2).UnitWidthEx = oldUnitWidthEx2;
```

```
 
```

```
            vcGantt1.ScrollToDate(earliestStart, VcHorizontalAlignment.vcLeftAligned, 120);
```

```
 
```

```
            dateLine1.Date = earliestStart;
```

```
            dateLine1.Visible = true;
```

```
            dateLine2.Date = latestEnd;
```

```
            dateLine2.Visible = true;
```

```
         }
```

```
      }
```

```
 
```

```
 
```

```
      private void vcGantt1_VcNodesMarked(object sender, VcNodesMarkedEventArgs e)
```

```
      {
```

```
         UnmarkAllNodes();
```

```
         MarkNodesInTimeRange();
```

```
      }
```

```
 
```

```
 
```

```
      private void UnmarkAllNodes()
```

```
      {
```

```
         vcGantt1.SuspendUpdate(true);
```

```
         foreach (string nodeID in zoomedNodesIDs)
```

```
         {
```

```
            VcNode node = vcGantt1.GetNodeByID(nodeID);
```

```
            node.set_DataField(eTasks.NodeZoomed, 0);
```

```
            node.Update();
```

```
         }
```

```
         vcGantt1.SuspendUpdate(false);
```

```
 
```

```
         zoomedNodesIDs.Clear();
```

```
      }
```

```
 
```

```
 
```

```
      private void MarkNodesInTimeRange()
```

```
      {
```

```
         //Set "NodeZoomed" datafield for all nodes in zoomed timescale section
```

```
         DateTime startDate;
```

```
         DateTime endDate;
```

```
 
```

```
         if (!diagramLeftClicked)
```

```
         {
```

```
            vcGantt1.SuspendUpdate(true);
```

```
            foreach (VcNode node in vcGantt1.NodeCollection)
```

```
            {
```

```
               startDate = (DateTime)node.get_DataField(eTasks.Start);
```

```
               endDate = (DateTime)node.get_DataField(eTasks.End);
```

```
 
```

```
               if (startDate >= earliestStart && startDate < latestEnd || endDate > earliestStart && endDate <= latestEnd)
```

```
               {
```

```
                  node.set_DataField(eTasks.NodeZoomed, 1);
```

```
                  node.Update();
```

```
 
```

```
                  zoomedNodesIDs.Add(node.get_DataField(eTasks.ID).ToString());
```

```
               }
```

```
            }
```

```
            vcGantt1.SuspendUpdate(false);
```

```
         }
```

```
         diagramLeftClicked = false;
```

```
      }
```

```
 
```

```
 
```

```
      private void vcGantt1_VcDiagramLeftClicking(object sender, VcDiagramClickingEventArgs e)
```

```
      {
```

```
         //Reset the timescale so that only section 2 is visible
```

```
         VcTimeScale ts = vcGantt1.TimeScaleCollection.Active;
```

```
         ts.get_Section(1).StartDate = vcGantt1.TimeScaleStart;
```

```
         ts.get_Section(2).StartDate = vcGantt1.TimeScaleStart;
```

```
 
```

```
         ts.get_Section(0).UnitWidthEx = oldUnitWidthEx0;
```

```
         ts.get_Section(1).UnitWidthEx = oldUnitWidthEx1;
```

```
         ts.get_Section(2).UnitWidthEx = oldUnitWidthEx2;
```

```
 
```

```
         UnmarkAllNodes();
```

```
 
```

```
         dateLine1.Visible = false;
```

```
         dateLine2.Visible = false;
```

```
 
```

```
         diagramLeftClicked = true;
```

```
      }
```

 

 

Do you want to learn how to integrate a shift calendar into timescale? See this [blog post](https://blog.netronic.com/faq-shift-calendar).

[View full post](https://blog.netronic.com/gantt-chart-trick-how-to-visualize-operations-with-very-short-durations)

```json
{
  "@context" : "http://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Alfred Göhlich"
  },
  "dateModified" : "2017-09-17T11:57:16.751Z",
  "datePublished" : "2015-01-28T12:30:00Z",
  "headline" : "Gantt Chart Trick: How To Visualize Operations With Short Durations",
  "image" : {
    "@type" : "ImageObject",
    "height" : 236,
    "url" : "http://cdn2.hubspot.net/hub/315990/file-2377851483-png/blog/Zeitskalenlupe2.png",
    "width" : 173
  },
  "mainEntityOfPage" : "https://blog.netronic.com/gantt-chart-trick-how-to-visualize-operations-with-very-short-durations",
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "height" : 60,
      "url" : "/hs/hsstatic/content_shared_assets/static-1.4092/img/default-amp-logo.png",
      "width" : 60
    },
    "name" : "SMB Production Scheduling Software Blog"
  }
}
```