Gantt chart customization

TeeChart for JavaScript for the HTML5 Canvas
Post Reply
roman
Newbie
Newbie
Posts: 3
Joined: Thu Oct 16, 2014 12:00 am

Gantt chart customization

Post by roman » Thu Oct 30, 2014 6:15 am

I use Gantt chart to show CNC machine status monitoring.
Time window is one day or 12 hours so I have two shifts to draw (6:00-18:00,18:00-6:00).
Each shift has its breaks with specific length in specific time.

Is it possible to set my own axes.bottom begin, end and step?
For example from 6:00 to 18:00 step 1 hour so axes.bottom labels will be something like "6:00,7:00,8:00,...,17:00,18:00" and grid will accept given labels.
If I will zoom it should change from my axis to auto.

Is it also possible to highlight breaks in shift? Something like colored rectangle under the status bars?
cnc.PNG
CNC status monitoring example
cnc.PNG (19.27 KiB) Viewed 16217 times

Marc
Site Admin
Site Admin
Posts: 1213
Joined: Thu Oct 16, 2003 4:00 am
Location: Girona
Contact:

Re: Gantt chart customization

Post by Marc » Fri Oct 31, 2014 3:29 pm

Hello,

You can set the Axis label step via the Increment property and the Axis min and max via the setMinMax method.

Eg. Modifications made to datetime.htm demo page included with TeeChart examples

Code: Select all

  var msecsInADay = 86400000;
  
  Chart1.axes.bottom.increment = msecsInADay * 5;

  for (var t=0; t<100; t++) {
    series.data.values[t]=Math.random()*1000;
    series.data.x[t]=new Date(today + t * msecsInADay);
  }
  
  Chart1.axes.bottom.labels.dateFormat = 'shortDate';
  Chart1.axes.bottom.labels.angle = 90;
  
  Chart1.axes.bottom.setMinMax(series.data.x[20].getTime(), series.data.x[37].getTime());
The above code sets an axis label step at 5 days and the axis minimum and maximum to the 20th and 37th data values respectively.

I hope that may be of help.

Any extras you'd like to plot on the Chart, such as the breaks you describe, can be done via the Chart Canvas (example: http://www.steema.com/files/public/teec ... _paint.htm). Shapes, polygons or lines may be plotted on the Chart and fixed to data locations if required.

On the datetime chart the code would look like this:

Code: Select all

  var myFormat = new Tee.Format(Chart1);
  myFormat.gradient.visible=true;
  myFormat.gradient.colors=["white","lime"];
  myFormat.transparency=0.3;  
  
  //Chart1.ondraw=function() { //use this for after plot code
  series.onbeforedraw=function() {  //use this to plot before series plots, ie. underneath it
    var x1 = Chart1.axes.bottom.calc(series.data.x[20].getTime()),
        y1 = Chart1.axes.left.calc(200),
        x2 = Chart1.axes.bottom.calc(series.data.x[70].getTime()),
        y2 = Chart1.axes.left.calc(400);

    myFormat.rectangle(x1,y1, x2-x1, y2-y1);
  }
An example here, http://www.steema.com/files/public/teec ... roller.htm , plots an image to the Chart:

Code: Select all

  Chart1.ondraw=function() {
    var img=document.getElementById("skyline"); //where skyline is an img on the page.
    Chart1.ctx.drawImage(img,Chart1.axes.bottom.calc(Chart1.axes.bottom.minimum) + 8,
	                     Chart1.axes.left.calc(Chart1.axes.left.minimum)-img.height);
  }  
Regards,
Marc Meumann
Steema Support

roman
Newbie
Newbie
Posts: 3
Joined: Thu Oct 16, 2014 12:00 am

Re: Gantt chart customization

Post by roman » Thu Nov 06, 2014 8:06 am

Thank you for you ideas, I solved axis label step problem by defining

Code: Select all

var OneHour = (new Date(2014,1,2,6,0,0) - new Date(2014,1,1,6,0,0))/24;
and setting increment to defined OneHour

Code: Select all

Chart1.axes.bottom.increment = OneHour;
When I zoom I reset increment to auto and vice-versa

Code: Select all

Chart1.onzoom = function(){
        Chart1.axes.bottom.increment = 0;
}
    
Chart1.zoom.onreset = function(){
        Chart1.axes.bottom.increment = OneHour;
}

It works very well so case is solved.

As for drawing breaks on canvas under series, I have some problems.
First of all there is no onbeforedraw functionality definition in my teechart.js v1.7 July 2014, I have found only one mention

Code: Select all

...
if (s.onbeforedraw) s.onbeforedraw(s);
...
Second, if I understand it well, I have to recalculate and redraw everything I drew, related to bottom axis, during every zoom and zoom.onreset.
To do it well I need to calculate

Code: Select all

	var x1 = Chart1.axes.bottom.calc(new Date(y,m,d,h,i,s));
	var x2 = Chart1.axes.bottom.calc(new Date(y,m,d,h,i,s));

and draw new rectangles.
What about canvas.clearRect(), is it done during Chart.draw()?

Yeray
Site Admin
Site Admin
Posts: 9533
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Gantt chart customization

Post by Yeray » Thu Nov 06, 2014 1:21 pm

Hello,
roman wrote: As for drawing breaks on canvas under series, I have some problems.
First of all there is no onbeforedraw functionality definition in my teechart.js v1.7 July 2014, I have found only one mention

Code: Select all

...
if (s.onbeforedraw) s.onbeforedraw(s);
...
Yes, that's enough. This line makes the series onbeforedraw method to be called at that time if you define it.
roman wrote:Second, if I understand it well, I have to recalculate and redraw everything I drew, related to bottom axis, during every zoom and zoom.onreset.
To do it well I need to calculate

