ASE Home Page Products Download Purchase Support About ASE
ChartDirector General
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  gantt chart scrolling
Posted by Anze on Feb-24-2012 20:59
Hi!

I am using a gantt chart in dotNet. I have managed to create a chart and display all the
data I need. I have external fields to set the dates in the chart. When I submit the fields I
reload the whole page and recreate the chart.

In your documentation I have found the article that I can scroll (vertically and horizontally)
with ajax.

Could you please give me just a short example of scrolling the chart with mouse.

Kind Regards,
Anze

  Re: gantt chart scrolling
Posted by Peter Kwan on Feb-25-2012 03:00
Hi Anze,

Zooming and scrolling are described in the "Zooming and Scrolling" section of the documentation. It describes in general how to scroll and zoom the chart, and introduce some examples. However, none of the examples is a gantt chart. (As there are many chart styles in ChartDirector, we cannot include examples for all possible chart styles.) If you need an example, please kindly let me know what is your programming language.

Regards
Peter Kwan

  Re: gantt chart scrolling
Posted by Anze on Feb-27-2012 16:23
Hi!

I would really appreciate a simple example of scrolling in gantt chart only. My programming
language is .NET.

Thank you in advance!

Anze

  Re: gantt chart scrolling
Posted by Anze on Feb-27-2012 16:34
sorry...My language is c# dotnet

  Re: gantt chart scrolling
Posted by Peter Kwan on Feb-28-2012 05:13
Attachments:
Hi Anze,

I have just made a very simple example based on the "Zoomable and Scrollable Demonstration (2)" sample code. I simply copy and paste the "Simple Gantt Chart" sample code into the charting portion of the "Zoomable and Scrollable Demonstration (2)" to change the latter from a scatter chart to a gantt chart. Then I modify the scaling part of the code to interchange the xy axis (as the axis is swapped in a gantt chart) and set the y-axis to date scale and x-axis to labels.

Hope this can help.

Regards
Peter Kwan
gantt_zoomscroll.aspx
<%@ Page Language="C#" Debug="true" %>
<%@ Import Namespace="ChartDirector" %>
<%@ Register TagPrefix="chart" Namespace="ChartDirector" Assembly="netchartdir" %>
<script runat="server">

//
// Copyright 2006 Advanced Software Engineering Limited
//
// You may use and modify the sample code in this file in your application, provided the Sample Code
// and its modifications are used only in conjunction with ChartDirector. Usage of this software is
// subjected to the terms and condition of the ChartDirector license.
//
//
// We need to handle 3 types of request: - initial request for the full web page - partial update
// (AJAX chart update) to update the chart without reloading the page - full page update for old
// browsers that does not support partial updates
//

//
// Handles the initial request
//
private void createFirstChart(WebChartViewer viewer)
{
    // Initialize the Javascript ChartViewer
    viewer.ScrollDirection = WebChartDirection.HorizontalVertical;
    viewer.ZoomDirection = WebChartDirection.HorizontalVertical;
    viewer.MouseUsage = WebChartMouseUsage.Scroll;

    // Draw the chart
    drawChart(viewer);
}

//
// Handles partial update (AJAX chart update)
//
private void processPartialUpdate(WebChartViewer viewer)
{
    // In this demo, we just need to redraw the chart
    drawChart(viewer);
}

//
// Handles full update
//
private void processFullUpdate(WebChartViewer viewer)
{
    // In this demo, we just need to redraw the chart
    drawChart(viewer);
}

