



function histogram(id,x_min,x_max,y_min,y_max,margin_top,margin_right,margin_bottom,margin_left) {
  
  //histogram object
  this.object = null;
  this.object_allow_scale_x = true;
  this.object_allow_scale_y = true;
  
  //dimensions object
  this.object_width = 0;
  this.object_height = 0;
  
  //visible data range
  this.x_min = x_min;
  this.x_max = x_max;
  this.y_min = y_min;
  this.y_max = y_max;
  
  //initial values margins
  this.margin_left = margin_left;
  this.margin_right = margin_right;
  this.margin_top = margin_top;
  this.margin_bottom = margin_bottom;
  
  //function to remove all child nodes
  function cleanObject(object) {
    if(object.hasChildNodes()) {
      while(object.childNodes.length>=1) {
        object.removeChild(object.firstChild);       
      } 
    }
  }
  
  //private function to find histogram div
  var findObject = function findObject(id) {
   var object = null;
   if( document.layers ) {   
    object = document.layers[id];
   } else if( document.all ) {
    object = document.all[id];
   } else if( document.getElementById ) {
    object = document.getElementById(id);
   }
   return object;
  };
  
  // put markers and marker-titles on the vertical axes
  
  this.setScaleX = function(markerStart, markerStep, markerTitleStart, markerTitleStep) {
    var i,r;
    if(this.object && this.object_allow_scale_x && (this.object_width>0) && (this.object_height>0)) {
      //register
      this.object_allow_scale_x = false;
      //create new item
      var scaleXLine = document.createElement('div');
      scaleXLine.className = 'horizontalScaleLine';
      //calculate dimensions
      var lineWidth = this.object_width-this.margin_left-this.margin_right;
      var lineBottom = this.margin_bottom;
      var lineLeft = this.margin_left;
      //set dimensions
      scaleXLine.style.width = lineWidth+'px';
      scaleXLine.style.bottom = lineBottom+'px';
      scaleXLine.style.left = lineLeft+'px';
      //add to object
      this.object.appendChild(scaleXLine);
      //check dimensions and position
      scaleXLine.style.bottom = (lineBottom - scaleXLine.offsetHeight)+'px';
      //set markers
      i = markerStart;      
      while((markerStep>0) && (i<=this.x_max)) {
        //create new item
        var scaleXMarker = document.createElement('div');
        scaleXMarker.className = 'horizontalScaleMarker';
        //calculate dimensions
        var markerBottom = this.margin_bottom;
        var markerLeft = this.margin_left + Math.round((this.object_width-this.margin_left-this.margin_right)*(i-this.x_min)/(this.x_max-this.x_min));
        //set dimensions
        scaleXMarker.style.bottom = markerBottom+'px';
        scaleXMarker.style.left = markerLeft+'px';
        //add to object
        this.object.appendChild(scaleXMarker);
        //check position
        scaleXMarker.style.bottom = (markerBottom - scaleXMarker.offsetHeight)+'px';
        i+=markerStep;
      }
      //set marker titles
      i = markerTitleStart;      
      r = Math.pow(10,Math.ceil(Math.log(1/markerTitleStep)/Math.log(10))); 
      while((markerTitleStep>0) && (i<=this.x_max)) {
        //create new item
        var scaleXMarkerTitle = document.createElement('div');
        scaleXMarkerTitle.className = 'horizontalScaleMarkerTitle';
        //calculate dimensions
        var markerTitleBottom = 0;
        var markerTitleLeft = this.margin_left + Math.round((this.object_width-this.margin_left-this.margin_right)*(i-this.x_min)/(this.x_max-this.x_min));
        var markerTitleHeight = this.margin_bottom;
        //set dimensions
        scaleXMarkerTitle.style.height = markerTitleHeight+'px';
        scaleXMarkerTitle.style.bottom = markerTitleBottom+'px';
        scaleXMarkerTitle.style.left = markerTitleLeft+'px';
        //set content
        scaleXMarkerTitle.innerHTML=(r>1)?(Math.round(i*r)/r):i;
        //add to object
        this.object.appendChild(scaleXMarkerTitle);
        //check position
        scaleXMarkerTitle.style.left = (markerTitleLeft-Math.round(scaleXMarkerTitle.offsetWidth/2))+'px';
        if(scaleXMarkerTitle.offsetheight>markerTitleHeight) { scaleXMarkerTitle.style.height = (markerTitleHeight - (scaleXMarkerTitle.offsetHeight-markerTitleHeight))+'px'; }
        i+=markerTitleStep;
      }
    }
  };
  
  // put markers and marker-titles on the horizontal axes
  
  this.setScaleY = function(markerStart, markerStep, markerTitleStart, markerTitleStep) {
    var i,r;
    var markerLeft, markerBottom, lineLeft, lineWidth, lineHeight, lineBottom, scaleYMarker, scaleYLine;
    if(this.object && this.object_allow_scale_y && (this.object_width>0) && (this.object_height>0)) {
      //register
      this.object_allow_scale_y = false;
      //create new item
      scaleYLine = document.createElement('div');
      scaleYLine.className = 'verticalScaleLine';
      //calculate dimensions
      lineHeight = this.object_height-this.margin_top-this.margin_bottom;
      lineLeft = this.margin_left;
      lineBottom = this.margin_bottom;
      //set dimensions
      scaleYLine.style.height = lineHeight+'px';
      scaleYLine.style.bottom = lineBottom+'px';
      scaleYLine.style.left = lineLeft+'px';
      //add to object
      this.object.appendChild(scaleYLine);
      //check dimensions and position
      if(scaleYLine.offsetheight>scaleYLine.clientHeight) { scaleYLine.style.height = (lineHeight - (scaleYLine.offsetHeight-scaleYLine.clientHeight))+'px'; }
      scaleYLine.style.left = (lineLeft - scaleYLine.offsetWidth)+'px';
      //set markers
      i = markerStart;            
      while((markerStep>0) && (i<=this.y_max)) {
        //create new item
        scaleYMarker = document.createElement('div');
        scaleYLine = document.createElement('div');
        scaleYMarker.className = 'verticalScaleMarker';
        scaleYLine.className = 'verticalScaleMarkerLine';
        //calculate dimensions
        markerLeft = this.margin_left;
        markerBottom = this.margin_bottom + Math.round((this.object_height-this.margin_top-this.margin_bottom)*(i-this.y_min)/(this.y_max-this.y_min));
        lineLeft = this.margin_left;
        lineWidth = this.object_width-this.margin_left-this.margin_right;
        lineBottom = markerBottom;
        //set dimensions
        scaleYMarker.style.bottom = markerBottom+'px';
        scaleYMarker.style.left = markerLeft+'px';
        scaleYLine.style.bottom = lineBottom+'px';
        scaleYLine.style.width = lineWidth+'px';
        scaleYLine.style.left = lineLeft+'px';
        //add to object
        this.object.appendChild(scaleYMarker);
        this.object.appendChild(scaleYLine);
        //check position
        scaleYMarker.style.left = (markerLeft - scaleYMarker.offsetWidth)+'px';
        i+=markerStep;
      }
      //set marker titles
      i = markerTitleStart;  
      r = Math.pow(10,Math.ceil(Math.log(1/markerTitleStep)/Math.log(10))); 
      while((markerTitleStep>0) && (i<=this.y_max)) {
        //create new item
        var scaleYMarkerTitle = document.createElement('div');
        scaleYMarkerTitle.className = 'verticalScaleMarkerTitle';
        //calculate dimensions
        var markerTitleLeft = 0;
        var markerTitleBottom = this.margin_bottom + Math.round((this.object_height-this.margin_top-this.margin_bottom)*(i-this.y_min)/(this.y_max-this.y_min));
        var markerTitleWidth = this.margin_left;
        //set dimensions
        scaleYMarkerTitle.style.width = markerTitleWidth+'px';
        scaleYMarkerTitle.style.bottom = markerTitleBottom+'px';
        scaleYMarkerTitle.style.left = markerTitleLeft+'px';
        //set content
        scaleYMarkerTitle.innerHTML=(r>1)?(Math.round(i*r)/r):i;
        //add to object
        this.object.appendChild(scaleYMarkerTitle);
        //check position
        scaleYMarkerTitle.style.bottom = (markerTitleBottom-Math.round(scaleYMarkerTitle.offsetHeight/2))+'px';
        if(scaleYMarkerTitle.offsetWidth>markerTitleWidth) { scaleYMarkerTitle.style.width = (markerTitleWidth - (scaleYMarkerTitle.offsetWidth-markerTitleWidth))+'px'; }
        i+=markerTitleStep;
      }
    }
  };
  
  // add data to histogram
  //
  // x : x-value
  // y : y-value
  // w : width
  // z : z-index for item, item gets style class item<z>
  // title : mouseover title
  
  this.addItem = function(x,y,w,z,title) {
    if(this.object && (this.object_width>0) && (this.object_height>0) && (y>0)) {
      //create new item
      var newItem = document.createElement('div');
      newItem.className = 'item'+z;
      newItem.title = title;
      newItem.alt = title;
      newItem.style.zIndex = z;
      //calculate dimensions
      var newHeight = Math.round((this.object_height-this.margin_top-this.margin_bottom)*(y-this.y_min)/(this.y_max-this.y_min));
      var newBottom = this.margin_bottom;
      var newLeft = this.margin_left + Math.round((this.object_width-this.margin_left-this.margin_right)*(x-this.x_min)/(this.x_max-this.x_min));
      var newWidth = this.margin_left + Math.round((this.object_width-this.margin_left-this.margin_right)*(x+w-this.x_min)/(this.x_max-this.x_min)) - newLeft + 1;
      //set dimensions
      newItem.style.width = newWidth+'px';
      newItem.style.height = newHeight+'px';
      newItem.style.bottom = newBottom+'px';
      newItem.style.left = newLeft+'px';
      //add to object
      this.object.appendChild(newItem);
      //check dimensions
      if(newItem.offsetWidth>newItem.clientWidth) { newItem.style.width = Math.max(0,(newWidth - (newItem.offsetWidth-newItem.clientWidth)))+'px'; }
      if(newItem.offsetHeight>newItem.clientHeight) { newItem.style.height = Math.max(0,(newHeight - (newItem.offsetHeight-newItem.clientHeight)))+'px'; }
    }
  };
  
  // add print button
  //
  // url : location image
  // title : title link
  
  this.addPrintButton = function(url,title) {
    var parent = this.object.parentNode;
    if(this.object && parent) {      
      var printButton = document.createElement('div');
      printButton.className = 'print';
      printButton.appendChild(document.createTextNode(title));
      printButton.onclick = function(){var printWindow = window.open(url,'printWindow','fullscreen=no,toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no'); printWindow.resizeTo(900,400); };
      if(parent.lastChild == this.object) {
        parent.appendChild(printButton);
      } else {
        parent.insertBefore(printButton, this.nextSibling);
      }
    }
  };
  
  //initialize
  this.object = findObject(id);
  if(this.object) {
    this.object_width = this.object.clientWidth;
    this.object_height = this.object.clientHeight;
    cleanObject(this.object);
  }
}
