Вход Регистрация
Файл: js/al/graph.js
Строк: 2260
<?php
if (!window.Graph)
(function(
window) {

var 
DRAG_CURSOR 'pointer',
  
DRAG2_CURSOR 'pointer';
var 
document window.document;

// Date utils
var MINUTE 60HOUR 60 MINUTEDAY 24 HOURMONTH 28 DAYYEAR 365 DAYMAXSCALE DAY HOUR;
var 
xscales = [
  {
baseHOURformat: ['hour'], sub: -1},
  {
baseHOURformat: ['hour'], subHOUR},
  {
baseHOURformat: ['hour'], subHOUR},
  {
baseHOURformat: ['dayHour'], subHOUR},
  {
baseHOURformat: ['dayHour'], subHOUR},
  {
base12 HOURformat: ['dayHour'], subHOUR},
  {
baseDAYformat: ['dayFull''day'], sub: -1},
  {
baseDAYformat: ['dayFull''day'], subDAY},
  {
baseDAYformat: ['dayFull''day'], subDAY},
  {
baseDAYformat: ['dayFull''day'], subDAY},
  {
baseMONTHformat: ['monthFull''month'], sub: -1},
  {
baseMONTHformat: ['monthFull''month'], subMONTH},
  {
baseMONTHformat: ['monthFull''month'], subMONTH},
  {
baseMONTHformat: ['monthFull''month'], subMONTH},
  {
baseMONTHformat: ['monthFull''month'], subMONTH},
  {
baseYEARformat: ['yearFull'], sub: -1}]; // using 'year' ('00, '01, '02...) seems a bad idea
var DEF_TIME Math.round((new Date()).getTime() / 1000);
var 
dateFormats = {
  
hour"{hour}:00",
  
daygetLang('stats_day_mon').split("{month}").join("{dayMonth}"),
  
dayFullgetLang('stats_day_mon').split("{month}").join("{dayMonth}"),
  
dayFullYeargetLang('stats_day_month_year').split("{month}").join("{dayMonth}"),
  
dayHourgetLang('graph_day_fullmon_year_hour'),
  
dayHourMingetLang('graph_day_fullmon_year_hour_min'),
  
month"{shortMonth}'{shortYear}",
  
monthFull"{month}'{shortYear}",
  
year"'{shortYear}",
  
yearFull"{year}"
};
var 
colors = [0x597da30xb05c910x4d9fab0x5695670xac4c4c0xc9c2550xcd9f4d0x876db3,
              
0x6f9fc40xc77bb10x70c5c80x80bb880xce5e5e0xe8e2820xedb24a0xae97d3,
              
0x6391bc0xc77bb10x62b1bc0x80bb880xb754540xc9c2550xdca94f0x997fc4,
              
0x85afd00xc77bb10x8ecfce0x80bb880xe470700xc9c2550xf7be5a0xbeaadf];

var 
globalTouchCount 0;

function 
fullDate(timeparams) {
  var 
fmt = (params && params.show_time) ? ((params.show_minutes) ? 'dayHourMin' 'dayHour') : 'dayFullYear';
  return 
formatDate(timefmt);
}

function 
formatDate(timeformat) {
  if (
time == -1) {
    var 
= (format == 'dayHour' '0' '88'), '88''88',
      
mmmm 'Mmmmmmmm'mmmm2 'Mmmmmmmm'mmm 'mmm'mmm2 'mmm'yyyy '88888'yy '.88';
  } else {
    var 
date = new Date(time 1000);
    var 
date.getHours(), date.getMinutes().toString();
    var 
h12 12;
    if (
h12 == 0h12 12;
    var 
am_pm 12 'AM':'PM';
    
h.toString();
    if (
m.length == 1'0' m;
    var 
date.getDate().toString(),
    
mmmm getLang('Month' + (date.getMonth() + 1) + '_of'), mmmm2 getLang('Month' + (date.getMonth() + 1)),
    
mmm mmmm.substr(03).toLowerCase(), mmm2 mmmm2.substr(03).toLowerCase(),
    
yyyy date.getFullYear().toString(), yy yyyy.substr(2);
  }
  var 
fmt dateFormats[format];
  return 
fmt.split('{month}').join(mmmm2).
    
split('{shortMonth}').join(mmm2).
    
split('{shortYear}').join(yy).
    
split('{year}').join(yyyy).
    
split('{day}').join(d).
    
split('{dayMonth}').join(mmmm).
    
split('{shortDayMonth}').join(mmm).
    
split('{hour}').join(h).
    
split('{hour12}').join(h12).
    
split('{min}').join(m).
    
split('{am/pm}').join(am_pm);
}

function 
incDate(timestepinc) {
  var 
date = new Date(time 1000);
  if (
step >= YEAR) {
    var 
count step YEAR;
    
date = new Date((Math.floor(date.getFullYear() / count) + inc) * count0100);
    return 
Math.floor(date.getTime() / 1000);
  } else
  if (
step YEAR && step >= MONTH) {
    var 
count step MONTH;
    
date = new Date(date.getFullYear(), (Math.floor(date.getMonth() / count) + inc) * count100);
    return 
Math.floor(date.getTime() / 1000);
  } else
  if (
step MONTH) {
    var 
tz date.getTimezoneOffset() * 60;
    return 
Math.floor((time tz) / step inc) * step tz;
  }
}

// Other utils
function addEventEx(graphelementeventlistener) {
  
element.graph graph;
  
addEvent(elementeventlistener);
}
function 
removeEventEx(elementeventlistener) {
  
removeData(element"graph");
  
removeEvent(elementeventlistener);
}
function 
prepareEvent(eventpass) {
  if (
event.touches) {
    if (
event.touches.length || globalTouchCount 1) {
      
event.currentTarget.graph.endDrag();
      return 
false;
    } else {
      if (!
passcancelEvent(event);
      return 
event.touches[0];
    }
  }
  
cancelEvent(event);
  return 
event;
}

function 
getContext(e) {
  var 
ctx e.getContext("2d");
  if (!
ctx) return ctx;
  if (!
ctx.measureText || !ctx.measureText(getLang('Month1')))
    return 
null;
  return 
ctx;
}

function 
getFirstControlPoints(rhs) {
  var 
rhs.length= [], tmp = [], 2.0;
  
x[0] = rhs[0] / b;
  for (var 
1ni++) {
    
tmp[i] = b;
    
= (4.0 3.5) - tmp[i];
    
x[i] = (rhs[i] - x[1]) / b;
  }
  for (var 
1ni++)
    
x[1] -= tmp[i] * x[i];
  return 
x;
}

function 
getYStep(maxValueintScale) {
  var 
step Math.pow(10Math.floor(Math.LOG10E Math.log(maxValue)));
  if (
maxValue step <= 2)
    
step /= 4.0; else
  if (
maxValue step <= 4)
    
step /= 2.0;

  if (
intScale) {
    
step Math.max(step1);
    if (
step == 2.5) {
      
step 2;
    }
  }
  return 
step;
}

function 
formatValue(value) { // something like -10 000 000.000001
  
var sgn = (value 0) ? '-' '';
  
value Math.abs(value);
  var 
intv Math.floor(value), fltv value intv;
  
fltv Math.round(fltv 100000.0) / 100000.0;
  var 
res '';
  while (
intv 0) {
    var 
= (intv 1000).toString();
    
res = (intv 999 '000'.substr(0q.length) : '') + + (res == '' '' ' ') + res;
    
intv Math.floor(intv 1000);
  }
  if (
res == ''res '0';
  if (
fltv 0res += fltv.toString().substr(1);
  return 
sgn res;
}

function 
drawCheck(ecolorcolor2checkedover) {
  var 
ctx getContext(e);
  
ctx.clearRect(002020);
  if (
checked) { // shadow
    
ctx.lineWidth 2;
    
ctx.strokeStyle color2;
    
ctx.beginPath();
    
ctx.moveTo(6.511);
    
ctx.lineTo(9.514);
    
ctx.lineTo(17.56);
    
ctx.stroke();
  }
  if (
over) {
    
ctx.fillStyle color2;
    
ctx.fillRect(331414);
  }
  
ctx.lineWidth 1;
  
ctx.strokeStyle color;
  
ctx.strokeRect(3.53.51313);
  if (
checked) {
    
ctx.lineWidth 2;
    
ctx.beginPath();
    
ctx.moveTo(6.510);
    
ctx.lineTo(9.513);
    
ctx.lineTo(17.55);
    
ctx.stroke();
  }
}

function 
drawLines(ctxxywhlinesstTimeenTimexfactoryfactoryDeltazoomedOutactivesmooth) {
  
smooth = (!zoomedOut) && smooth;
  var 
stIdxs = [], enIdxs = [], _lines = [];
  for (var 
0lines.length + (active 0); l++) {
    var 
line = (lines.length) ? (active != lines[l] ? lines[l] : null) : active;
    if (
line && line.shown) {
      var 
stIdx 0enIdx line.d.length 1;
      while ((
stIdx line.d.length 2) && (line.d[stIdx 2].stTime)) stIdx++;
      while ((
enIdx 2) && (line.d[enIdx 2].enTime)) enIdx--;
      if (
enIdx stIdx 5// dots overload
        
smooth false;
      if (
enIdx >= stIdx && (line.d[enIdx].>= stTime) && (line.d[stIdx].<= enTime)) {
        
_lines.push(line);
          
stIdxs.push(stIdx);
        
enIdxs.push(enIdx);
        }
    }
  }

  
lines _lines;
  for (var 
0lines.lengthl++) {
    var 
stIdx stIdxs[l], enIdx enIdxs[l], ps lines[l].d;

    if (
smooth && (enIdx stIdx 2)) {
    var 
knots = [], 0;
    for (var 
stIdx<= enIdxi++) {
      
knots[n] = {X+ (ps[i].stTime) * xfactorY- (ps[i].yDelta) * yfactor};
      
n++;
    }
    
n--;

    var 
rhs = [];
    for (var 
11; ++i)
      
rhs[i] = knots[i].knots[1].X;
    
rhs[0] = knots[0].knots[1].X;
    
rhs[1] = (knots[1].knots[n].X) / 2.0;
    var 
xs1 getFirstControlPoints(rhs);

    for (var 
11; ++i)
      
rhs[i] = knots[i].knots[1].Y;
    
rhs[0] = knots[0].knots[1].Y;
    
rhs[1] = (knots[1].knots[n].Y) / 2.0;
    var 
ys1 getFirstControlPoints(rhs), xs2 = [], ys2 = [];
    for (var 
0n; ++i) {
      if (
1) {
      
xs2[i] = knots[1].xs1[1];
      
ys2[i] = knots[1].ys1[1];
      } else {
      
xs2[i] = (knots[n].xs1[1]) / 2;
      
ys2[i] = (knots[n].ys1[1]) / 2;
      }
    }
    }

    
// fill
    
if (lines[l].&& stIdx enIdx) {
      
ctx.globalAlpha = (active == null || active != lines[l]) ? 0.2 0.4;
      
ctx.fillStyle lines[l].hexColor;
      
ctx.strokeStyle lines[l].hexColor;
      
ctx.lineWidth = (zoomedOut 2);
      if (
lines[l].b) {
        for (var 
stIdx<= enIdxi++) {
          var 
cx1 Math.floor(+ ((stIdx ? (ps[1].ps[i].x) / ps[i].x) - stTime) * xfactor);
          var 
cx2 Math.floor(+ ((enIdx ? (ps[i].ps[1].x) / ps[i].x) - stTime) * xfactor);
          var 
cy = (ps[i].yDelta) * yfactor;
          
ctx.fillRect(cx1cycx2 cx1ps[i].yfactor);
        }
      } else {
        
ctx.beginPath();
        var 
px + (ps[stIdx].stTime) * xfactor;
        
ctx.moveTo(pxyDelta yfactor);
        for (var 
stIdx<= enIdxi++) {
        var 
cx + (ps[i].stTime) * xfactor;
        if (
smooth && (stIdx) && (enIdx stIdx 2))
          
ctx.bezierCurveTo(Math.min(Math.max(pxxs1[stIdx 1]), cx), Math.min(hMath.max(ys1[stIdx 1], 0)), Math.min(Math.max(pxxs2[stIdx 1]), cx), Math.min(hMath.max(ys2[stIdx 1], 0)), cx- (ps[i].yDelta) * yfactor);
        else
          
ctx.lineTo(cx- (ps[i].yDelta) * yfactor);
        
px cx;
        }
        
ctx.lineTo(pxyDelta yfactor);
        
ctx.fill();
      }
      
ctx.globalAlpha 1;
    }

    
// stroke
    
ctx.strokeStyle lines[l].hexColor;
    
ctx.lineWidth = (zoomedOut 2);
    
ctx.beginPath();
    var 
px + (ps[stIdx].stTime) * xfactorpy - (ps[stIdx].yDelta) * yfactor;
    
ctx.moveTo(pxpy);
    if (
lines[l].b) {
      for (var 
stIdx<= enIdxi++) {
        var 
cx Math.floor(+ ((enIdx ? (ps[i].ps[1].x) / ps[i].x) - stTime) * xfactor);
        var 
cy - (ps[i].yDelta) * yfactor;
        
ctx.lineTo(cxcy);
        if (
enIdx)
        if (
zoomedOut)
          
ctx.lineTo(cx- (ps[1].yDelta) * yfactor);
        else {
          
ctx.stroke();
          
ctx.beginPath();
          
ctx.moveTo(cx- (ps[1].yDelta) * yfactor);
        }
      }
    } else {
      for (var 
stIdx 1<= enIdxi++) {
        var 
cx + (ps[i].stTime) * xfactorcy - (ps[i].yDelta)* yfactor;
        if (
ps[i].== 'x') {
          
ctx.stroke();
          
ctx.beginPath();
          
ctx.moveTo(cxcy);
        } else {
          if (
ps[i].== '-' || ps[i].== '--' || ps[i].== '.') {
            
ctx.stroke();
            
ctx.globalAlpha 0.3;
            
ctx.beginPath();
            
ctx.moveTo(pxpy);
          }

          if (
smooth && (stIdx) && (enIdx stIdx 2))
            
ctx.bezierCurveTo(Math.min(Math.max(pxxs1[stIdx 1]), cx), Math.min(hMath.max(ys1[stIdx 1], 0)), Math.min(Math.max(pxxs2[stIdx 1]), cx), Math.min(hMath.max(ys2[stIdx 1], 0)), cx- (ps[i].yDelta) * yfactor);
          else
            
ctx.lineTo(cx- (ps[i].yDelta) * yfactor);

          if (
ctx.globalAlpha != 1) {
            
ctx.stroke();
            
ctx.beginPath();
            
ctx.moveTo(cxcy);
          }
        }
        
ctx.globalAlpha 1;
        
px cx;
        
py cy;
      }
    }
    
ctx.stroke();

    
// dots
    
if (smooth || (enIdx stIdx && !zoomedOut)) {
      
ctx.strokeStyle lines[l].hexColor;
      
ctx.fillStyle '#ffffff';
      
ctx.lineWidth 2;
      for (var 
stIdx<= enIdxi++) {
        
ctx.beginPath();
        
ctx.arc(+ (ps[i].stTime) * xfactor- (ps[i].yDelta) * yfactor3.50Math.PI*2true);
        
ctx.fill();
        
ctx.stroke();
      }
    }
  }
}

function 
drawBars(ctxxywhlineslabelsbarWxfactoryfactoryDelta) {
  for (var 
0lines.lengthl++) {
    var 
ps lines[l].d;
    for (
0ps.lengthi++) {
      if (!
labels[ps[i].x]) {
        continue;
      }
      var 
cx Math.floor(getBarXValue(xxfactorbarWlps[i].x));
      var 
psy Math.max(ps[i].yyfactor);
      var 
cy = (psy yDelta) * yfactor;

      
ctx.fillStyle lines[l].hexColor;
      
ctx.fillRect(cxMath.floor(cy), barWMath.ceil(psy yfactor));
    }
  }
}

function 
getBarXValue(xOffsetxStepbarsWidthlineIndexbarIndex) {
  return 
xOffset barsWidth lineIndex barsWidth barIndex xStep;
}

function 
clearSelection() {
  if(
document.selection && document.selection.empty) {
    
document.selection.empty();
  } else if(
window.getSelection) {
    var 
sel window.getSelection();
    
sel.removeAllRanges();
  }
}

function 
dataObjectToArray(data_object) {
  var 
data_array = [];
  for (var 
name in data_object) {
    
data_array.push(data_object[name]);
  }
  return 
data_array;
}

// Graph constructor

function Graph(iddataparamswidthheight) {
  var 
graph this;
  
params extend({}, params);
  
width width width 585;
  
height height height 385;
  
extend(this, {paramsparamswidthwidthheightheightviewWidthwidthviewHeightheight 80});
  
this.params.yunits this.params.yunits || '';

  
// create basic DOM tree
  
this.graphDiv ge(id);
  
setStyle(this.graphDiv, {fontFamily'tahoma, arial, verdana, sans-serif, Lucida Sans'fontSize'11px'color'#36638e'widththis.viewWidth 'px'clear'both'lineHeight'130%'});
  
this.graphDiv.innerHTML '<div style="float: left"><canvas style="padding-top: 20px"></canvas></div>
    <div style="float: left">
      <div style="height: 20px; float: right;"></div>
      <div style="height: 20px; padding-left: 10px;"></div>
      <div style="position: relative; height: ' 
this.viewHeight 'px;">
        <canvas height="' 
this.viewHeight '"></canvas>
        <canvas height="' 
+ (this.viewHeight 17) + '" style="position: absolute; top: 0; left: 0;"></canvas>
        <div style="position: absolute; border: 1px solid #5f7d9d; color: #5f7d9d;
            background-color: #eeeeee; padding: 2px 3px 2px 4px; white-space: nowrap; display: none;">' 
cur.graphVars['lang.data_empty'] + '</div>
      </div>
      <div style="position: relative; height: 40px;">
        <canvas height="40"></canvas>
        <div style="position: absolute; top: 0; height: 38px; border: 1px solid #b8c5d4; border-width: 1px 0px 1px 1px; border-top-color: #d3dee8;"><div style="background: white; opacity: 0.5; filter: alpha(Opacity=50); width: 100%; height: 100%;"></div></div>
        <div style="position: absolute; top: 0; height: 38px; border: 1px solid #b8c5d4; cursor: ' 
DRAG_CURSOR ';"></div>
        <div style="position: absolute; top: 0; height: 38px; border: 1px solid #b8c5d4; border-width: 1px 1px 1px 0px; border-top-color: #d3dee8;"><div style="background: white; opacity: 0.5; filter: alpha(Opacity=50); width: 100%; height: 100%;"></div></div>
        <div style="position: absolute; top: 0; height: 38px; border: 1px solid #b8c5d4; background: #ced9de; opacity: 0.5; filter: alpha(Opacity=50); display: none;"></div>
          <div style="position: absolute; top: 0; width: 8px; height: 40px; cursor: w-resize;"></div>
          <div style="position: absolute; top: 0; width: 8px; height: 40px; cursor: e-resize;"></div>
      </div>
      <div style="float: left; width: 270px; padding-top: 8px; -moz-user-select: none; -khtml-user-select: none;"></div><div style="float: left; width: 270px; padding-top: 8px; -moz-user-select: none; -khtml-user-select: none;"></div>
    </div><div style="clear: left;"></div>'
;

  
this.vScale this.graphDiv.children[0];
  
this.vScaleView this.vScale.children[0];
  
this.mainLayout this.graphDiv.children[1];
  
this.menu this.mainLayout.children[0];
  
this.title this.mainLayout.children[1];
  
this.zinLayout this.mainLayout.children[2];
  
this.zinView this.zinLayout.children[0];
  
this.dotsLayer this.zinLayout.children[1];
  
this.message this.zinLayout.children[2];
  
this.zoutLayout this.mainLayout.children[3];
  
this.zoutView this.zoutLayout.children[0];
  
this.lMask this.zoutLayout.children[1];
  
this.zoutWindow this.zoutLayout.children[2];
  
this.rMask this.zoutLayout.children[3];
  
this.select this.zoutLayout.children[4];
  
this.lHandle this.zoutLayout.children[5];
  
this.rHandle this.zoutLayout.children[6];
  
this.column = [this.mainLayout.children[4], this.mainLayout.children[5]];

  var 
defaultGraph 0;
  if (
typeof params.multiple == 'object' && params.multiple.items) {
    if (!
params.multiple.defparams.multiple.def 0;
    for (
i in params.multiple.items) {
      var 
item se('<a class="graph_menu_item' + (== params.multiple.def ' graph_menu_item_sel' '') + '">' params.multiple.items[i] + '</a>');
      var 
clickContext = {clickNodeigraphthis};
      
addEvent(item'click'this.onClickMenunullclickContext);
      
cur.destroy.push(function() {
        
removeEvent(item'click'this.onClickMenunullclickContext);
      });
      
this.menu.appendChild(item);
    }
    if (
params.multiple.graph_item) {
      var 
item se('<a class="graph_menu_item">' params.multiple.graph_item '</a>');
      var 
clickContext = {clickNodeparams.multiple.items.lengthgraphthisalt_graphtrue};
      
addEvent(item'click'this.onClickMenunullclickContext);
      
cur.destroy.push(function() {
        
removeEvent(item'click'this.onClickMenunullclickContext);
      });
      
this.menu.appendChild(item);
    }

    for (
i in params.multiple.altitems) {
      var 
item se('<a class="graph_menu_item' + (params.multiple.altitems.length == params.multiple.def ' graph_menu_item_sel' '') + '">' params.multiple.altitems[i][0] + '</a>');
      var 
clickContext = {clickNodeigraphthisforce_funcparams.multiple.altitems[i][1] };
      
addEvent(item'click'this.onClickMenunullclickContext);
      
cur.destroy.push(function() {
        
removeEvent(item'click'this.onClickMenunullclickContext);
      });
      
this.menu.appendChild(item);
    }
    
defaultGraph params.multiple.def;
    
params.multiple 1;
  }

  
extend(this, {
    
colMax: [00], lines: [],
    
leftTime: -1rightTime: -1,
    
ymarks: [],
    
ystep0,
    
minValue100maxValue0minTime2147483647maxTime0,
    
dragTime: [],
    
startDrag: -1startDrag2: -1startValue: -1startValue2: -1endValue: -1,
    
dragElementnullmaskDraggingfalseviewClickfalsesmoothLinesfalse,
    
scaleWidth0activeLinenullisNegativefalse});

  try {
    var 
tctx getContext(this.zinView);
    if (!
tctx) throw 'Error';
  } catch (
e) {
    
this.zoutLayout.style.display 'none';
    
this.vScale.style.display 'none';
    
this.title.style.display 'none';
    
this.message = (this.message == null) ? this.zinLayout.children[0] : this.message;
    
this.message.innerHTML = (cur.graphVars['lang.bad_browser'] || 'Для отображения графика статистики Вам необходимо {link}обновить браузер{/link}.').replace('{link}''<a onclick="Graph.prototype.showBadBrowserBox();">').replace('{/link}''</a>');
    
setStyle(this.graphDiv, {backgroundColor'#F7F7F7'width'480px'margin'0 auto'});
    
setStyle(this.message, {
      
leftMath.round((getSize(this.zinLayout)[0] - getSize(this.message)[0]) / 2) + 'px',
      
topMath.round((getSize(this.zinLayout)[1] - getSize(this.message)[1]) / 2) + 'px',
      
display'block',
      
color'#707070',
      
border'none',
      
backgroundColor'transparent'
    
});
    if (!
cur.badBrowserBox) {
      
this.showBadBrowserBox();
    }
    return 
null;
  }

  if (
vk.al) {
    
stManager.add(['tooltips.js''tooltips.css'], function() {
      
tooltips.create(graph.mainLayout, {text'...'black1forcetoup1nohide1});
    });
  } else {
    
tooltips false;
  }

  if (!
params.bar_chart) {
    
addEventEx(thisthis.lHandle'mousedown touchstart'this.takeHandle);      // resize window
    
addEventEx(thisthis.rHandle'mousedown touchstart'this.takeHandle);
    
addEventEx(thisthis.zoutWindow'mousedown touchstart'this.takeWindow);      // drag window
    
addEventEx(thisthis.lMask'mousedown touchstart'this.takeMask);        // select new window
    
addEventEx(thisthis.rMask'mousedown touchstart'this.takeMask);
    
addEventEx(thisthis.zinLayout'mousedown touchstart'this.takeView);      // drag view
    
addEventEx(thisthis.zinLayout'mousewheel DOMMouseScroll'this.wheelView);    // zoom with mousewheel
    
addEventEx(thisthis.zoutLayout'mousewheel DOMMouseScroll'this.wheelView);
  }
  
addEventEx(thisthis.dotsLayer'mousemove'this.showDots);              // show hints
  
addEventEx(thisthis.zinLayout'mouseout'this.hideDots);            // hide hints
  
addEvent(this.column[0], 'selectionstart'cancelEvent);
  
addEvent(this.column[1], 'selectionstart'cancelEvent);

  if (
typeof(data) != 'string') {
    
graph.loadGraph = function(index) {
      
graph.setData(params.multiple ? (data[index] || []) : dataisArray(params.adjust) ? params.adjust[index] : params.adjust);
    }
  }

  if (
params.multiple) {
    for (var 
0data.lengthi++) {
      
data[i] = dataObjectToArray(data[i]);
    }

    
graph.setData((typeof(data) == 'string') ? data : (data[defaultGraph] || []), isArray(params.adjust) ? params.adjust[0] : params.adjust);
  } else {
    
graph.setData((typeof(data) == 'string') ? data dataObjectToArray(data), params.adjust);
  }
  return 
graph;
}

// Prototype methods
Graph.prototype = {
  
getXValue: function(pageXview) {
    return (
view ?
      ((
pageX getXY(this.zinView)[0]) / this.xfactorIn this.leftTime) :
      ((
pageX getXY(this.zoutView)[0]) / this.xfactorOut this.minTime));
  },
  
allowZoom: function(zoom_allowed) {
    
this.zoutLayout.style.display zoom_allowed 'block' 'none';
    
this.viewHeight this.height - (zoom_allowed 80 40);
    
this.zinLayout.style.height this.viewHeight "px";
    
this.zinView.height this.viewHeight;
    
this.dotsLayer.height this.viewHeight 17;
    
this.disable_zoom = !zoom_allowed;
  },
  
showEmpty: function(no_data) {
    if (
no_datathis.allowZoom(false);
    
setStyle(this.message, {
      
displayno_data 'block' 'none',
      
leftMath.round((this.viewWidth getSize(this.message)[0]) / 2) + 'px',
      
topMath.round((this.viewHeight getSize(this.message)[1]) / 2) + 'px'});
  },
  
overrideCursor: function(cursor) {
    
document.body.style.cursor cursor cursor 'default';
    
//document.body.style.cursor = cursor ? cursor : 'auto'; // Opera don't understand 'auto'
    
this.lHandle.style.cursor cursor cursor 'w-resize';
    
this.rHandle.style.cursor cursor cursor 'e-resize';
    
this.zoutWindow.style.cursor cursor cursor DRAG_CURSOR;
  },
  
takeHandle: function(ev) {
    var 
ev.currentTarget.graph;
    if (
g.disable_zoom) return;
    if (!(
ev prepareEvent(ev))) return;
    
addEventEx(gdocument'mousemove drag touchmove'g.dragHandle);
    
addEventEx(gdocument'mouseup touchend'g.endDrag);
    
g.startDrag ev.pageX;
    
g.startValue = (ev.currentTarget == g.lHandle) ? g.leftTime g.rightTime;
    
g.dragElement ev.currentTarget;
    
g.hideDots(ev);
    
g.overrideCursor(g.dragElement.style.cursor);
    return 
false;
  },
  
takeWindow: function(ev) {
    var 
ev.currentTarget.graph;
    if (
g.disable_zoom) return;
    if (!(
ev prepareEvent(evtrue))) return;
    
addEventEx(gdocument'mousemove drag touchmove'g.dragWindow);
    
addEventEx(gdocument'mouseup touchend'g.endDrag);
    
g.startDrag ev.pageX;
    
g.startValue g.leftTime;
    
g.hideDots(ev);
    
g.overrideCursor(DRAG2_CURSOR);
    return 
false;
  },
  
takeMask: function(ev) {
    
cancelEvent(ev);
    var 
ev.currentTarget.graph;
    if (
g.disable_zoom) return;
    
g.dragElement ev.currentTarget;
    if (!(
ev prepareEvent(ev))) return;
    
addEventEx(gdocument'mousemove drag touchmove'g.dragMask);
    
addEventEx(gdocument'mouseup touchend'g.endDrag);
    
g.startValue = (ev.pageX getXY(g.dragElement.parentNode)[0]) / g.xfactorOut g.minTime;
    
g.endValue g.startValue;
    
g.hideDots(ev);
    return 
false;
  },
  
takeView: function(ev) {
    var 
ev.currentTarget.graph;
    if (
g.disable_zoom) {
      
g.deselectLine(ev);
      return;
    }
    if (!(
ev prepareEvent(evtrue))) return;
    
g.dragTime[0] = g.getXValue(ev.pageXtrue);
    
addEventEx(gdocument'mousemove drag touchmove'g.dragView);
    
addEventEx(gdocument'mouseup touchend'g.endDrag);
    
g.overrideCursor(DRAG2_CURSOR);
    
g.viewClick true;
    
g.startDrag ev.pageX;
    
g.showDots(ev);
    
//return false;
  
},
  
dragHandle: function(ev) {
    var 
ev.currentTarget.graph;
    if (!(
ev prepareEvent(ev))) return;
    var 
xfactorOut g.viewWidth / (g.maxTime g.minTime);
    if (
g.dragElement == g.lHandle) {
      
g.leftTime Math.max(g.minTimeMath.min(g.rightTime g.MAXSCALEg.startValue - (g.startDrag ev.pageX) / xfactorOut));
    } else {
      
g.rightTime Math.min(g.maxTimeMath.max(g.leftTime g.MAXSCALEg.startValue - (g.startDrag ev.pageX) / xfactorOut));
    }
    
g.redrawWindow();
    return 
false;
  },
  
dragWindow: function(ev) {
    var 
ev.currentTarget.graph;
    if (!(
ev prepareEvent(ev))) return;
    var 
xfactorOut g.viewWidth / (g.maxTime g.minTime),
    
diff g.leftTime - (g.startValue - (g.startDrag ev.pageX) / xfactorOut);
    
diff Math.max(diffg.rightTime g.maxTime);
    
diff Math.min(diffg.leftTime g.minTime);

    
g.leftTime -= diff;
    
g.rightTime -= diff;
    
g.redrawWindow();
    return 
false;
  },
  
dragMask: function(ev) {
    var 
ev.currentTarget.graph;
    if (!(
ev prepareEvent(ev))) return;
    var 
xfactorOut g.viewWidth / (g.maxTime g.minTime);
    
g.endValue = (ev.pageX getXY(g.dragElement.parentNode)[0]) / xfactorOut g.minTime;
    var 
lpos = (Math.max(g.minTimeMath.min(g.startValueg.endValue)) - g.minTime) * xfactorOut,
      
rpos = (Math.min(g.maxTimeMath.max(g.startValueg.endValue)) - g.minTime) * xfactorOut;
    if (!
g.maskDragging && (rpos lpos 4)) {
      
g.select.style.display 'block';
      
g.maskDragging true;
    }
    
g.select.style.left lpos "px";
    
g.select.style.width = (rpos lpos 2) + "px";

    return 
false;
  },
  
dragView: function(ev) {
    var 
ev.currentTarget.graph;
    if (!(
ev prepareEvent(evg.viewClick))) return;
    var 
diff = (ev.pageX getXY(g.zoutView)[0]) / g.xfactorIn g.leftTime g.dragTime[0];
    
diff Math.max(diffg.rightTime g.maxTime);
    
diff Math.min(diffg.leftTime g.minTime);
    
g.leftTime -= diff;
    
g.rightTime -= diff;

    if (
Math.abs(ev.pageX g.startDrag) > 4)
      
g.viewClick false;
    
g.redrawWindow();
    
g.showDots(ev);
    return 
g.viewClick;
  },
  
endDrag: function(ev) {
    var 
this;
    if (
ev) {
      
cancelEvent(ev);
      
ev.currentTarget.graph;
    }
    
removeEventEx(document'mousemove drag touchmove'g.dragHandle);
    
removeEventEx(document'mousemove drag touchmove'g.dragWindow);
    
removeEventEx(document'mousemove drag touchmove'g.dragMask);
    
removeEventEx(document'mousemove drag touchmove'g.dragView);
    
removeEventEx(document'mouseup touchend'g.endDrag);
    
g.select.style.display 'none';
    
g.overrideCursor();
    if (
g.endValue != -1) {
      if (
g.maskDragging) {
        
g.leftTime Math.min(g.startValueg.endValue);
        
g.rightTime Math.min(g.maxTimeMath.max(Math.max(g.startValueg.endValue), g.leftTime g.MAXSCALE));
        
g.leftTime Math.max(g.minTimeMath.min(g.leftTimeg.rightTime g.MAXSCALE));
      } else {
        var 
diff = (g.rightTime g.leftTime) / 2.0;
        
g.leftTime = (g.endValue diff);
        
g.rightTime = (g.endValue diff);
        if (
g.leftTime g.minTime) {
          
diff g.minTime g.leftTime;
          
g.leftTime += diff;
          
g.rightTime += diff;
        } else
        if (
g.rightTime g.maxTime) {
          
diff g.rightTime g.maxTime;
          
g.leftTime -= diff;
          
g.rightTime -= diff;
        }
      }
    }
    if (
g.viewClick)
      
g.deselectLine(ev);
    else
      
g.redrawWindow();
    
g.endValue = -1;
    
g.maskDragging false;
    
g.viewClick false;
    
g.dragTime = [];
    return 
false;
  },
  
wheelView: function(ev) {
    var 
ev.currentTarget.graph,
      
delta = (ev.detail ? -ev.detail 50 ev.wheelDelta),
      
dist g.rightTime g.leftTimediffL = (delta dist) / 3500diffR;
    if (
g.disable_zoom) return;
      if (
g.lines.length == 0) return;
    
diffL Math.min(diffL, (dist g.MAXSCALE) / 2);
    
diffR Math.max(g.minTime g.leftTime diffL0);
    
g.leftTime Math.max(g.minTimeg.leftTime diffL);
    
g.rightTime Math.min(g.maxTimeg.rightTime diffR);
    
g.redrawWindow();
    
g.showDots(ev);
    return 
cancelEvent(ev);
  },
  
overLegend: function(ev) {
    var 
line ev.currentTarget.line;
    
drawCheck(line.legendCheckline.hexColorline.hexColor2line.showntrue);
  },
  
outLegend: function(ev) {
    var 
line ev.currentTarget.line;
    
drawCheck(line.legendCheckline.hexColorline.hexColor2line.shownfalse);
  },
  
toggleLegend: function(ev) {
    var 
ev.currentTarget.graphline ev.currentTarget.linenoneShown true;
    for (var 
0g.lines.lengthl++)
      if (
g.lines[l] != line && g.lines[l].shown)
        
noneShown false;
    
line.shown noneShown || !line.shown;
    
drawCheck(line.legendCheckline.hexColorline.hexColor2line.showntrue);
    
g.updateLines();
    
clearSelection();
    return 
cancelEvent(ev);
  },
  
chooseLegend: function(ev) {
    var 
ev.currentTarget.graphline ev.currentTarget.lineonlyThis line.shown;
    if (
onlyThis)
      for (var 
0g.lines.lengthl++)
        if (
g.lines[l] != line && g.lines[l].shown) {
          
onlyThis false;
          break;
        }

    for (var 
0g.lines.lengthl++) {
      
g.lines[l].shown onlyThis || (g.lines[l] == line);
      
drawCheck(g.lines[l].legendCheckg.lines[l].hexColorg.lines[l].hexColor2g.lines[l].showng.lines[l] == line);
    }
    
g.updateLines();
    
clearSelection();
    return 
cancelEvent(ev);
  },
  
showDots: function(ev) {
    var 
= ((ev && ev.currentTarget) ? ev.currentTarget.graph this);
    if (
g.params.bar_chart) {
      
g.highlightBar(ev);
      return;
    }
    var 
nearTime = -1nnd 0cx g.getXValue(ev.pageXtrue);
    var 
ccx ev.pageX getXY(g.zinView)[0], ccy ev.pageY getXY(g.zinView)[1];
    var 
max_coltext = [00];
    var 
activeLine = -1;
    var 
ctx getContext(g.dotsLayer);
    
ctx.clearRect(00g.viewWidthg.viewHeight);

    for (var 
0g.lines.lengthl++) {
      var 
ni = -1nd 0;
      if (
g.lines[l].shown) {
        for (var 
g.lines[l].stIdx<= g.lines[l].enIdxi++)
          if (
g.lines[l].d[i].>= g.leftTime && g.lines[l].d[i].<= g.rightTime && (ni == -|| nd Math.abs(g.lines[l].d[i].cx))) {
            
ni i;
            
nd Math.abs(g.lines[l].d[i].cx);
          }
      }
      if (
ni > -1) {
        var 
dot g.lines[l].d[ni],
            
dotX = (dot.g.leftTime) * g.xfactorIn,
            
dotY g.viewHeight - (g.isNegative ? (34 + (dot.g.localBottom) * g.yfactorIn) : (25 + (dot.- (g.adjust g.localBottom 0)) * g.yfactorIn));
        
g.lines[l].dot.posX dotX;
        
g.lines[l].dot.posY dotY;
        if (
ccx >= dotX && ccx <= dotX &&
            
ccy >= dotY && ccy <= dotY 9) {
          
activeLine l;
        }
        if (
nearTime == -|| nd nnd) {
          
nnd nd;
          
nearTime g.lines[l].d[ni].x;
        }

        
ctx.fillStyle g.lines[l].hexColor;
        
ctx.beginPath();
        
ctx.arc(dotXdotY30Math.PI*2true);
        
ctx.fill();

        if (!
isVisible(g.lines[l].dotLabel) || !g.lines[l].dotLabel.dot || g.lines[l].dotLabel.dot.!= dot.|| parseInt(g.lines[l].dot.style.left) != Math.floor(dotX)) {
          
g.lines[l].dotLabel.innerHTML dot.dot.formatValue(dot.y) + g.params.yunits;
          var 
labelW getSize(g.lines[l].dotLabel)[0];
          var 
pos Math.max(Math.min(-labelW 2.0, -labelW g.viewWidth dotX 2), dotX);
          
g.lines[l].dotLabel.dot dot;
          
g.lines[l].dotLabel.pos Math.floor(pos);
          
g.lines[l].dotLabel.labelW;

          
setStyle(g.lines[l].dot, {
            
leftMath.floor(dotX) + "px",
            
topMath.floor(dotY) + "px"});
          
setStyle(g.lines[l].dotLabel, {
            
top: ((g.lines[l].dot.posY 26) ? -26 6) + "px",
            
leftg.lines[l].dotLabel.pos "px"});
        }

        
g.lines[l].legendBox.innerHTML formatValue(dot.y) + g.params.yunits;
        
g.lines[l].legendBox.style.display 'block';
      } else {
        
g.lines[l].legendBox.style.display 'none';
      }
      if (
g.lines[l].legendBox.style.left == '40px') { // label position fix in legend
        
var col g.lines.length 1;
        
max_coltext[col] = Math.max(max_coltext[col], getSize(g.lines[l].legend.children[1])[0]);
      }
    }
    if (!
g.smoothLines || !tooltips) {
      
activeLine = -1;
    }
    for (var 
0g.lines.lengthl++) {
      if (!
g.lines[l].shown) {
        
hide(g.lines[l].dot);
        continue;
      }
      if (
activeLine == l) {
        
g.showDotTT(l);
      } else if (
activeLine == -1) {
        if (
g.activeLine == null || g.activeLine == g.lines[l]) {
          
show(g.lines[l].dot);
        } else {
          
hide(g.lines[l].dot);
        }
      } else {
        
hide(g.lines[l].dot);
      }
    }

    if (
max_coltext[0] || max_coltext[1]) {
      for (var 
0g.lines.lengthl++) {
        var 
col g.lines.length 1;
        if (
max_coltext[col]) {
          
g.lines[l].legendBox.style.left = (max_coltext[col] + 40) + 'px';
        }
      }
    }
    if (
activeLine == -&& tooltips) {
      
tooltips.hide(g.mainLayout, {fasthide1});
    }
    if (
nearTime > -&& isVisible(g.title))
      
g.title.innerHTML fullDate(nearTimeg.params);
  },
  
hideDots: function(ev) {
    var 
= (ev.currentTarget ev.currentTarget.graph this), vwPos getXY(g.zinView);
    if (
ev.pageX >= vwPos[0] && ev.pageX vwPos[0] + g.viewWidth && ev.pageY >= vwPos[1] && ev.pageY vwPos[1] + g.viewHeight) return;

    for (var 
0g.lines.lengthl++) {
      
hide(g.lines[l].dot);
      if(
g.lines[l].sum) {
        
g.lines[l].legendBox.innerHTML formatValue(g.lines[l].sum) + g.params.yunits;
      } else {
        
hide(g.lines[l].legendBox);
      }
    }
    var 
ctx getContext(g.dotsLayer);
    
ctx.clearRect(00g.viewWidthg.viewHeight);
    
g.title.innerHTML fullDate(g.localLeft) + (g.localRight g.localLeft ' &ndash; ' fullDate(g.localRight) : '');
    if (
tooltips) {
      
tooltips.hide(g.mainLayout, {fasthide1});
    }
  },
  
highlightBar: function(ev) {
    var 
= ((ev && ev.currentTarget) ? ev.currentTarget.graph this);
    var 
cx = (ev.pageX getXY(g.zinView)[0]);
    var 
cy = (ev.pageY getXY(g.zinView)[1]);
    var 
ctx getContext(g.dotsLayer);
    
ctx.clearRect(00g.viewWidthg.viewHeight);

    var 
activeLine activeBar = -1;
    for (var 
0g.lines.lengthl++) {
      for (var 
0g.lines[l].d.lengthi++) {
        var 
nx getBarXValue(0g.xstepg.barsWidthlg.lines[l].d[i].x);
        var 
ny g.viewHeight - (g.isNegative ? (34 + (g.lines[l].d[i].g.localBottom) * g.yfactorIn) : (25 + (g.lines[l].d[i].- (g.adjust g.localBottom 0)) * g.yfactorIn));
        if (
cx nx && cx <= nx g.barsWidth && cy >= ny) {
          
activeLine l;
          
activeBar i;
          break;
        }
      }
    }
    for (var 
0g.lines.lengthl++) {
      if (
activeBar > -1) {
        var 
dot g.lines[l].d[activeBar],
            
dotX getBarXValue(0g.xstepg.barsWidthldot.x),
            
dotY g.viewHeight - (g.isNegative ? (34 + (dot.g.localBottom) * g.yfactorIn) : (25 + (dot.- (g.adjust g.localBottom 0)) * g.yfactorIn)),
            
val formatValue(dot.y) + g.params.yunits;

        if (
activeLine == l) {
          
ctx.fillStyle g.lines[l].hexColor3;
          
ctx.fillRect(dotXdotYg.barsWidthg.viewHeight);

          
g.showTT(dotXdotYdot.dot.val '<br>' g.lines[l].name ', ' this.params.bar_chart[activeBar]);
          
g.lines[l].legendBox.style.display 'block';
          
g.lines[l].legendBox.innerHTML val;
        } else {
          
g.lines[l].legendBox.style.display 'block';
          
g.lines[l].legendBox.innerHTML val;
        }
      } else if(
g.lines[l].sum) {
        
g.lines[l].legendBox.innerHTML formatValue(g.lines[l].sum) + g.params.yunits;
      } else {
        
g.lines[l].legendBox.style.display 'none';
      }
    }
    if (
activeBar == -&& tooltips) {
      
tooltips.hide(g.mainLayout, {fasthide1});
    }
  },
  
expandLabel: function(ev) {
    var 
ev.currentTarget.graphline ev.currentTarget.linedot line.dotLabel.dotpos line.dotLabel.pos;
    if (!
g.smoothLines) {
      var 
text '';
      if (
line.l) {
        
text += langNumeric(dot.yline.ltrue);
      } else {
        
text += (dot.dot.formatValue(dot.y)) + ' ' line.name;
      }
      
line.dotLabel.innerHTML text;
      var 
sz getSize(line.dotLabel)[0];
      if (
pos sz line.dot.posX g.viewWidth) {
        
line.dotLabel.innerHTML line.name ' ' + (dot.dot.formatValue(dot.y));
        
line.dotLabel.style.left pos - (sz line.dotLabel.w) + "px";
      } else
        
line.dotLabel.style.left pos "px";

      for (var 
0g.lines.lengthl++)
        
g.lines[l].dotLabel.style.zIndex = (g.lines[l] == line) ? 1000 200;
    }
    return 
cancelEvent(ev);
  },
  
chideLabel: function(ev) {
    var 
ev.currentTarget.graphline ev.currentTarget.line,
      
locX ev.pageX - (getXY(line.dot)[0] + line.dotLabel.pos);
    if (
locX || locX line.dotLabel.w)
      
g.hideLabel(ev);
  },
  
hideLabel: function(ev) {
    var 
ev.currentTarget.graphline ev.currentTarget.linedot line.dotLabel.dotpos line.dotLabel.pos;
    
line.dotLabel.innerHTML dot.dot.formatValue(dot.y);
    
line.dotLabel.style.left pos "px";
  },
  
selectLine: function(ev) {
    var 
ev.currentTarget.graphline ev.currentTarget.line;
    
g.activeLine line;
    
g.redrawWindow();
    
g.showDots(ev);
    return 
cancelEvent(ev);
  },
  
deselectLine: function(ev) {
    
this.activeLine null;
    
this.redrawWindow();
    
this.showDots(ev);
    return 
cancelEvent(ev);
  },
  
showDotTT: function(lineIndex) {
    if (!
this.smoothLines) {
      return;
    }
    if (
this.ttLine != lineIndex) {
      
tooltips.hide(this.mainLayout, {fasthide1});
    }

    var 
line this.lines[lineIndex], dot line.dotLabel.dot;
    var 
text '';
    if (
line.l) {
      
text += langNumeric(dot.yline.ltrue);
    } else {
      
text += (dot.dot.formatValue(dot.y)) + ' &ndash; ' line.name;
    }
    
text += '<br/><span style="font-weight: normal; font-size: 0.9em;">' fullDate(dot.xthis.params) + '</span>';

    for (var 
0this.lines.lengthl++) {
      
hide(this.lines[l].dot);
    }
    
this.showTT(line.dot.posX 1line.dot.posY 5text);
    
this.ttLine lineIndex;

    var 
ctx getContext(this.dotsLayer);
    
ctx.strokeStyle line.hexColor;
    
ctx.globalAlpha 0.3;
    
ctx.lineWidth 4;
    
ctx.beginPath();
    
ctx.arc(line.dot.posXline.dot.posY6.50Math.PI*2true);
    
ctx.stroke();
    
ctx.globalAlpha 1;
  },
  
showTT: function(dotXdotYtext) {
    var 
xy getXY(this.zinLayout);
    
xy[0] += dotX + (this.params.bar_chart this.barsWidth 0);
    
xy[1] += dotY;
    
xy[0] = Math.floor(xy[0]); xy[1] = Math.floor(xy[1]);
    if (
this.mainLayout.tt && this.mainLayout.tt.container && (!isVisible(this.mainLayout.tt.container) || !this.dotLabelXY || this.dotLabelXY[0] != xy[0])) {
      
geByClass1('tt_text'this.mainLayout.tt.container).innerHTML text;
      
tooltips.hide(this.mainLayout, {fasthide1});
      
tooltips.show(this.mainLayout, {forcexyxy});
      
this.dotLabelXY xy;
    }
  },
  
onClickMenu: function(ev) {
    var 
ev.data.graph;
    for (var 
i in g.menu.children) {
      if (
g.menu.children[i].nodeType != 1) continue;

      if (
== ev.data.clickNode) {
        
addClass(g.menu.children[i], 'graph_menu_item_sel');
        if (!
ev.data.alt_graph) {
          
g.loadGraph(i);
          if (
isVisible(g.graphDiv.id.replace(/_graph$/, '') + '_alt_graph')) {
            
hide(g.graphDiv.id.replace(/_graph$/, '') + '_alt_graph');
            for (
i in g.mainLayout.children) {
              if (
g.mainLayout.children[i].nodeType == && g.mainLayout.children[i].mh) {
                
show(g.mainLayout.children[i]);
              }
            }
            
g.mainLayout.style.width g.viewWidth "px";
            
show(g.vScale);
          }
        } else {
          
hide(g.vScale);
          for (
i in g.mainLayout.children) {
            if (
g.mainLayout.children[i].nodeType != || g.mainLayout.children[i] == g.menu || !isVisible(g.mainLayout.children[i])) continue;
            
g.mainLayout.children[i].mh 1;
            
hide(g.mainLayout.children[i]);
          }
          
g.mainLayout.style.width g.viewWidth g.scaleWidth "px";
          
show(g.graphDiv.id.replace(/_graph$/, '') + '_alt_graph');
        }
      } else {
        
removeClass(g.menu.children[i], 'graph_menu_item_sel');
      }
    }
    
cancelEvent(ev);
  },

  
// some lines were shown or hidden
  
updateLines: function() {
    
this.redrawWindow();
    
// redraw zoutView
    
var ctx getContext(this.zoutView);
    
ctx.clearRect(00this.viewWidth40);
    if (
this.isNegative)
      
drawLines(ctx04this.viewWidth32this.linesthis.minTimethis.maxTimethis.xfactorOutthis.yfactorOut, -this.localBottomtruenullfalse);
    else
      
drawLines(ctx04this.viewWidth36this.linesthis.minTimethis.maxTimethis.xfactorOutthis.yfactorOut0truenullfalse);
  },
  
// window borders were moved
  
redrawWindow: function() {
    
// move window
    
this.xfactorOut this.viewWidth / (this.maxTime this.minTime);
    
this.xfactorIn this.viewWidth / (this.rightTime this.leftTime);
    var 
leftOut Math.round((this.leftTime this.minTime) * this.xfactorOut),
      
rightOut Math.round((this.rightTime this.minTime) * this.xfactorOut) - 1;
    
leftOut Math.min(leftOutthis.viewWidth 4);
    
rightOut Math.max(leftOut 1rightOut);

    
setStyle(this.lMask, {
      
widthleftOut "px",
      
display: (leftOut "block" "none")});
    
setStyle(this.zoutWindow, {
      
leftleftOut "px",
      
width: (rightOut leftOut 1) + "px"});
    
setStyle(this.rMask, {
      
left: (rightOut 1) + "px",
      
width: (this.viewWidth rightOut 2) + "px",
      
display: (this.viewWidth rightOut "block" "none")});

    
this.lHandle.style.left Math.max(0leftOut 4) + "px";
    
this.rHandle.style.left Math.min(this.viewWidth 8rightOut 4) + "px";

    
// get visible data
    
var localMax = (this.adjust ? -1e9 0), localMin = (this.adjust 1e9 0), outMax 0outMin 0dotsVisible 0;
    
this.localLeft this.rightTime;
    
this.localRight this.leftTime;
    for (var 
0this.lines.lengthl++) {
      var 
line this.lines[l];
      if (
line.shown) {
        var 
stIdx 0enIdx line.d.length 1ps line.d;
        while ((
stIdx ps.length 1) && (ps[stIdx 1].this.leftTime)) stIdx++;
        while ((
enIdx 1) && (ps[enIdx 1].this.rightTime)) enIdx--;
        
line.stIdx stIdx;
        
line.enIdx enIdx;
        if (
enIdx >= stIdx && (ps[enIdx].>= this.leftTime) && (ps[stIdx].<= this.rightTime)) {
          for (var 
stIdx<= enIdxi++) {
            
localMax Math.max(localMaxps[i].y);
            
localMin Math.min(localMinps[i].y);
            
this.localLeft Math.min(this.localLeftps[i].x);
            
this.localRight Math.max(this.localRightps[i].x);
          }
          
dotsVisible Math.max(dotsVisibleenIdx stIdx);
        }

        
outMax Math.max(outMaxline.maxValue);
        
outMin Math.min(outMaxline.minValue);
      }
    }

    if (
this.lines.length == || (localMax localMin 1e-6)) {
      
this.isNegative false;
      
this.ystep 1;
      
this.localTop 5;
      
this.localBottom 0;
    } else {
      
this.isNegative = (localMin < -1e-6);
      
this.ystep Math.max(getYStep(localMax - (this.adjust localMin 0), this.params.int_scale), this.isNegative getYStep(-localMinthis.params.int_scale) : 1e-6);
      
this.localTop = (Math.ceil(localMax this.ystep)) * this.ystep;
      
this.localBottom = -(Math.ceil(- localMin this.ystep)) * this.ystep;
    }
    
this.yfactorIn = (this.viewHeight - (this.isNegative 43 34)) / (this.localTop this.localBottom);
    
this.yfactorOut this.minValue < -1e-6 ? (32 / (outMax outMin)): (36 outMax);
    
this.smoothLines dotsVisible 30 true false;

    
// update title
    
this.title.innerHTML fullDate(this.localLeft) + (this.localRight this.localLeft ' &ndash; ' fullDate(this.localRight) : '');

    
// redraw zinView
    
var ctx getContext(this.zinView), ctxS getContext(this.vScaleView);
    
ctx.clearRect(00this.viewWidththis.viewHeight);
    
ctx.fillStyle '#fafafa';
    
ctx.fillRect(09this.viewWidththis.viewHeight 9);
    
ctxS.clearRect(00this.scaleWidththis.viewHeight);

    
// y scale
    
ctx.lineWidth 1;
    
ctx.strokeStyle '#e6eaf0';
    
ctxS.font '11px tahoma, arial, verdana, sans-serif, Lucida Sans';
    
ctxS.fillStyle '#36638e';
    
ctxS.textAlign 'right';
    
ctxS.textBaseline 'middle';
    for (var 
gridY this.localBottomgridY this.localTop this.ystepgridY += this.ystep) {
      var 
cy this.viewHeight 24.5 Math.round((gridY this.localBottom) * this.yfactorIn) - (this.isNegative 0);
      if (
gridY this.localTop) {
        
ctx.strokeStyle = (this.isNegative && Math.abs(gridY) < 1e-8) ? '#9fb1c4' '#e6eaf0';
        
ctx.beginPath();
        
ctx.moveTo(0cy);
        
ctx.lineTo(this.viewWidthcy);
        
ctx.stroke();
      }
      
ctxS.fillText(formatValue(gridY), this.scaleWidth 6cy);
    }

    
// x scale
    
ctx.fillStyle '#ffffff';
    
ctx.fillRect(0this.viewHeight 25this.viewWidth25);

    
ctx.font '11px tahoma, arial, verdana, sans-serif, Lucida Sans';
    
ctx.fillStyle '#36638e';
    
ctx.textAlign 'center';
    
ctx.textBaseline 'top';

    var 
fin false;
    var 
i_start this.params.show_time || this.params.show_minutes 6;
    for (var 
i_start; (100) && !fini++) {
      if (
xscales.length) {
        var 
sc xscales[i];
      } else {
        var 
yearCnt = [2510][(xscales.length 1) % 3] * Math.pow(10Math.floor((xscales.length 1) / 3));
        var 
sc = {baseyearCnt YEARformat: ['yearFull'], subMath.max(1yearCnt 10) * YEAR};
      }

      var 
baseWidth sc.base this.xfactorIn;
      for (var 
0sc.format.lengthj++) {
        var 
formatWidth ctx.measureText(formatDate(-1sc.format[j])).width;
        if (
formatWidth baseWidth) {
          var 
sTm incDate(this.leftTimesc.base, -2);
          var 
eTm incDate(this.rightTimesc.base2);
          
ctx.strokeStyle '#e6eaf0';
          if (
sc.sub != -1)
            for (var 
tm sTmtm <= eTmtm incDate(tmsc.sub1)) {
              var 
ax Math.floor((tm this.leftTime) * this.xfactorIn) + 0.5;
              
ctx.beginPath();
              
ctx.moveTo(axthis.viewHeight 24);
              
ctx.lineTo(axthis.viewHeight 22);
              
ctx.stroke();
            }
          for (var 
tm sTmtm <= eTmtm incDate(tmsc.base1)) {
            if (
incDate(tmsc.base1) < tm HOUR)
              throw 
"Erroneous date increase";
            var 
ax Math.floor((tm this.leftTime) * this.xfactorIn) + 0.5;
            
//ctx.strokeStyle = '#e6eaf0';
            
ctx.beginPath();
            
ctx.moveTo(ax9);
            
ctx.lineTo(axthis.viewHeight 24);
            
ctx.stroke();
            
//ctx.strokeStyle = '#9fb1c4';
            
ctx.beginPath();
            
ctx.moveTo(axthis.viewHeight 24);
            if (
sc.sub == -1)
              
ctx.lineTo(axthis.viewHeight);
            else
              
ctx.lineTo(axthis.viewHeight 20);
            
ctx.stroke();
            var 
textpos ax;
            if (
sc.sub == -1)
              
textpos += (baseWidth 2.0);
            if (
textpos formatWidth 2.0 && textpos formatWidth 2.0 this.viewWidth)
              
ctx.fillText(replaceEntities(formatDate(tmsc.format[j])), textposthis.viewHeight 19);
          }

          
fin true;
          break;
        }
      }
      if (
fin) break;
    }

    
ctx.strokeStyle '#e6eaf0';
    
ctx.lineWidth 1;
    
ctx.strokeRect(0this.viewHeight 24.5this.viewWidth 126);
    
ctx.strokeStyle '#f0f2f5';
    
ctx.globalAlpha 0.5;
    
ctx.beginPath();
    
ctx.moveTo(1this.viewHeight 25.5);
    
ctx.lineTo(this.viewWidththis.viewHeight 25.5);
    
ctx.stroke();
    
ctx.globalAlpha 1;

    
// graph
    
if (this.isNegative)
      
drawLines(ctx09this.viewWidththis.viewHeight 43this.linesthis.leftTimethis.rightTimethis.xfactorInthis.yfactorIn, -this.localBottomfalsethis.activeLinethis.smoothLines);
    else
      
drawLines(ctx09this.viewWidththis.viewHeight 34this.linesthis.leftTimethis.rightTimethis.xfactorInthis.yfactorInthis.adjust ? -this.localBottom 0falsethis.activeLinethis.smoothLines);

    
ctx.strokeStyle '#b8c5d4';
    
ctx.beginPath();
    
ctx.moveTo(09);
    
ctx.lineTo(0this.viewHeight 0.5);
    if (!
isVisible(this.zoutLayout)) {
      
ctx.lineTo(this.viewWidththis.viewHeight 0.5);
    }
    
ctx.stroke();
  },
  
destroyDots: function(data) {
    for (var 
0this.lines.lengthl++) {
      var 
line this.lines[l];
      
removeEventEx(line.dotLabel'mouseover'this.expandLabel);
      
removeEventEx(line.dotLabel'mousemove'this.chideLabel);
      
removeEventEx(line.dotLabel'mouseout'this.hideLabel);
      
removeEventEx(line.dot'click'this.selectLine);
      
removeEventEx(line.legend'mouseover'this.overLegend);
      
removeEventEx(line.legend'mouseout'this.outLegend);
      
removeEventEx(line.legend'click'this.toggleLegend);
      
removeEventEx(line.legend'dblclick'this.chooseLegend);
      if (
line.dot) {
        
this.zinLayout.removeChild(line.dot);
      }
      if (
line.legend.parentNode) {
        
line.legend.parentNode.removeChild(line.legend);
      }
      
removeData(line.dotLabel);
      
removeData(line.dot);
      
removeData(line.legend);
    }
  },
  
initLoadedData: function(text) {
    var 
_t this;
    
this.message.innerHTML cur.graphVars['lang.data_empty'];
    
setStyle(this.message, {
        
display'none',
        
backgroundColor'#eeeeee',
        
border'1px solid #5f7d9d'});
    try {
      var 
= eval(text);
      
_t.loadGraph = function(index) {
        
_t.setData(d[index] || [], isArray(_t.params.adjust) ? _t.params.adjust[index] : _t.params.adjust);
      }
      
_t.noData = (d.length == || (d.length == && d[0].length == 0));
      
_t.setData(_t.params.multiple d[0] : disArray(_t.params.adjust) ? _t.params.adjust[0] : _t.params.adjust);
    } catch(
e){
      
_t.setData([], false);
    }
  },
  
setData: function(dataadjust) {
    var 
_t this;
    if (
typeof(data) == 'string') {
      
this.zoutLayout.style.display 'none';
      
this.vScale.style.display 'none';
      
this.title.style.display 'none';
      
//this.message.innerHTML = cur.graphVars['lang.loading'];
      
this.message.innerHTML '<img src="/images/progress7.gif" />';
      
setStyle(this.message, {
        
display'block',
        
backgroundColor'transparent',
        
border'none',
        
leftMath.round((this.viewWidth 149) / 2) + 'px',
        
topMath.round((this.viewHeight 8) / 2) + 'px'});
      if (
window.ajax) {
        
ajax.post(data, {html51}, {onDone: function(text) {
          
_t.initLoadedData(text);
        }});
      } else {
        
Ajax.Post({url:data.split('%26').join('&'), query: {html51}, onDone: function(restext) {
          
_t.initLoadedData(text);
        }});
      }
      return;
    }

    if (
this.params.bar_chart) {
      
this.setBarChartData(dataadjust);
      return;
    }

    if (
this.lines.length == data.length) {
      var 
showOverride = [];
      for (var 
0this.lines.lengthl++)
        if (
this.lines[l].name.toLowerCase() != data[l].name.toLowerCase()) {
          
showOverride null;
          break;
        } else
          
showOverride[l] = this.lines[l].shown;
    }

    
// remove old lines
    
this.destroyDots();
    
this.adjust adjust;
    
this.minValue 100;
    
this.maxValue 1;
    
this.minAbsValue 1.0;
    
this.minTime 2147483647;
    
this.maxTime 0;
    
// prepare lines
    
this.lines = [];
    var 
maxDotsCount 0;
    var 
max_coltext = [00];
    var 
dotsVisible 0;

    
this.MAXSCALE DAY HOUR;
    
this.XSTEP DAY;
    for (var 
0data.lengthl++) {
      var 
line extend({atrue}, data[l]);
      if (!
line.|| !line.d.length) {
        continue;
      }
      if (!
line.|| 1) {
        
line.colors[colors.length];
      }
      var 
= (line.0xFF0000) >> 16;
      var 
= (line.0x00FF00) >> 8;
      var 
= (line.0x0000FF);
      
Math.min(255, (>> 2) + 192);
      
Math.min(255, (>> 2) + 192);
      
Math.min(255, (>> 2) + 192);
      
line.c2 = (<< 16) | (<< 8) | (b);
      
line.hexColor line.c.toString(16);
      
line.hexColor '#' '000000'.substr(0line.hexColor.length) + line.hexColor;
      
line.hexColor2 line.c2.toString(16);
      
line.hexColor2 '#' '000000'.substr(0line.hexColor.length) + line.hexColor2;
      
line.minValue 100;
      
line.maxValue 1;

      
// make dot
      
line.dot ce('div', {
        
innerHTML'<div style="color: white;
            -webkit-border-radius: 2px; -khtml-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px;
            background-color: ' 
line.hexColor '; position: absolute; padding: 2px 3px 3px 3px; white-space: nowrap; cursor: default;"></div>'
      
}, {
        
position'absolute',
        
display'none'
      
});
      
line.dotLabel line.dot.children[0];
      
this.zinLayout.appendChild(line.dot);

      
addEventEx(thisline.dotLabel'mouseover'this.expandLabel);
      
addEventEx(thisline.dotLabel'mousemove'this.chideLabel);
      
addEventEx(thisline.dotLabel'mouseout'this.hideLabel);
      
addEventEx(thisline.dotLabel'mousedown'cancelEvent);
      
//addEventEx(this, line.dotLabel, 'click', this.selectLine);
      //addEventEx(this, line.dot, 'click', this.selectLine);
      
line.dotLabel.line line;
      
line.dot.line line;

      
// make legend
      
var col_width Math.floor(this.viewWidth 2);

      
line.legend ce('div', {
        
innerHTML'<canvas width="20" height="20" style="vertical-align: middle; padding-right: 2px;"></canvas>' +
          
'<span>' + ((line.name.length >= 30) ? line.name.substr(027) + '...' line.name)  + '</span>' +
          
'<div style="position: absolute; top: 0px; left: 0px; padding: 2px 3px; white-space: nowrap; display: none; background: ' line.hexColor '; color: white; -webkit-border-radius: 2px; -khtml-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px;"></div>'
      
}, {
        
colorline.hexColor,
        
position'relative',
        
cursor'pointer'
      
});
      
line.shown showOverride showOverride[l] : line.a;
      
line.legendCheck line.legend.children[0];
      
drawCheck(line.legendCheckline.hexColorline.hexColor2line.shownfalse);
      
line.legendBox line.legend.children[2];
      
addEventEx(thisline.legend'mouseover'this.overLegend);
      
addEventEx(thisline.legend'mouseout'this.outLegend);
      
addEventEx(thisline.legend'click'this.toggleLegend);
      
addEventEx(thisline.legend'dblclick'this.chooseLegend);
      
line.legend.line line;

      for (var 
0line.d.lengthi++) {
        
line.d[i].parseInt(line.d[i].|| line.d[i]["0"] || DEF_TIME);
        
line.d[i].parseFloat(line.d[i].|| line.d[i]["1"] || 0);
        
line.d[i].line.d[i].|| line.d[i]["2"] || null;
        
line.d[i].line.d[i].|| line.d[i]["3"] || null;
        
line.maxValue Math.max(line.maxValueline.d[i].y);
        
line.minValue Math.min(line.minValueline.d[i].y);
        
this.maxValue Math.max(this.maxValueline.d[i].y);
        
this.minValue Math.min(this.minValueline.d[i].y);
        
this.minAbsValue Math.min(this.minAbsValueMath.abs(line.d[i].y));
        
this.maxTime Math.max(this.maxTimeline.d[i].x);
        
this.minTime Math.min(this.minTimeline.d[i].x);
        if (
&& Math.abs(line.d[i].line.d[1].x) > 1) {
          
this.MAXSCALE Math.min(this.MAXSCALE2.5 Math.abs(line.d[i].line.d[1].x));
          
this.XSTEP = (this.XSTEP Math.abs(line.d[i].line.d[1].x)) / 2;
        }
        if (
this.leftTime != -&& line.d[i].>= this.leftTime && line.d[i].<= this.rightTime) {
          
dotsVisible++;
        }
      }
      
maxDotsCount Math.max(maxDotsCountline.d.length);

      
// probably not needed
      
line.d.sort(function(l1l2) {
        return (
l1.l2.x);
      });
      
this.lines.push(line);
    }
    for (var 
0this.lines.lengthi++) {
      var 
line this.lines[i];
      if (
this.lines.length 2) {
        
this.column[0].appendChild(line.legend);
        
max_coltext[0] = Math.max(max_coltext[0], getSize(line.legend.children[1])[0]);
      } else {
        
this.column[1].appendChild(line.legend);
        
max_coltext[1] = Math.max(max_coltext[1], getSize(line.legend.children[1])[0]);
      }
    }
    for (var 
0this.lines.lengthi++) {
      if (
this.lines.length 2) {
        
this.lines[i].legendBox.style.left = (max_coltext[0] + 40) + 'px';
      } else {
        
this.lines[i].legendBox.style.left = (max_coltext[1] + 40) + 'px';
      }
    }

    var 
noData this.noData || (this.lines.length == && !this.params.multiple);

    
this.zoutLayout.style.display noData 'none' 'block';
    
this.vScale.style.display noData 'none' 'block';;
    
this.title.style.display noData 'none' 'block';

    if (
this.lines.length == 0) {
      
this.maxTime incDate(DEF_TIMEDAY0);
      
this.minTime this.maxTime DAY;
    } else {
      
this.maxTime += this.XSTEP 5;
    }
    if (
this.params.no_zoom) {
      
this.leftTime this.minTime;
      
this.rightTime this.maxTime;
      
this.allowZoom(false);
    } else {
      if (
this.maxTime this.minTime DAY && maxDotsCount 10) {
        
this.minTime -= DAY;
        
this.maxTime += DAY;
        
this.allowZoom(false);
      } else {
        
this.allowZoom(true);
      }
      
this.showEmpty(noData);

      if (
this.leftTime == -|| dotsVisible 10) {
        var 
st 10 DAY;
        if (
this.XSTEP MONTH) {
          
st YEAR;
        } else if (
this.XSTEP 10 DAY) {
          
st MONTH;
        }
        
this.leftTime = (this.params.show_all || maxDotsCount 10) ? this.minTime Math.max(this.minTimethis.maxTime st);
        
this.rightTime this.maxTime;
      } else {
        
this.leftTime Math.max(this.minTimeMath.min(this.maxTimethis.leftTime));
        
this.rightTime Math.max(this.minTimeMath.min(this.maxTimethis.rightTime));
      }
    }

    var 
ctx getContext(this.vScaleView);
    
ctx.font '11px tahoma, arial, verdana, sans-serif, Lucida Sans';
    var 
maxWidth Math.max(
      
ctx.measureText(formatValue(this.maxValue getYStep(this.maxValuethis.params.int_scale))).width,
      
Math.max(  ctx.measureText(formatValue(getYStep(this.minAbsValuethis.params.int_scale))).width,
            
ctx.measureText(formatValue(this.minValue)).width));
    
this.scaleWidth = (this.lines.length == 0) ? : (maxWidth 25);
    
this.scaleWidth Math.floor(this.scaleWidth);
    
this.vScale.style.width this.scaleWidth "px";
    
this.vScale.style.height this.height "px";
    
this.vScaleView.width this.scaleWidth;
    
this.vScaleView.height this.height;
    
this.viewWidth = (this.width this.scaleWidth);

    
this.mainLayout.style.width this.viewWidth "px";
    
this.zinView.width this.viewWidth;
    
this.dotsLayer.width this.viewWidth;
    
this.zoutView.width this.viewWidth;
    
this.column[0].style.width Math.floor(this.viewWidth 2) + "px";
    
this.column[1].style.width Math.floor(this.viewWidth 2) + "px";

    
this.activeLine null;

    
this.updateLines();
  },
  
setBarChartData: function(dataadjust) {
    
// remove old lines
    
this.destroyDots();
    
this.adjust adjust;
    
this.minValue 100;
    
this.maxValue 1;
    
this.minAbsValue 1.0;
    
// prepare lines
    
this.lines = [];
    var 
max_coltext = [00];

    for (var 
0data.lengthl++) {
      var 
line extend({atrue}, data[l]);
      if (!
line.|| !line.d.length) {
        continue;
      }
      if (!
line.c) {
        var 
colors_row 4;
        
colors_row colors_row == colors_row;
        
line.colors[(colors_row Math.floor(4)) % colors.length];
      }
      var 
= (line.0xFF0000) >> 16;
      var 
= (line.0x00FF00) >> 8;
      var 
= (line.0x0000FF);
      
r2 Math.min(255, (>> 2) + 192);
      
g2 Math.min(255, (>> 2) + 192);
      
b2 Math.min(255, (>> 2) + 192);
      
line.c2 = (r2 << 16) | (g2 << 8) | (b2);
      
r3 Math.min(25516);
      
g3 Math.min(25516);
      
b3 Math.min(25516);
      
line.c3 = (r3 << 16) | (g3 << 8) | (b3);
      
line.hexColor line.c.toString(16);
      
line.hexColor '#' '000000'.substr(0line.hexColor.length) + line.hexColor;
      
line.hexColor2 line.c2.toString(16);
      
line.hexColor2 '#' '000000'.substr(0line.hexColor2.length) + line.hexColor2;
      
line.hexColor3 line.c3.toString(16);
      
line.hexColor3 '#' '000000'.substr(0line.hexColor3.length) + line.hexColor3;
      
line.minValue 100;
      
line.maxValue 1;

      
// make legend
      
line.legend ce('div', {
        
innerHTML'<canvas width="20" height="20" style="vertical-align: middle; padding-right: 2px;"></canvas>' +
          
'<span style="font-weight: bold;">' + ((line.name.length >= 30) ? line.name.substr(027) + '...' line.name)  + '</span>' +
          
'<div style="position: absolute; top: 0px; left: 0px; padding: 2px 3px; white-space: nowrap; display: none; background: ' line.hexColor2 '; -webkit-border-radius: 2px; -khtml-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px;"></div>'
      
}, {
        
colorline.hexColor,
        
position'relative',
        
cursor'default',
        
paddingLeft'10px'
      
});
      
line.shown true;
      
line.legendCheck line.legend.children[0];
      
line.legendBox line.legend.children[2];
      var 
ctx getContext(line.legendCheck);
      
ctx.fillStyle ctx.strokeStyle line.hexColor;
      
ctx.lineWidth 4;
      
ctx.lineJoin 'round';
      
ctx.strokeRect(4599);
      
ctx.fillRect(4599);

      if (
line.sum) {
        
line.legendBox.innerHTML formatValue(line.sum) + this.params.yunits;
        
show(line.legendBox);
      }

      for (var 
0line.d.lengthi++) {
        
line.d[i].line.d[i].|| line.d[i]["0"] || i;
        
line.d[i].parseFloat(line.d[i].|| line.d[i]["1"] || 0);
        
line.d[i].line.d[i].|| line.d[i]["2"] || null;
        
line.d[i].line.d[i].|| line.d[i]["3"] || null;
        
line.maxValue Math.max(line.maxValueline.d[i].y);
        
line.minValue Math.min(line.minValueline.d[i].y);
        
this.maxValue Math.max(this.maxValueline.d[i].y);
        
this.minValue Math.min(this.minValueline.d[i].y);
        
this.minAbsValue Math.min(this.minAbsValueMath.abs(line.d[i].y));
      }
      
line.stInd 0;
      
line.enIdx line.d.length;

      
this.lines.push(line);
    }
    for (var 
0this.lines.lengthi++) {
      var 
line this.lines[i];
      if (
this.lines.length 2) {
        
this.column[0].appendChild(line.legend);
        
max_coltext[0] = Math.max(max_coltext[0], getSize(line.legend.children[1])[0]);
      } else {
        
this.column[1].appendChild(line.legend);
        
max_coltext[1] = Math.max(max_coltext[1], getSize(line.legend.children[1])[0]);
      }
    }
    for (var 
0this.lines.lengthi++) {
      var 
line this.lines[i];
      if (
this.lines.length 2) {
        
line.legendBox.style.left = (max_coltext[0] + 40) + 'px';
      } else {
        
line.legendBox.style.left = (max_coltext[1] + 40) + 'px';
      }
    }

    var 
noData this.noData || (this.lines.length == && !this.params.multiple);

    
this.zoutLayout.style.display noData 'none' 'block';
    
this.vScale.style.display noData 'none' 'block';;
    
this.showEmpty(noData);

    
this.zoutLayout.style.display 'none';
    
this.title.style.display 'none';
    
this.vScaleView.style.paddingTop 0;
    
this.viewHeight this.height 24;
    
this.zinLayout.style.height this.viewHeight "px";
    
this.zinView.height this.viewHeight;
    
this.dotsLayer.height this.viewHeight 25;
    
this.disable_zoom true;
    if (
this.params.multiple && this.menu.parentNode == this.mainLayout) {
      var 
menu re(this.menu);
      
setStyle(menu, {position'absolute'right'10px'top'20px'zIndex1000});
      
this.zinLayout.insertBefore(menuthis.zinView);
    }

    var 
ctx getContext(this.vScaleView);
    
ctx.font '11px tahoma, arial, verdana, sans-serif, Lucida Sans';
    var 
yUnits this.params.yunits this.params.yunits '';
    var 
maxWidth Math.max(
      
ctx.measureText(formatValue(this.maxValue getYStep(this.maxValuethis.params.int_scale) + yUnits)).widthctx.measureText(formatValue(getYStep(this.minAbsValuethis.params.int_scale) + yUnits)).width);
    
this.scaleWidth = (this.lines.length == 0) ? : (maxWidth 30);
    
this.scaleWidth Math.floor(this.scaleWidth);
    
this.vScale.style.width this.scaleWidth "px";
    
this.vScale.style.height this.height "px";
    
this.vScaleView.width this.scaleWidth;
    
this.vScaleView.height this.height;
    
this.viewWidth = (this.width this.scaleWidth);

    
this.mainLayout.style.width this.viewWidth "px";
    
this.zinView.width this.viewWidth;
    
this.dotsLayer.width this.viewWidth;
    
this.column[0].style.width Math.floor(this.viewWidth 2) + "px";
    
this.column[1].style.width Math.floor(this.viewWidth 2) + "px";

    
this.xstep Math.floor(this.viewWidth this.params.bar_chart.length);
    
this.barsWidth Math.floor(this.xstep / (this.lines.length 1));
    
this.barsWidth Math.min(this.barsWidth25);

    
// draw window
    
if (this.lines.length == || (this.maxValue this.minValue 1e-6)) {
      
this.isNegative false;
      
this.ystep 1;
      
this.localTop 5;
      
this.localBottom 0;
    } else {
      
this.isNegative = (this.minValue < -1e-6);
      
this.ystep Math.max(getYStep(this.maxValue - (adjust this.minValue 0), this.params.int_scale), this.isNegative getYStep(-this.minValuethis.params.int_scale) : 1e-6);
      
this.localTop = (Math.ceil(this.maxValue this.ystep)) * this.ystep;
      
this.localBottom 0;
    }
    
this.yfactorIn = (this.viewHeight - (this.isNegative 43 34)) / (this.localTop this.localBottom);
    
this.xfactorIn 1;

    
// redraw zinView
    
var ctx getContext(this.zinView), ctxS getContext(this.vScaleView);
    
ctx.clearRect(00this.viewWidththis.viewHeight);
    
ctx.fillStyle '#fafafa';
    
ctx.fillRect(09this.viewWidththis.viewHeight 9);
    
ctxS.clearRect(00this.scaleWidththis.viewHeight);

    
// y scale
    
ctx.lineWidth 1;
    
ctx.strokeStyle '#e6eaf0';
    
ctxS.font '11px tahoma, arial, verdana, sans-serif, Lucida Sans';
    
ctxS.fillStyle '#36638e';
    
ctxS.textAlign 'right';
    
ctxS.textBaseline 'middle';
    for (var 
gridY this.localBottomgridY this.localTop this.ystepgridY += this.ystep) {
      var 
cy this.viewHeight 24.5 Math.round((gridY this.localBottom) * this.yfactorIn) - (this.isNegative 0);
      if (
gridY this.localTop) {
        
ctx.strokeStyle = (this.isNegative && Math.abs(gridY) < 1e-8) ? '#9fb1c4' '#e6eaf0';
        
ctx.beginPath();
        
ctx.moveTo(0cy);
        
ctx.lineTo(this.viewWidthcy);
        
ctx.stroke();
      }
      
ctxS.fillText(formatValue(gridY) + yUnitsthis.scaleWidth 6cy);
    }

    
// x scale
    
ctx.fillStyle '#e9ecf0';
    
ctx.fillRect(0this.viewHeight 25this.viewWidth25);

    
ctx.font '11px tahoma, arial, verdana, sans-serif, Lucida Sans';
    
ctx.fillStyle '#36638e';
    
ctx.textAlign 'center';
    
ctx.textBaseline 'top';

    var 
fontSize 11;
    for (var 
0this.params.bar_chart.lengthi++) {
      while (
ctx.measureText(this.params.bar_chart[i]).width this.xstep && fontSize >= 8) {
        
fontSize--;
        
ctx.font fontSize 'px tahoma, arial, verdana, sans-serif, Lucida Sans';
      }
    }

    for (var 
0this.params.bar_chart.lengthi++) {
      var 
text this.params.bar_chart[i];
      var 
textpos this.xstep * (0.5);
      
ctx.fillText(replaceEntities(text), textposthis.viewHeight 19);
    }

    
// graph
    
if (this.isNegative)
      
drawBars(ctx09this.viewWidththis.viewHeight 43this.linesthis.params.bar_chartthis.barsWidththis.xstepthis.yfactorIn, -this.localBottom);
    else
      
drawBars(ctx09this.viewWidththis.viewHeight 34this.linesthis.params.bar_chartthis.barsWidththis.xstepthis.yfactorInthis.adjust ? -this.localBottom 0);

    
ctx.strokeStyle '#b8c5d4';
    
ctx.lineWidth 1;
    
ctx.beginPath();
    
ctx.moveTo(0.59);
    
ctx.lineTo(0.5this.viewHeight);
    
ctx.lineTo(this.viewWidththis.viewHeight);
    
ctx.stroke();

    
ctx.strokeStyle '#6b93b5';
    
ctx.lineWidth 2;
    
ctx.globalAlpha 0.25;
    
ctx.beginPath();
    
ctx.moveTo(1this.viewHeight 26);
    
ctx.lineTo(this.viewWidththis.viewHeight 26);
    
ctx.stroke();
  },
  
destroy: function() {
    
this.destroyDots();
    
this.endDrag();
    
removeEventEx(this.lHandle'mousedown touchstart'this.takeHandle);
    
removeEventEx(this.rHandle'mousedown touchstart'this.takeHandle);
    
removeEventEx(this.zoutWindow'mousedown touchstart'this.takeWindow);
    
removeEventEx(this.lMask'mousedown touchstart'this.takeMask);
    
removeEventEx(this.rMask'mousedown touchstart'this.takeMask);
    
removeEventEx(this.zinLayout'mousedown touchstart'this.takeView);
    
removeEventEx(this.dotsLayer'mousemove'this.showDots);
    
removeEventEx(this.zinLayout'mouseout'this.hideDots);
    
removeEventEx(this.zinLayout'mousewheel DOMMouseScroll'this.wheelView);
    
removeEventEx(this.zoutLayout'mousewheel DOMMouseScroll'this.wheelView);
    
removeEvent(this.column[0], 'selectionstart'cancelEvent);
    
removeEvent(this.column[1], 'selectionstart'cancelEvent);
    
this.graphDiv.innerHTML '';
  },

  
showBadBrowserBox: function() {
    var 
= (window.devicePixelRatio >= '_2x' '');
    var 
content getLang('stats_good_browser_box_msg') + '
    <div id="stats_good_browsers" class="clear_fix">
      <a href="http://www.mozilla-europe.org/" target="_blank" style="background: url(/images/firefox'
+s+'.png) no-repeat 50% 17px;">Mozilla Firefox</a>
      <a href="http://www.google.com/chrome/" target="_blank" style="background: url(/images/chrome'
+s+'.png) no-repeat 50% 17px;">Google Chrome</a>
      <a href="http://www.opera.com/" target="_blank" style="background: url(/images/opera'
+s+'.png) no-repeat 50% 15px;">Opera</a>
      <a href="http://www.apple.com/safari/" target="_blank" style="background: url(/images/safari'
+s+'.png) no-repeat 50% 12px;">Safari</a>
    </div>
    <style>
      #stats_good_browsers {
        height: 136px;
        margin: 10px auto 0 auto;
        width: 480px;
      }
      #stats_good_browsers a {
        float: left;
        height: 20px;
        padding: 106px 0 10px 0;
        width: 120px;
        text-align: center;
        -webkit-border-radius: 4px;
        -khtml-border-radius: 4px;
        -moz-border-radius: 4px;
        border-radius: 4px;
      }
      #stats_good_browsers a:hover {
        text-decoration: none;
        background-color: #edf1f5!important;
      }
    </style>'
;
    
cur.badBrowserBox MessageBox({width540hideButtonstruebodyStyle'padding: 25px; text-align: center;'hideOnBGClicktrue}).content(content).show();
    if (!
window.ajax) {
      var 
cur.badBrowserBox.body();
      
hide(geByClass1('box_title_wrap'b.parentNode));
      
hide(geByClass1('box_controls_wrap'b.parentNode));
    }
  }
}

window.Graph Graph;
addEvent(document'touchstart touchmove touchend', function(ev) {
  
globalTouchCount ev.touches.length;
});
})(
window);

try{
stManager.done('graph.js');}catch(e){}
?>
Онлайн: 0
Реклама