//
// Draw the chart
//
private void drawChart(WebChartViewer viewer)
{
    // data for the gantt chart, representing the start date, end date and names for
    // various activities
    DateTime[] startDate = {new DateTime(2004, 8, 16), new DateTime(2004, 8, 30),
        new DateTime(2004, 9, 13), new DateTime(2004, 9, 20), new DateTime(2004, 9,
        27), new DateTime(2004, 10, 4), new DateTime(2004, 10, 25), new DateTime(
        2004, 11, 1), new DateTime(2004, 11, 8)};
    DateTime[] endDate = {new DateTime(2004, 8, 30), new DateTime(2004, 9, 13),
        new DateTime(2004, 9, 27), new DateTime(2004, 10, 4), new DateTime(2004, 10,
        11), new DateTime(2004, 11, 8), new DateTime(2004, 11, 8), new DateTime(2004,
        11, 22), new DateTime(2004, 11, 22)};
    string[] labels = {"Market Research", "Define Specifications",
        "Overall Archiecture", "Project Planning", "Detail Design",
        "Software Development", "Test Plan", "Testing and QA", "User Documentation"};

    // Create a XYChart object of size 620 x 280 pixels. Set background color to
    // light blue (ccccff), with 1 pixel 3D border effect.
    XYChart c = new XYChart(620, 280, 0xccccff, 0x000000, 1);

    // Add a title to the chart using 15 points Times Bold Itatic font, with white
    // (ffffff) text on a deep blue (000080) background
    c.addTitle("Simple Gantt Chart Demo", "Times New Roman Bold Italic", 15, 0xffffff
        ).setBackground(0x000080);

    // Set the plotarea at (140, 55) and of size 460 x 200 pixels. Use alternative
    // white/grey background. Enable both horizontal and vertical grids by setting
    // their colors to grey (c0c0c0). Set vertical major grid (represents month
    // boundaries) 2 pixels in width
    c.setPlotArea(140, 55, 460, 200, 0xffffff, 0xeeeeee, Chart.LineColor, 0xc0c0c0,
        0xc0c0c0).setGridWidth(2, 1, 1, 1);
	c.setClipping();

    // swap the x and y axes to create a horziontal box-whisker chart
    c.swapXY();

    // Set multi-style axis label formatting. Month labels are in Arial Bold font in
    // "mmm d" format. Weekly labels just show the day of month and use minor tick
    // (by using '-' as first character of format string).
    c.yAxis().setMultiFormat(Chart.StartOfMonthFilter(),
        "<*font=Arial Bold*>{value|mmm d}", Chart.StartOfDayFilter(), "-{value|d}");

    // Set the y-axis to shown on the top (right + swapXY = top)
    c.setYAxisOnRight();

    // Reverse the x-axis scale so that it points downwards.
    c.xAxis().setReverse();

    // Set the horizontal ticks and grid lines to be between the bars
    c.xAxis().setTickOffset(0.5);

    // Add a green (33ff33) box-whisker layer showing the box only.
    c.addBoxWhiskerLayer(Chart.CTime(startDate), Chart.CTime(endDate), null, null,
        null, 0x00cc00, Chart.SameAsMainColor, Chart.SameAsMainColor);

    if ((viewer.GetCustomAttr("minY") == null) || (viewer.GetCustomAttr("minY") == "")) {
        // The axis scale has not yet been set up. This means this is the first time the chart is
        // drawn and it is drawn with no zooming. We can use auto-scaling to determine the
        // axis-scales, then remember them for future use.

	    // Set the labels on the x axis
    	c.xAxis().setLabels(labels);

        // explicitly auto-scale axes so we can get the axis scales
        c.layout();

        // save the axis scales for future use
        viewer.SetCustomAttr("minX", c.xAxis().getMinValue());
        viewer.SetCustomAttr("maxX", c.xAxis().getMaxValue());
        viewer.SetCustomAttr("minY", c.yAxis().getMinValue());
        viewer.SetCustomAttr("maxY", c.yAxis().getMaxValue());

        viewer.ZoomInHeightLimit = 1.0 / labels.Length;

    } else {
        // Retrieve the original full axes scale
        double minX = double.Parse(viewer.GetCustomAttr("minX"));
        double maxX = double.Parse(viewer.GetCustomAttr("maxX"));
        double minY = double.Parse(viewer.GetCustomAttr("minY"));
        double maxY = double.Parse(viewer.GetCustomAttr("maxY"));

        // Compute the zoomed-in axis scales by multiplying the full axes scale with the view port
        // ratio
        int firstBar = (int)Math.Round(maxX - (maxX - minX) * viewer.ViewPortTop);
        int noOfBars = (int)Math.Round((minX - maxX) * viewer.ViewPortHeight);
        double yScaleMin = minY + (maxY - minY) * viewer.ViewPortLeft;
        double yScaleMax = minY + (maxY - minY) * (viewer.ViewPortLeft + viewer.ViewPortWidth);

        // Set the axis scales
        string[] visibleLabels = new string[noOfBars];
        Array.Copy(labels, firstBar, visibleLabels, 0, visibleLabels.Length);
        c.xAxis().setLinearScale(firstBar, firstBar + noOfBars - 1, visibleLabels);
        c.yAxis().setDateScale(yScaleMin, yScaleMax);

        // By default, ChartDirector will round the axis scale to the tick position. For zooming, we
        // want to use the exact computed axis scale and so we disable rounding.
        c.xAxis().setRounding(false, false);
        c.yAxis().setRounding(false, false);
    }

    // Create the image
    // Output the chart
    viewer.Image = c.makeWebImage(Chart.PNG);

    // Include tool tip for the chart
    viewer.ImageMap = c.getHTMLImageMap("", "",
        "title='{xLabel}: {top|mmm dd, yyyy} to {bottom|mmm dd, yyyy}'");
}

