Page 1 of 1

Gantt chart customization

Posted: Thu Oct 30, 2014 6:15 am
by 17770444
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 17769 times

Re: Gantt chart customization

Posted: Fri Oct 31, 2014 3:29 pm
by Marc
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

Re: Gantt chart customization

Posted: Thu Nov 06, 2014 8:06 am
by 17770444
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()?

Re: Gantt chart customization

Posted: Thu Nov 06, 2014 1:21 pm
by yeray
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();

Re: Gantt chart customization

Posted: Fri Nov 28, 2014 12:25 pm
by 17770444
Thank you for your cooperation, result is very nice.
Capture.PNG
Capture.PNG (64.92 KiB) Viewed 17585 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

Re: Gantt chart customization

Posted: Fri Nov 28, 2014 2:16 pm
by yeray
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>