We have added more functionality to our HTML5/JavaScript Gantt chart widgets. With the release of version 6.3 of our Visual Scheduling Widget (in short: VSW-SE) you can now intuitively drag&drop rows in the table area. Here is a description of this new feature and the other enhancements in the new version.
Intuitive drag & drop of table rows in the Gantt chart
Although VSW SE is offering a great bundle of possibilities to interact with the chart, one important thing was missing so far: drag & drop of table rows. This feature is highly valuable when quick and easy interactive restructuring or reordering of the data displayed in the table part is required.
The challenge with this feature was to find the most intuitive way for the user to do his work, especially when working with hierarchical structures.
To enable this feature globally, the options pm_defaultActivity/Entity/ResourceAllowedRowDragModes have been added. If one of these options is enabled, then you can drag the rows in the activities view, resources view, and entities table, respectively. You only need to press the left mouse button on a row and keep the button pressed. A row phantom appears, and you can start dragging.
There are two indicators that will help you easily determine the new position of the row when dropping the phantom:
- First, there is a horizontal line in the table exactly where the row should be placed. This orange line starts with an arrow to make it easier for the user to see whether the row will be on the same level or one level below the row that is currently hovered with the mouse cursor, i.e., as a child row:
- Secondly, a special indicator at the top left of the phantom gives additional information about the concrete new position:
In addition to globally enabling drag & drop of rows, you can of course also specify on a row-by-row basis whether they can be dragged or not. The activity, entity, and resource properties PM_AllowedRowDragModes are intended for this purpose.
Very often, different levels in a table contain different types of data. In this case, it does not make sense to allow the user to drop a row at each position. Instead, for example, a row from level x should only be droppable at a new position with level x. For this, the drag mode DragOnSameLevelOnly is provided. By enabling this mode, the phantom will switch to “cannot insert” (see figure above) to guide the user.
As already known from interactions with bars, the application is informed by events throughout the interaction process. The callback functions canDrag, onDragStart, onDrag, and onDragEnd are triggered as far as they are defined by setting the corresponding options.
As soon as the user drops a row, the application has to process this interaction and restructure the data accordingly. This leads us to the next extension of VSW SE. Especially for the reordering of table rows, a mechanism is needed to determine the order in which the rows are displayed. Let us see what VSW SE provides for this purpose.
Sorting of activities, allocations, resources, and entities
So far, the order in which objects were added determined the order in which the table rows were displayed. But it lacked a mechanism to explicitly specify a sort order or even more to dynamically change the sort order of the rows.
For sorting activity, allocation, entity, or resource rows each of these object types has now the new PM_SortCode property. The value type can be any that can be compared using JavaScript. By the options activityRowSortMode, allocationRowSortMode, entityRowSortMode, and resourceRowSortMode the order of the sorting (ascending, descending, or none) can be specified.
To get more flexibility, there are also the new options activityRowSortCodePropertyName, allocationRowSortCodePropertyName, entityRowSortCodePropertyName, and resourceRowSortCodePropertyName. They allow you to quickly change the sorting criterion. Instead of the default PM_SortCode property, you can switch to a different object property and the rows will be reordered accordingly. There is no need to update the PM_SortCode property of all objects to achieve a new sort order. It is sufficient to simply change the source from which the sort code should be taken.
This sorting mechanism is essential when realizing an application with drag & drop of table rows (see above). If the ascending sort mode is defined and the values contain integer values, VSW SE pre-calculates the new sort codes of the dropped row object and eventually also of its siblings automatically. In this case, these calculated values can be found in the arguments of the OnDrop event function. Thus, all information an application needs to update its own sort codes in response to user interactions is available.
Assuming the user has dropped an activity row, the application can use the updateActivities method and update the sort codes of all affected activities. After that, the VSW SE will update the display and position of the dropped row at exactly the place targeted by the user.
Performance enhancements
Although performance enhancement is a continuous task in our daily development, this time we have focused on three special topics, some of which also affect the API:
- There are the new callback options visibilityFilterForActivities/Allocations/Resources/Entities. These replace the now deprecated visibilityFilter. VSW SE can now save time when filtering because the amount of objects to be processed in each case is reduced. Only objects of the same type are considered when evaluating the filter.
- Following the same intention and principle, the new callback options compareActivities/Allocations/Resources/Entities replace the now deprecated compareObjects
- The performance of the add-, update- Activities/Resources/Entities methods when processing hierarchies by using the ParentID properties of the concerned objects have been significantly improved.
Easier setting of default values
It is annoying and causes an unnecessary amount of data transfer between web server and client when all objects of a certain type have a property with the same value. For this, there are now the options defaultValuesForObjectProperties with 'Object' standing for Activity, ActivityEntry, Allocation, AllocationEntry, Entity, Link, and Resource.
The type of these options is Object. You can create a JavaScript object with properties that are specific to the object type for which you want to set the default values.
For example, if you set the following object as the defaultValuesForActivityProperties option, by default all activities will be colored green, and the user will only be able to resize the activity bars on the right side (i.e., at the end). Any other interaction with the bars, such as moving them, will not work.
{
PM_Color: "green",
PM_AllowedBarDragModes: netronic.nVSW.ActivityBarDragModes.DragEnd
}
One additional note regarding the evaluation order of the object properties:
Depending on the property we are considering, we now have a maximum of three ways to set up a property. These settings are evaluated in the following order and the evaluation process stops as soon as a defined value is found:
- Setting a property directly on the object itself, for example, Activity["PM_BarHeight"] = 20;
- Setting by the new default value objects, for example, widget.option("defaultValuesForActivityProperties", {"PM_BarHeight": 40});
- Setting a specific option, for example, widget.option("pm_defaultActivityBarHeight", 30);
If none of these three ways is used to set a property, the values defined internally in the widget are applied.
Miscellaneous
There are some other extensions:
- New property PM_BorderDashArray of Activity and Allocation objects.
- Symbols on date lines are now also placed in an optimized way.
- Automatic detection of duplicate IDs and cycles in the hierarchy when using ParentIDs on adding or updating objects resulting in a warning and additionally in an exception in the latter case.
For further details, please check the Changelog chapter in the Interface Definition Document (IDD), which is included in the download.
Features in previous releases