//
// Page Load event handler
//
protected void Page_Load(object sender, EventArgs e)
{
    //
    // We need to handle the first chart request, partial update request (AJAX chart update) and
    // full page update
    //
    if (WebChartViewer.IsPartialUpdateRequest(Page)) {
        // *** Is a parial update request ***

        // The .NET platform will not restore the states of the controls before or during Page_Load,
        // so we need to restore the state ourselves
        WebChartViewer1.LoadViewerState();

        // Draw the chart in partial update mode
        processPartialUpdate(WebChartViewer1);

        // Output the chart immediately and then terminate the page life cycle.
        WebChartViewer1.PartialUpdateChart();
    } else if (IsPostBack) {
        // *** Is a full update request ***
        processFullUpdate(WebChartViewer1);
    } else {
        // *** Page is first accessed ***
        createFirstChart(WebChartViewer1);
    }
}

</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>ChartDirector Zoom and Scroll Demonstration (2)</title>
    <script type="text/javascript" src="cdjcv.js"></script>
    <style type="text/css">
        div.chartPushButtonSelected { padding:5px; background:#ccffcc; cursor:hand; }
        div.chartPushButton { padding:5px; cursor:hand; }
        td.chartPushButton { font-family:Verdana; font-size:9pt; cursor:pointer; border-bottom:#000000 1px solid; }
    </style>
</head>
<body style="margin:0px" onload="initJsChartViewer()">
<script type="text/javascript">
// Initialize browser side Javascript controls
function initJsChartViewer()
{
    // Check if the Javascript ChartViewer library is loaded
    if (!window.JsChartViewer)
        return;

    // Get the Javascript ChartViewer object
    var viewer = JsChartViewer.get('<%=WebChartViewer1.ClientID%>');

    // Connect the mouse usage buttons to the Javascript ChartViewer object
    connectViewerMouseUsage('ViewerMouseUsage1', viewer);

    // Connect the view port window navigation pad to the Javascript ChartViewer object
    connectViewerViewPort('ViewerViewPort1', viewer);

    // Detect if browser is capable of support partial update (AJAX chart update)
    if (JsChartViewer.canSupportPartialUpdate())
        // Browser can support partial update, so connect the view port change event to
        // trigger a partial update
        viewer.attachHandler("ViewPortChanged", viewer.partialUpdate);
}
</script>
<form method="post" id="ZoomScrollDemo2" runat="server">
<table cellspacing="0" cellpadding="0" border="0">
    <tr>
        <td align="right" colspan="2" style="background:#000088">
            <div style="padding-bottom:2px; padding-right:3px; font-weight:bold; font-size:10pt; font-style:italic; font-family:Arial;">
                <a style="color:#FFFF00; text-decoration:none" href="http://www.advsofteng.com/">Advanced Software Engineering</a>
            </div>
        </td>
    </tr>
    <tr valign="top">
        <td style="width:130px; background:#e0e0e0; border-left:black 1px solid; border-top:black 1px solid; border-bottom:black 1px solid;">
            <!-- The following table is to create 3 cells for 3 buttons. The buttons are used to control
                 the mouse usage mode of the Javascript ChartViewer. -->
            <table id="ViewerMouseUsage1" cellspacing="0" cellpadding="0" width="100%" border="0">
                <tr>
                    <td class="chartPushButton">
                        <div class="chartPushButton" id="ViewerMouseUsage1_Scroll" title="Pointer">
                            <img src="pointer.gif" style="vertical-align:middle" width="16" height="16" alt="Pointer" />&nbsp;&nbsp;Pointer
                        </div>
                    </td>
                </tr>
                <tr>
                    <td class="chartPushButton">
                        <div class="chartPushButton" id="ViewerMouseUsage1_ZoomIn" title="Zoom In">
                            <img src="zoomInIcon.gif" style="vertical-align:middle" width="16" height="16" alt="Zoom In" />&nbsp;&nbsp;Zoom In
                        </div>
                    </td>
                </tr>
                <tr>
                    <td class="chartPushButton">
                        <div class="chartPushButton" id="ViewerMouseUsage1_ZoomOut" title="Zoom Out">
                            <img src="zoomOutIcon.gif" style="vertical-align:middle" width="16" height="16" alt="Zoom Out" />&nbsp;&nbsp;Zoom Out
                        </div>
                    </td>
                </tr>
            </table>
            <script type="text/javascript">
            // Connect the mouse usage buttons to the Javascript ChartViewer
            function connectViewerMouseUsage(controlId, viewer)
            {
                // A cross browser utility to get the object by id.
                function getObj(id) { return document.getElementById ? document.getElementById(id) : document.all[id]; }

                // Set the button styles (colors) based on mouse usage mode
                function syncButtons()
                {
                    getObj(controlId + "_Scroll").className = (viewer.getMouseUsage() == JsChartViewer.Scroll) ?
                        "chartPushButtonSelected" : "chartPushButton";
                    getObj(controlId + "_ZoomIn").className = (viewer.getMouseUsage() == JsChartViewer.ZoomIn) ?
                        "chartPushButtonSelected" : "chartPushButton";
                    getObj(controlId + "_ZoomOut").className = (viewer.getMouseUsage() == JsChartViewer.ZoomOut) ?
                        "chartPushButtonSelected" : "chartPushButton";
                }
                syncButtons();

                // Run syncButtons whenever the Javascript ChartViewer is updated
                viewer.attachHandler("PostUpdate", syncButtons);

                // Set the Javascript ChartViewer mouse usage mode if the buttons are clicked.
                getObj(controlId + "_Scroll").onclick = function() { viewer.setMouseUsage(JsChartViewer.Scroll); syncButtons(); }
                getObj(controlId + "_ZoomIn").onclick = function() { viewer.setMouseUsage(JsChartViewer.ZoomIn); syncButtons(); }
                getObj(controlId + "_ZoomOut").onclick = function() { viewer.setMouseUsage(JsChartViewer.ZoomOut); syncButtons(); }
            }
            </script>
            <br /><br /><br /><br />
            <!-- The following DIV blocks constitute the view port navigation pad. -->
            <div id="ViewerViewPort1" style="margin: 10px 5px; text-align: center">
                <div style="border:black 1px solid; padding:0px; margin:0px; width:120px; height:120px; background-color:#c0c0ff;
                    text-align:left">
                    <div id="ViewerViewPort1_ViewPort" style="border:black 1px solid; padding:0px; margin:0px; visibility:hidden;
                        width:60px; height:60px; position:relative; background-color:#c0c0c0">
                        <img src="" style="display:none" height="1" width="1" alt="" />
                    </div>
                </div>
            </div>
            <script type="text/javascript">
            // Connect the view port navigation pad to the Javascript ChartViewer
            function connectViewerViewPort(controlId, viewer)
            {
                // A cross browser utility to get the object by id.
                function getObj(id) { return document.getElementById ? document.getElementById(id) : document.all[id]; }

                // Get the inner rectangle representing the visible view port
                var p = getObj(controlId + "_ViewPort");

                // Set up the mouse down event handler
                p.onmousedown = ViewerViewPort_startDrag;
                p.viewer = viewer;

                // Remember the width and height of the outer container of the navigation pad. The exact definition of
                // width and height differs depending on browsers (some includes the borders and some exclude the borders).
                var parent = p.parentElement || p.parentNode;
                p.parentW = parent.offsetWidth - (document.all ? 2 : 4);
                p.parentH = parent.offsetHeight - (document.all ? 2 : 4);

                // Connect the view port to the viewer PostUpdate handler
                connectViewPortHandler(controlId, viewer);

                // The navigation pad has been set up, so can display it now.
                p.style.visibility = "visible";
            }
            // Connect the view port to the viewer PostUpdate handler
            function connectViewPortHandler(controlId, viewer)
            {
                // Set the navigation pad size and position depending on the Javascript ChartViewer view port state
                var syncViewPort = function()
                {
                    // A cross browser utility to get the object by id.
                    function getObj(id) { return document.getElementById ? document.getElementById(id) : document.all[id]; }

                    // Get the inner rectangle representing the visible view port
                    var p = getObj(controlId + "_ViewPort");

                    // Set the size and position based on Javascript ChartViewer view port state
                    p.currentWidth = p.style.width = Math.round(p.parentW * viewer.getViewPortWidth());
                    p.currentHeight = p.style.height = Math.round(p.parentH * viewer.getViewPortHeight());
                    p.currentX = p.style.left = Math.round(p.parentW * viewer.getViewPortLeft());
                    p.currentY = p.style.top = Math.round(p.parentH * viewer.getViewPortTop());
                }
                syncViewPort();

                // Run syncViewPort whenever the Javascript ChartViewer is updated
                viewer.attachHandler("PostUpdate", syncViewPort);
            }
            // Mouse down event handler
            function ViewerViewPort_startDrag(e)
            {
                if (document.onmousemove != ViewerViewPort_mouseMove)
                {
                    // Remember the current onmousemove and onmouseup event handler and replace them
                    // with our own handler
                    document.ViewerViewPort_onmousemovesave = document.onmousemove;
                    document.ViewerViewPort_onmouseupsave = document.onmouseup;
                    document.onmousemove = ViewerViewPort_mouseMove;
                    document.onmouseup = ViewerViewPort_endDrag;
                }

                // Remember the mouse down position
                document.ViewerViewPort_dragObj = this;
                this.refX = this.currentX - (window.event || e).clientX;
                this.refY = this.currentY - (window.event || e).clientY;
            }
            // Mouse move event handler
            function ViewerViewPort_mouseMove(e)
            {
                // Set the position of the navigation pad depending on how far the mouse has been dragged
                var obj = document.ViewerViewPort_dragObj;
                obj.currentX = obj.style.left =
                    Math.max(0, Math.min(obj.refX + (window.event || e).clientX, obj.parentW - obj.currentWidth));
                obj.currentY = obj.style.top =
                    Math.max(0, Math.min(obj.refY + (window.event || e).clientY, obj.parentH - obj.currentHeight));
                return false;
            }
            // Mouse up event handler
            function ViewerViewPort_endDrag(e)
            {
                // Restore the previous nmousemove and onmouseup event handler
                document.onmousemove = document.ViewerViewPort_onmousemovesave;
                document.onmouseup = document.ViewerViewPort_onmouseupsave;

                // Set the new view port position based on the mouse position
                var newVpLeft = 0;
                var newVpTop = 0;
                var obj = document.ViewerViewPort_dragObj;
                if (obj.viewer.getViewPortWidth() < 1)
                    newVpLeft = obj.currentX / (obj.parentW - obj.currentWidth) * (1 - obj.viewer.getViewPortWidth());
                if (obj.viewer.getViewPortHeight() < 1)
                    newVpTop = obj.currentY / (obj.parentH - obj.currentHeight) * (1 - obj.viewer.getViewPortHeight());

                // Change the view port only when the new view port position is really different from
                // existing position (to avoid unnecessary partial or full update)
                if ((Math.abs(obj.viewer.getViewPortLeft() - newVpLeft) > 0.0000001) ||
                    (Math.abs(obj.viewer.getViewPortTop() - newVpTop) > 0.0000001))
                {
                    obj.viewer.setViewPortLeft(newVpLeft);
                    obj.viewer.setViewPortTop(newVpTop);
                    obj.viewer.applyHandlers("ViewPortChanged");
                }
            }
            </script>
        </td>
        <td style="border: black 1px solid; background-color: #c0c0ff">
            <div style="padding:5px">
                <chart:WebChartViewer id="WebChartViewer1" runat="server" width="500px" height="480px" />
            </div>
        </td>
    </tr>
</table>
</form>
</body>
</html>

  Re: gantt chart scrolling
Posted by WNKR10 on Jul-08-2013 16:07
Hi, i am using MFC and C++. I tried to do the example
Simple Zooming and Scrolling(MFC) with gantt chart, but with now success.
I cannot understand how to implement the loadData(), initChartViewer(CChartViewer *viewer), drawChart(CChartViewer *viewer), updateImageMap(CChartViewer *viewer)
that they'll work with gantt chart. I used the "Simple Gantt Chart" sample code. Please give me a short example how to do that.
Kind regards,
wnkr

  Re: gantt chart scrolling
Posted by Peter Kwan on Jul-09-2013 04:33
Attachments:
Hi WNKR10,

I have attached an example created by combining the "Simple Gantt Chart" sample code with the "Simple Zooming and Scrolling" sample code.

For the loadData, you just need to get the data from your data source (database, XML, etc). In the sample code, it just gets the data from some hard coded variables.

For initChartViewer, you just need to set the initial state of the ChartViewer (whether it is initially in "drag to zoom" or "drag to scroll" state, and what is the initial zoom level, ...). In the attached sample code, the initial state is set to "drag to scroll" and everything is left as default (which means initially there is no zoom or scroll).

The drawChart code draws the chart, with the axis code modified to handle zooming and scrolling. For example, the axis labels are no longer hard coded for weekly labels (as after zooming, the date range can be any arbitrary range), but is left to ChartDirector to automatically place the labels. The date range is no longer hard coded to a fixed value, but is sychronize to the view port.

Hope this can help.

Regards
Peter Kwan
simplezoomscrollgantt.zip
simplezoomscrollgantt.zip

36.81 Kb

  Re: gantt chart scrolling
Posted by WNKR10 on Jul-09-2013 15:13
Thank you, it works great! I was just close to do it myself, but now i see where my mistakes've been! Now i can implement my own data with gantt chart and try to do more elaborate stuff, thanks again for the fast answer!
Regards,
wnkr