Code: Select all

	var x1 = Chart1.axes.bottom.calc(new Date(y,m,d,h,i,s));
	var x2 = Chart1.axes.bottom.calc(new Date(y,m,d,h,i,s));

and draw new rectangles.
What about canvas.clearRect(), is it done during Chart.draw()?
Yes, taking the DateTime example here, you can use ondraw or onbeforedraw events to draw your custom shapes, lines etc related to the chart elements as follows:

Code: Select all

  var myFormat = new Tee.Format(Chart1);
  myFormat.gradient.visible=true;
  myFormat.gradient.colors=["white","lime"];
  myFormat.transparency=0.3;
  
  Chart1.series.items[0].onbeforedraw=function() {  //use this to plot before series plots, ie. underneath it

    var x1 = Chart1.axes.bottom.calc(new Date(2014,11,1,0,0,0)),
        y1 = Chart1.axes.left.startPos,
        x2 = Chart1.axes.bottom.calc(new Date(2014,11,15,0,0,0)),
        y2 = Chart1.axes.left.endPos;

    // X,Y, Width, Height
    myFormat.rectangle(x1,y1, x2-x1, y2-y1);
  }
  
  Chart1.ondraw=function() {

    var x1 = Chart1.axes.bottom.calc(new Date(2014,12,15,0,0,0)),
        y1 = Chart1.axes.left.startPos,
        x2 = Chart1.axes.bottom.calc(new Date(2015,0,1,0,0,0)),
        y2 = Chart1.axes.left.endPos;

    // X,Y, Width, Height
    myFormat.rectangle(x1,y1, x2-x1, y2-y1);
  }
  
  Chart1.draw();
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

roman
Newbie
Newbie
Posts: 3
Joined: Thu Oct 16, 2014 12:00 am

Re: Gantt chart customization

Post by roman » Fri Nov 28, 2014 12:25 pm

Thank you for your cooperation, result is very nice.
Capture.PNG
Capture.PNG (64.92 KiB) Viewed 16033 times
I believe that there is possibility to load data from XML, but I'm lost as what structure has to have XML file for Gantt and Line chart.
Could you describe it for me?

Best regards
Roman

Yeray
Site Admin
Site Admin
Posts: 9533
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Gantt chart customization

Post by Yeray » Fri Nov 28, 2014 2:16 pm

Hi Roman,
roman wrote:I believe that there is possibility to load data from XML, but I'm lost as what structure has to have XML file for Gantt and Line chart.
Could you describe it for me?
The Data Sources/From XML example from the Features Demo is probably a good start point.

However, parseXML doesn't handle Gantt series particular lists (data.start, data.end) so you should override it to support it.
Here it is an example that seems to work fine for me here:

Code: Select all

<!DOCTYPE html>
<html>
<head>
<title>TeeChart JavaScript XML to Series Example</title>

<!--[if lt IE 9]>
    <script src="../../src/excanvas/excanvas_text.js"></script>
    <script src="../../src/excanvas/canvas.text.js"></script>
<![endif]-->

<script src="../../src/teechart.js" type="text/javascript"></script>
<script src="../../src/teechart-table.js" type="text/javascript"></script>

<script type="text/javascript">
var Chart1;
function draw() {
  Chart1=new Tee.Chart("canvas");
  var b=Chart1.addSeries(new Tee.Gantt());
  b.loadXML(document.getElementById("xml"));
  Chart1.title.text="XML to Chart";

  Chart1.axes.bottom.title.text=b.title;
  Chart1.axes.left.title.text=b.data.title;

  Chart1.legend.visible=false;
  Chart1.draw();
}

function parseXML(series,xml,seriesTag,pointTag) {
  var data=series.data;
  data.x=[];
  data.labels=[];
  data.start=[];
  data.end=[];

  seriesTag=seriesTag || "series";

  var doc=loadXML(xml.value), n;

  var s = doc.getElementsByTagName(seriesTag)[0];
  if (s) {
    n= s.getAttribute("color");
    if (n) series.color=n;

    n= s.getAttribute("name");
    if (n) series.title=n;

    n= s.getAttribute("metric");
    if (n) data.title=n;

    pointTag=pointTag || "point";

    var points= s.getElementsByTagName(pointTag);
    if (points) {
      for (var t = 0; t < points.length; t++) {
        data.x.push(t);
		
        n = points[t].getAttribute("name");
        if (n) data.labels.push(n);

        n = points[t].getAttribute("start");
        if (n){
          var year, month, day;
          var dateParts = n.split("/");
          var date = new Date(dateParts[2], (dateParts[1] - 1), dateParts[0]);
          data.start.push(date);
        }

        n = points[t].getAttribute("end");
        if (n){
          var year, month, day;
          var dateParts = n.split("/");
          var date = new Date(dateParts[2], (dateParts[1] - 1), dateParts[0]);
          data.end.push(date);
        }
      }
      data.values=data.start;
    }
  }
}

function trunc(value) {
  return value | 0;
}
</script>
</head>
<body onload="draw()">

<div>
<textarea id="xml" rows="6" cols="70" "wrap="off">
<series name="Dates" metric="Type">
  <point name="Type A" start="10/11/2014" end="10/12/2014"/>
  <point name="Type B" start="20/11/2014" end="15/2/2015"/>
  <point name="Type C" start="1/10/2014" end="1/1/2015"/>
</series>
</textarea>
<br/>
<button type="BUTTON" onclick="Chart1.series.items[0].refresh();">Refresh</Button>
</DIV>
<br/>
<canvas id="canvas" width="600" height="300">
This browser does not seem to support HTML5 Canvas.
</canvas>
</body>
</html>
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Post Reply