@ -74,6 +74,7 @@ function LineGraph(body, options) {
}
}
} ;
} ;
// options is shared by this ItemSet and all its items
// options is shared by this ItemSet and all its items
this . options = util . extend ( { } , this . defaultOptions ) ;
this . options = util . extend ( { } , this . defaultOptions ) ;
this . dom = { } ;
this . dom = { } ;
@ -81,6 +82,7 @@ function LineGraph(body, options) {
this . hammer = null ;
this . hammer = null ;
this . groups = { } ;
this . groups = { } ;
this . abortedGraphUpdate = false ;
this . abortedGraphUpdate = false ;
this . autoSizeSVG = false ;
var me = this ;
var me = this ;
this . itemsData = null ; // DataSet
this . itemsData = null ; // DataSet
@ -121,7 +123,7 @@ function LineGraph(body, options) {
this . setOptions ( options ) ;
this . setOptions ( options ) ;
this . groupsUsingDefaultStyles = [ 0 ] ;
this . groupsUsingDefaultStyles = [ 0 ] ;
this . body . emitter . on ( "rangechanged ", function ( ) {
this . body . emitter . on ( 'rangechanged ', function ( ) {
me . lastStart = me . body . range . start ;
me . lastStart = me . body . range . start ;
me . svg . style . left = util . option . asSize ( - me . width ) ;
me . svg . style . left = util . option . asSize ( - me . width ) ;
me . _updateGraph . apply ( me ) ;
me . _updateGraph . apply ( me ) ;
@ -129,7 +131,7 @@ function LineGraph(body, options) {
// create the HTML DOM
// create the HTML DOM
this . _create ( ) ;
this . _create ( ) ;
this . body . emitter . emit ( "change ") ;
this . body . emitter . emit ( 'change ') ;
}
}
LineGraph . prototype = new Component ( ) ;
LineGraph . prototype = new Component ( ) ;
@ -143,10 +145,10 @@ LineGraph.prototype._create = function(){
this . dom . frame = frame ;
this . dom . frame = frame ;
// create svg element for graph drawing.
// create svg element for graph drawing.
this . svg = document . createElementNS ( 'http://www.w3.org/2000/svg' , "svg ") ;
this . svg . style . position = "relative ";
this . svg . style . height = ( '' + this . options . graphHeight ) . replace ( "px ", '' ) + 'px' ;
this . svg . style . display = "block ";
this . svg = document . createElementNS ( 'http://www.w3.org/2000/svg' , 'svg ') ;
this . svg . style . position = 'relative ';
this . svg . style . height = ( '' + this . options . graphHeight ) . replace ( 'px ', '' ) + 'px' ;
this . svg . style . display = 'block ';
frame . appendChild ( this . svg ) ;
frame . appendChild ( this . svg ) ;
// data axis
// data axis
@ -171,6 +173,12 @@ LineGraph.prototype._create = function(){
LineGraph . prototype . setOptions = function ( options ) {
LineGraph . prototype . setOptions = function ( options ) {
if ( options ) {
if ( options ) {
var fields = [ 'sampling' , 'defaultGroup' , 'graphHeight' , 'yAxisOrientation' , 'style' , 'barChart' , 'dataAxis' , 'sort' , 'groups' ] ;
var fields = [ 'sampling' , 'defaultGroup' , 'graphHeight' , 'yAxisOrientation' , 'style' , 'barChart' , 'dataAxis' , 'sort' , 'groups' ] ;
if ( options . graphHeight === undefined && options . height !== undefined && this . body . domProps . centerContainer . height !== undefined ) {
this . autoSizeSVG = true ;
}
else if ( this . body . domProps . centerContainer . height !== undefined && parseInt ( options . graphHeight . replace ( "px" , '' ) ) < this . body . domProps . centerContainer . height ) {
this . autoSizeSVG = true ;
}
util . selectiveDeepExtend ( fields , this . options , options ) ;
util . selectiveDeepExtend ( fields , this . options , options ) ;
util . mergeOptions ( this . options , options , 'catmullRom' ) ;
util . mergeOptions ( this . options , options , 'catmullRom' ) ;
util . mergeOptions ( this . options , options , 'drawPoints' ) ;
util . mergeOptions ( this . options , options , 'drawPoints' ) ;
@ -424,9 +432,9 @@ LineGraph.prototype._updateAllGroupData = function () {
if ( this . itemsData . _data . hasOwnProperty ( itemId ) ) {
if ( this . itemsData . _data . hasOwnProperty ( itemId ) ) {
var item = this . itemsData . _data [ itemId ] ;
var item = this . itemsData . _data [ itemId ] ;
if ( groupsContent [ item . group ] === undefined ) {
if ( groupsContent [ item . group ] === undefined ) {
throw new Error ( "Cannot find referenced group. Possible reason: items added before groups? Groups need to be added before items, as items refer to groups. ")
throw new Error ( 'Cannot find referenced group. Possible reason: items added before groups? Groups need to be added before items, as items refer to groups. ')
}
}
item . x = util . convert ( item . x , "Date ") ;
item . x = util . convert ( item . x , 'Date ') ;
groupsContent [ item . group ] . push ( item ) ;
groupsContent [ item . group ] . push ( item ) ;
}
}
}
}
@ -528,7 +536,7 @@ LineGraph.prototype.redraw = function() {
if ( this . width != 0 ) {
if ( this . width != 0 ) {
var rangePerPixelInv = this . width / range ;
var rangePerPixelInv = this . width / range ;
var xOffset = offset * rangePerPixelInv ;
var xOffset = offset * rangePerPixelInv ;
this . svg . style . left = ( - this . width - xOffset ) + "px ";
this . svg . style . left = ( - this . width - xOffset ) + 'px ';
}
}
}
}
@ -554,6 +562,14 @@ LineGraph.prototype._updateGraph = function () {
var groupRanges = { } ;
var groupRanges = { } ;
var changeCalled = false ;
var changeCalled = false ;
// update the height of the graph on each redraw of the graph.
if ( this . autoSizeSVG == true ) {
if ( this . options . graphHeight != this . body . domProps . centerContainer . height + 'px' ) {
this . options . graphHeight = this . body . domProps . centerContainer . height + 'px' ;
this . svg . style . height = this . body . domProps . centerContainer . height + 'px' ;
}
}
// getting group Ids
// getting group Ids
var groupIds = [ ] ;
var groupIds = [ ] ;
for ( var groupId in this . groups ) {
for ( var groupId in this . groups ) {
@ -584,7 +600,7 @@ LineGraph.prototype._updateGraph = function () {
if ( changeCalled == true ) {
if ( changeCalled == true ) {
DOMutil . cleanupElements ( this . svgElements ) ;
DOMutil . cleanupElements ( this . svgElements ) ;
this . abortedGraphUpdate = true ;
this . abortedGraphUpdate = true ;
this . body . emitter . emit ( "change ") ;
this . body . emitter . emit ( 'change ') ;
return ;
return ;
}
}
this . abortedGraphUpdate = false ;
this . abortedGraphUpdate = false ;
@ -695,7 +711,7 @@ LineGraph.prototype._getYRanges = function (groupIds, groupsData, groupRanges) {
groupData = groupsData [ groupIds [ i ] ] ;
groupData = groupsData [ groupIds [ i ] ] ;
if ( groupData . length > 0 ) {
if ( groupData . length > 0 ) {
group = this . groups [ groupIds [ i ] ] ;
group = this . groups [ groupIds [ i ] ] ;
if ( group . options . style == 'line' || group . options . barChart . handleOverlap != "stack ") {
if ( group . options . style == 'line' || group . options . barChart . handleOverlap != 'stack ') {
var yMin = groupData [ 0 ] . y ;
var yMin = groupData [ 0 ] . y ;
var yMax = groupData [ 0 ] . y ;
var yMax = groupData [ 0 ] . y ;
for ( j = 0 ; j < groupData . length ; j ++ ) {
for ( j = 0 ; j < groupData . length ; j ++ ) {
@ -738,9 +754,9 @@ LineGraph.prototype._getYRanges = function (groupIds, groupsData, groupRanges) {
} ) ;
} ) ;
intersections = { } ;
intersections = { } ;
this . _getDataIntersections ( intersections , barCombinedDataLeft ) ;
this . _getDataIntersections ( intersections , barCombinedDataLeft ) ;
groupRanges [ "__barchartLeft "] = this . _getStackedBarYRange ( intersections , barCombinedDataLeft ) ;
groupRanges [ "__barchartLeft "] . yAxisOrientation = "left ";
groupIds . push ( "__barchartLeft ") ;
groupRanges [ '__barchartLeft '] = this . _getStackedBarYRange ( intersections , barCombinedDataLeft ) ;
groupRanges [ '__barchartLeft '] . yAxisOrientation = 'left ';
groupIds . push ( '__barchartLeft ') ;
}
}
if ( barCombinedDataRight . length > 0 ) {
if ( barCombinedDataRight . length > 0 ) {
// sort by time and by group
// sort by time and by group
@ -753,9 +769,9 @@ LineGraph.prototype._getYRanges = function (groupIds, groupsData, groupRanges) {
} ) ;
} ) ;
intersections = { } ;
intersections = { } ;
this . _getDataIntersections ( intersections , barCombinedDataRight ) ;
this . _getDataIntersections ( intersections , barCombinedDataRight ) ;
groupRanges [ "__barchartRight "] = this . _getStackedBarYRange ( intersections , barCombinedDataRight ) ;
groupRanges [ "__barchartRight "] . yAxisOrientation = "right ";
groupIds . push ( "__barchartRight ") ;
groupRanges [ '__barchartRight '] = this . _getStackedBarYRange ( intersections , barCombinedDataRight ) ;
groupRanges [ '__barchartRight '] . yAxisOrientation = 'right ';
groupIds . push ( '__barchartRight ') ;
}
}
}
}
} ;
} ;
@ -853,11 +869,11 @@ LineGraph.prototype._updateYAxis = function (groupIds, groupRanges) {
}
}
// clean the accumulated lists
// clean the accumulated lists
if ( groupIds . indexOf ( "__barchartLeft ") != - 1 ) {
groupIds . splice ( groupIds . indexOf ( "__barchartLeft ") , 1 ) ;
if ( groupIds . indexOf ( '__barchartLeft ') != - 1 ) {
groupIds . splice ( groupIds . indexOf ( '__barchartLeft ') , 1 ) ;
}
}
if ( groupIds . indexOf ( "__barchartRight ") != - 1 ) {
groupIds . splice ( groupIds . indexOf ( "__barchartRight ") , 1 ) ;
if ( groupIds . indexOf ( '__barchartRight ') != - 1 ) {
groupIds . splice ( groupIds . indexOf ( '__barchartRight ') , 1 ) ;
}
}
return changeCalled ;
return changeCalled ;
@ -1047,9 +1063,9 @@ LineGraph.prototype._drawLineGraph = function (dataset, group) {
if ( dataset != null ) {
if ( dataset != null ) {
if ( dataset . length > 0 ) {
if ( dataset . length > 0 ) {
var path , d ;
var path , d ;
var svgHeight = Number ( this . svg . style . height . replace ( "px" , " ") ) ;
var svgHeight = Number ( this . svg . style . height . replace ( 'px' , ' ') ) ;
path = DOMutil . getSVGElement ( 'path' , this . svgElements , this . svg ) ;
path = DOMutil . getSVGElement ( 'path' , this . svgElements , this . svg ) ;
path . setAttributeNS ( null , "class ", group . className ) ;
path . setAttributeNS ( null , 'class ', group . className ) ;
// construct path from dataset
// construct path from dataset
if ( group . options . catmullRom . enabled == true ) {
if ( group . options . catmullRom . enabled == true ) {
@ -1064,16 +1080,16 @@ LineGraph.prototype._drawLineGraph = function (dataset, group) {
var fillPath = DOMutil . getSVGElement ( 'path' , this . svgElements , this . svg ) ;
var fillPath = DOMutil . getSVGElement ( 'path' , this . svgElements , this . svg ) ;
var dFill ;
var dFill ;
if ( group . options . shaded . orientation == 'top' ) {
if ( group . options . shaded . orientation == 'top' ) {
dFill = "M " + dataset [ 0 ] . x + "," + 0 + " " + d + "L " + dataset [ dataset . length - 1 ] . x + ", " + 0 ;
dFill = 'M ' + dataset [ 0 ] . x + ',' + 0 + ' ' + d + 'L ' + dataset [ dataset . length - 1 ] . x + ', ' + 0 ;
}
}
else {
else {
dFill = "M " + dataset [ 0 ] . x + ", " + svgHeight + " " + d + "L " + dataset [ dataset . length - 1 ] . x + ", " + svgHeight ;
dFill = 'M ' + dataset [ 0 ] . x + ', ' + svgHeight + ' ' + d + 'L ' + dataset [ dataset . length - 1 ] . x + ', ' + svgHeight ;
}
}
fillPath . setAttributeNS ( null , "class ", group . className + " fill ") ;
fillPath . setAttributeNS ( null , "d ", dFill ) ;
fillPath . setAttributeNS ( null , 'class ', group . className + ' fill ') ;
fillPath . setAttributeNS ( null , 'd ', dFill ) ;
}
}
// copy properties to path for drawing.
// copy properties to path for drawing.
path . setAttributeNS ( null , "d" , "M " + d ) ;
path . setAttributeNS ( null , 'd' , 'M ' + d ) ;
// draw points
// draw points
if ( group . options . drawPoints . enabled == true ) {
if ( group . options . drawPoints . enabled == true ) {
@ -1140,7 +1156,7 @@ LineGraph.prototype._convertYcoordinates = function (datapoints, group) {
var xValue , yValue ;
var xValue , yValue ;
var toScreen = this . body . util . toScreen ;
var toScreen = this . body . util . toScreen ;
var axis = this . yAxisLeft ;
var axis = this . yAxisLeft ;
var svgHeight = Number ( this . svg . style . height . replace ( "px" , " ") ) ;
var svgHeight = Number ( this . svg . style . height . replace ( 'px' , ' ') ) ;
if ( group . options . yAxisOrientation == 'right' ) {
if ( group . options . yAxisOrientation == 'right' ) {
axis = this . yAxisRight ;
axis = this . yAxisRight ;
}
}
@ -1158,7 +1174,7 @@ LineGraph.prototype._convertYcoordinates = function (datapoints, group) {
/ * *
/ * *
* This uses an uniform parametrization of the CatmullRom algorithm :
* This uses an uniform parametrization of the CatmullRom algorithm :
* "On the Parameterization of Catmull-Rom Curves " by Cem Yuksel et al .
* 'On the Parameterization of Catmull-Rom Curves ' by Cem Yuksel et al .
* @ param data
* @ param data
* @ returns { string }
* @ returns { string }
* @ private
* @ private
@ -1166,7 +1182,7 @@ LineGraph.prototype._convertYcoordinates = function (datapoints, group) {
LineGraph . prototype . _catmullRomUniform = function ( data ) {
LineGraph . prototype . _catmullRomUniform = function ( data ) {
// catmull rom
// catmull rom
var p0 , p1 , p2 , p3 , bp1 , bp2 ;
var p0 , p1 , p2 , p3 , bp1 , bp2 ;
var d = Math . round ( data [ 0 ] . x ) + ", " + Math . round ( data [ 0 ] . y ) + " ";
var d = Math . round ( data [ 0 ] . x ) + ', ' + Math . round ( data [ 0 ] . y ) + ' ';
var normalization = 1 / 6 ;
var normalization = 1 / 6 ;
var length = data . length ;
var length = data . length ;
for ( var i = 0 ; i < length - 1 ; i ++ ) {
for ( var i = 0 ; i < length - 1 ; i ++ ) {
@ -1188,13 +1204,13 @@ LineGraph.prototype._catmullRomUniform = function(data) {
bp2 = { x : ( ( p1 . x + 6 * p2 . x - p3 . x ) * normalization ) , y : ( ( p1 . y + 6 * p2 . y - p3 . y ) * normalization ) } ;
bp2 = { x : ( ( p1 . x + 6 * p2 . x - p3 . x ) * normalization ) , y : ( ( p1 . y + 6 * p2 . y - p3 . y ) * normalization ) } ;
// bp0 = { x: p2.x, y: p2.y };
// bp0 = { x: p2.x, y: p2.y };
d += "C " +
bp1 . x + ", " +
bp1 . y + " " +
bp2 . x + ", " +
bp2 . y + " " +
p2 . x + ", " +
p2 . y + " ";
d += 'C ' +
bp1 . x + ', ' +
bp1 . y + ' ' +
bp2 . x + ', ' +
bp2 . y + ' ' +
p2 . x + ', ' +
p2 . y + ' ';
}
}
return d ;
return d ;
@ -1218,7 +1234,7 @@ LineGraph.prototype._catmullRom = function(data, group) {
else {
else {
var p0 , p1 , p2 , p3 , bp1 , bp2 , d1 , d2 , d3 , A , B , N , M ;
var p0 , p1 , p2 , p3 , bp1 , bp2 , d1 , d2 , d3 , A , B , N , M ;
var d3powA , d2powA , d3pow2A , d2pow2A , d1pow2A , d1powA ;
var d3powA , d2powA , d3pow2A , d2pow2A , d1pow2A , d1powA ;
var d = Math . round ( data [ 0 ] . x ) + ", " + Math . round ( data [ 0 ] . y ) + " ";
var d = Math . round ( data [ 0 ] . x ) + ', ' + Math . round ( data [ 0 ] . y ) + ' ';
var length = data . length ;
var length = data . length ;
for ( var i = 0 ; i < length - 1 ; i ++ ) {
for ( var i = 0 ; i < length - 1 ; i ++ ) {
@ -1268,13 +1284,13 @@ LineGraph.prototype._catmullRom = function(data, group) {
if ( bp1 . x == 0 && bp1 . y == 0 ) { bp1 = p1 ; }
if ( bp1 . x == 0 && bp1 . y == 0 ) { bp1 = p1 ; }
if ( bp2 . x == 0 && bp2 . y == 0 ) { bp2 = p2 ; }
if ( bp2 . x == 0 && bp2 . y == 0 ) { bp2 = p2 ; }
d += "C " +
bp1 . x + ", " +
bp1 . y + " " +
bp2 . x + ", " +
bp2 . y + " " +
p2 . x + ", " +
p2 . y + " ";
d += 'C ' +
bp1 . x + ', ' +
bp1 . y + ' ' +
bp2 . x + ', ' +
bp2 . y + ' ' +
p2 . x + ', ' +
p2 . y + ' ';
}
}
return d ;
return d ;
@ -1289,13 +1305,13 @@ LineGraph.prototype._catmullRom = function(data, group) {
* /
* /
LineGraph . prototype . _linear = function ( data ) {
LineGraph . prototype . _linear = function ( data ) {
// linear
// linear
var d = " ";
var d = ' ';
for ( var i = 0 ; i < data . length ; i ++ ) {
for ( var i = 0 ; i < data . length ; i ++ ) {
if ( i == 0 ) {
if ( i == 0 ) {
d += data [ i ] . x + ", " + data [ i ] . y ;
d += data [ i ] . x + ', ' + data [ i ] . y ;
}
}
else {
else {
d += " " + data [ i ] . x + ", " + data [ i ] . y ;
d += ' ' + data [ i ] . x + ', ' + data [ i ] . y ;
}
}
}
}
return d ;
return d ;