Ero sivun ”Widget:JwObsCharts” versioiden välillä
Järvi-meriwikistä
(88 välissä olevaa versiota samalta käyttäjältä ei näytetä) | |||
Rivi 68: | Rivi 68: | ||
window.jwobschart[id] = {}; | window.jwobschart[id] = {}; | ||
− | + | ||
− | var memo = {}; window.jwobschart[id].memo = memo; | + | var memo = { "distF": 0 }; window.jwobschart[id].memo = memo; |
memo.widgetEl = jQuery( this ); | memo.widgetEl = jQuery( this ); | ||
Rivi 78: | Rivi 78: | ||
memo.waterbody = jQuery( this ).attr( 'data-jw-waterbody' ); if ( typeof memo.waterbody == 'undefined' ) { memo.waterbody = '-'; } | memo.waterbody = jQuery( this ).attr( 'data-jw-waterbody' ); if ( typeof memo.waterbody == 'undefined' ) { memo.waterbody = '-'; } | ||
memo.obscode = jQuery( this ).attr( 'data-jw-obscode' ); if ( typeof memo.obscode == 'undefined' ) { memo.obscode = '-'; } | memo.obscode = jQuery( this ).attr( 'data-jw-obscode' ); if ( typeof memo.obscode == 'undefined' ) { memo.obscode = '-'; } | ||
+ | if ( typeof i18n[ memo.obscode ] == 'undefined' ) { i18n[ memo.obscode ] = i18n.obs; } | ||
memo.refcode = jQuery( this ).attr( 'data-jw-refcode' ); if ( typeof memo.refcode == 'undefined' ) { memo.refcode = '-'; } | memo.refcode = jQuery( this ).attr( 'data-jw-refcode' ); if ( typeof memo.refcode == 'undefined' ) { memo.refcode = '-'; } | ||
memo.reffilter = jQuery( this ).attr( 'data-jw-reffilter' ); if ( typeof memo.reffilter == 'undefined' ) { memo.reffilter = ''; } | memo.reffilter = jQuery( this ).attr( 'data-jw-reffilter' ); if ( typeof memo.reffilter == 'undefined' ) { memo.reffilter = ''; } | ||
memo.obscodeParts = memo.obscode.split('_'); | memo.obscodeParts = memo.obscode.split('_'); | ||
memo.title = jQuery( this ).attr( 'data-title' ); if ( typeof memo.title == 'undefined' ) { memo.title = i18n[ memo.obscode ][ 'title' ][ memo.lang ]; } | memo.title = jQuery( this ).attr( 'data-title' ); if ( typeof memo.title == 'undefined' ) { memo.title = i18n[ memo.obscode ][ 'title' ][ memo.lang ]; } | ||
+ | memo.axistitlev = jQuery( this ).attr( 'data-axistitlev' ); if ( typeof memo.axistitlev == 'undefined' ) { memo.axistitlev = i18n[ memo.obscode ][ 'axisTitleV' ][ memo.lang ]; } | ||
+ | memo.tooltiptitle = jQuery( this ).attr( 'data-tooltiptitle' ); if ( typeof memo.tooltiptitle == 'undefined' ) { memo.tooltiptitle = i18n[ memo.obscode ][ 'title' ][ memo.lang ]; } | ||
+ | memo.info = jQuery( this ).attr( 'data-info' ); if ( typeof memo.info == 'undefined' ) { memo.info = jQuery( this ).attr( 'data-info' ); } | ||
if ( typeof jQuery( this ).attr( 'data-min' ) != 'undefined' ) { i18n[memo.obscode]['min'] = parseInt( jQuery( this ).attr( 'data-min' ) ); } | if ( typeof jQuery( this ).attr( 'data-min' ) != 'undefined' ) { i18n[memo.obscode]['min'] = parseInt( jQuery( this ).attr( 'data-min' ) ); } | ||
+ | if ( typeof jQuery( this ).attr( 'data-unit' ) != 'undefined' ) { i18n[memo.obscode]['unit'] = parseInt( jQuery( this ).attr( 'data-unit' ) ); } | ||
if ( typeof jQuery( this ).attr( 'data-start-date' ) != 'undefined' ) { | if ( typeof jQuery( this ).attr( 'data-start-date' ) != 'undefined' ) { | ||
Rivi 92: | Rivi 97: | ||
memo.startDate = '1800-01-01'; | memo.startDate = '1800-01-01'; | ||
} | } | ||
+ | |||
memo.service = jQuery( this ).attr( 'data-coo311-service_code' ); | memo.service = jQuery( this ).attr( 'data-coo311-service_code' ); | ||
Rivi 186: | Rivi 192: | ||
if ( i18n[memo.obscode].type == 'num' ) { | if ( i18n[memo.obscode].type == 'num' ) { | ||
− | + | ||
− | + | headerCols.push( i18n[ 'Date' ][ memo.lang ] ); | |
− | + | headerCols.push( i18n[ 'Time' ][ memo.lang ] ); | |
− | headerCols.push( '"' + | + | headerCols.push( '"' + memo.axistitlev + '"' ); |
headerCols.push( 'Lisätiedot' ); | headerCols.push( 'Lisätiedot' ); | ||
headerCols.push( 'Valokuva' ); | headerCols.push( 'Valokuva' ); | ||
Rivi 209: | Rivi 215: | ||
csvCols.push( '"' + memo.obses[o].value.toString().replace( '.', i18n['dec'][memo.lang] ) + '"' ); | csvCols.push( '"' + memo.obses[o].value.toString().replace( '.', i18n['dec'][memo.lang] ) + '"' ); | ||
− | csvCols.push( memo.obses[o].addInfo ); | + | csvCols.push( memo.obses[o].addInfo.replace( '<p>', '' ).replace( '</p>', '' ) ); |
csvCols.push( '' ); | csvCols.push( '' ); | ||
csvCols.push( memo.obses[o].maintainer ); | csvCols.push( memo.obses[o].maintainer ); | ||
Rivi 327: | Rivi 333: | ||
memo.trendType = jQuery( this ).attr( 'data-trend-type' ); if (typeof memo.trendType == 'undefined') { memo.trendType = i18n[memo.obscode]['trend']['type']; } | memo.trendType = jQuery( this ).attr( 'data-trend-type' ); if (typeof memo.trendType == 'undefined') { memo.trendType = i18n[memo.obscode]['trend']['type']; } | ||
− | memo.jw = new jwApi(); | + | memo.jw = new jwApi(); |
− | memo.jwR = new jwApi(); | + | memo.jwR = new jwApi(); |
var custom = ''; | var custom = ''; | ||
Rivi 345: | Rivi 351: | ||
} | } | ||
+ | // if testsite | ||
+ | if ( memo.siteid == 170072 ) { so.test = true; } | ||
+ | |||
memo.jw.loadObses( so, function( o ) { | memo.jw.loadObses( so, function( o ) { | ||
− | memo.obses = memo.jw.obs; | + | memo.obses = memo.jw.obs; |
if ( memo.refcode != '-' ) { | if ( memo.refcode != '-' ) { | ||
memo.jwR.loadObses( { "obscode": memo.refcode, "siteid": memo.siteid, "sort": "SiteID", "custom": memo.reffilter }, function( r ) { | memo.jwR.loadObses( { "obscode": memo.refcode, "siteid": memo.siteid, "sort": "SiteID", "custom": memo.reffilter }, function( r ) { | ||
Rivi 354: | Rivi 363: | ||
} else { | } else { | ||
drawVisualization(memo); | drawVisualization(memo); | ||
− | } | + | } |
}); | }); | ||
} else { | } else { | ||
Rivi 371: | Rivi 380: | ||
function drawVisualization( memo ) { | function drawVisualization( memo ) { | ||
− | if ( typeof i18n[ memo.obscode ].direction != 'undefined' ) { memo.vaxisdir = i18n[ memo.obscode ].direction; } else { memo.vaxisdir = 1; } | + | if ( typeof i18n[memo.obscode].valfield == 'undefined' ) { i18n[memo.obscode].valfield = 'val'; } |
+ | if ( typeof i18n[ memo.obscode ].direction != 'undefined' ) { memo.vaxisdir = i18n[ memo.obscode ].direction; } else { memo.vaxisdir = 1; } | ||
memo.options = { | memo.options = { | ||
Rivi 382: | Rivi 392: | ||
interpolateNulls: true, | interpolateNulls: true, | ||
vAxis: { | vAxis: { | ||
− | title: | + | title: memo.axistitlev, |
titleTextStyle: { bold: true, italic: false }, | titleTextStyle: { bold: true, italic: false }, | ||
slantedText: false, | slantedText: false, | ||
Rivi 437: | Rivi 447: | ||
obs = memo.obses[o]; | obs = memo.obses[o]; | ||
− | + | ||
memo.obsesTotal++; | memo.obsesTotal++; | ||
// create data | // create data | ||
− | obs.data = JSON.parse( obs.printouts.DataJSON ); | + | obs.data = JSON.parse( obs.printouts.DataJSON ); |
+ | obs.data.num = obs.data[ i18n[memo.obscode].valfield ]; | ||
if ( obs.data.unit == 'cm' && i18n[memo.obscode]['unit'] == 'm' ) { | if ( obs.data.unit == 'cm' && i18n[memo.obscode]['unit'] == 'm' ) { | ||
− | obs.data. | + | obs.data.num = obs.data.num/100; |
obs.value = obs.value/100; | obs.value = obs.value/100; | ||
} | } | ||
+ | |||
+ | if ( i18n[ memo.obscode ].valfield != 'val' ) { | ||
+ | obs.value = obs.data[ i18n[memo.obscode].valfield ]; | ||
+ | } | ||
// add season | // add season | ||
Rivi 503: | Rivi 518: | ||
if ( i18n[memo.obscode]['type'] == 'cat') { | if ( i18n[memo.obscode]['type'] == 'cat') { | ||
− | obs.popup +='<b>' + | + | obs.popup +='<b>' + memo.tooltiptitle + ': ' + i18n[memo.obscode]['catNames'][obs.value][memo.lang] + '</b> '; |
} else if ( i18n[memo.obscode]['type'] == 'date') { | } else if ( i18n[memo.obscode]['type'] == 'date') { | ||
− | obs.popup +='<b>' + | + | obs.popup +='<b>' + memo.tooltiptitle + '</b> '; |
} else { | } else { | ||
− | obs.popup +='<b>' + | + | memo.decimals = 1; |
+ | if ( memo.obscode == 'level' ) { memo.decimals = 2; } | ||
+ | obs.popup +='<b>' + memo.tooltiptitle + ': ' + (Math.round(obs.value * (memo.decimals*10))/(memo.decimals*10)).toString().replace( '.', i18n['dec'][memo.lang] ) + ' ' + i18n[memo.obscode]['unit'] + '</b> '; | ||
} | } | ||
Rivi 545: | Rivi 562: | ||
baseSize = 2; | baseSize = 2; | ||
} | } | ||
− | |||
− | |||
if ( memo.maintainerShow ) { maintcol = maintColors[obs.maintainer]; } | if ( memo.maintainerShow ) { maintcol = maintColors[obs.maintainer]; } | ||
Rivi 600: | Rivi 615: | ||
jQuery( '[data-toggle="tooltip"]' ).tooltip(); | jQuery( '[data-toggle="tooltip"]' ).tooltip(); | ||
} | } | ||
− | } | + | } |
+ | |||
+ | if ( typeof memo.info != 'undefined' ) { | ||
+ | memo.titleEl.append( ' <button style="padding: 0 0.25em; font-size: 13px; margin-bottom: 3px;" type="button" class="btn btn-secondary btn-info" data-toggle="tooltip" data-placement="top" title="' + memo.info + '"><span class="fontawesome"></span></button>' ); | ||
+ | jQuery( '[data-toggle="tooltip"]' ).tooltip(); | ||
+ | } | ||
+ | |||
} | } | ||
− | + | ||
if (memo.graphType == 'trend') { | if (memo.graphType == 'trend') { | ||
addDataToTrendChart(memo); | addDataToTrendChart(memo); | ||
+ | |||
+ | } else if (memo.graphType == 'seasonwithreferences') { | ||
+ | |||
+ | addDataToSeasonWithReferencesChart(memo); | ||
} else if (memo.graphType == 'trendwithhighlow') { | } else if (memo.graphType == 'trendwithhighlow') { | ||
Rivi 631: | Rivi 656: | ||
// sort according to obs date | // sort according to obs date | ||
memo.obsesA.sort( function( a, b ) { return b.obsdatetime - a.obsdatetime; }); | memo.obsesA.sort( function( a, b ) { return b.obsdatetime - a.obsdatetime; }); | ||
+ | |||
+ | if ( typeof memo.info != 'undefined' ) { | ||
+ | addToTitle = ' <button style="padding: 0 0.25em; font-size: 13px; margin-bottom: 3px;" type="button" class="btn btn-secondary btn-info" data-toggle="tooltip" data-placement="top" title="' + memo.info + '"><span class="fontawesome"></span></button>'; | ||
+ | } else { | ||
+ | addToTitle = ''; | ||
+ | } | ||
if ( memo.obscode == 'level' ) { | if ( memo.obscode == 'level' ) { | ||
Rivi 703: | Rivi 734: | ||
memo.widgetEl.html(''); | memo.widgetEl.html(''); | ||
− | memo.widgetEl.append( '<h3 style="text-align: center; font-size: 18px; margin-top: 0;">Vedenkorkeus</h3>' ); | + | memo.widgetEl.append( '<h3 style="text-align: center; font-size: 18px; margin-top: 0;">Vedenkorkeus' + addToTitle + '</h3>' ); |
memo.widgetEl.append( '<div style="width: 120px; height: 120px; margin: 12px auto; padding: 10px; border-radius: 6px; Xborder: 3px solid rgba( 213, 218, 38, 0.5 );">' + levelsvg + '</div>'); | memo.widgetEl.append( '<div style="width: 120px; height: 120px; margin: 12px auto; padding: 10px; border-radius: 6px; Xborder: 3px solid rgba( 213, 218, 38, 0.5 );">' + levelsvg + '</div>'); | ||
memo.widgetEl.append( '<p style="text-align: center; line-height: 20px;" class="huomio">' + diffStr + '<br /><span class="Xsmall">(' + obs.obsdatetime.inRelationToToday(memo.lang).toLowerCase() + ')</span></p>' ); | memo.widgetEl.append( '<p style="text-align: center; line-height: 20px;" class="huomio">' + diffStr + '<br /><span class="Xsmall">(' + obs.obsdatetime.inRelationToToday(memo.lang).toLowerCase() + ')</span></p>' ); | ||
Rivi 791: | Rivi 822: | ||
memo.widgetEl.html(''); | memo.widgetEl.html(''); | ||
− | memo.widgetEl.append( '<h3 style="text-align: center; font-size: 18px; margin-top: 0;">Pintaveden lämpötila</h3>' ); | + | memo.widgetEl.append( '<h3 style="text-align: center; font-size: 18px; margin-top: 0;">Pintaveden lämpötila' + addToTitle + '</h3>' ); |
memo.widgetEl.append( '<div style="width: 120px; height: 120px; margin: 10px auto; padding: 10px; border-radius: 6px; Xborder: 3px solid rgba( 213, 218, 38, 0.5 );">' + tsvg + '</div>'); | memo.widgetEl.append( '<div style="width: 120px; height: 120px; margin: 10px auto; padding: 10px; border-radius: 6px; Xborder: 3px solid rgba( 213, 218, 38, 0.5 );">' + tsvg + '</div>'); | ||
memo.widgetEl.append( '<p style="text-align: center; line-height: 22px;" class="huomio">' + tstr + '</p>' ); | memo.widgetEl.append( '<p style="text-align: center; line-height: 22px;" class="huomio">' + tstr + '</p>' ); | ||
Rivi 845: | Rivi 876: | ||
memo.widgetEl.html(''); | memo.widgetEl.html(''); | ||
− | memo.widgetEl.append( '<h3 style="text-align: center; font-size: 18px; margin-top: 0;">Sinilevätilanne</h3>' ); | + | memo.widgetEl.append( '<h3 style="text-align: center; font-size: 18px; margin-top: 0;">Sinilevätilanne' + addToTitle + '</h3>' ); |
memo.widgetEl.append( '<div style="width: 120px; height: 120px; margin: 10px auto; padding: 10px; border-radius: 6px; Xborder: 3px solid rgba( 213, 218, 38, 0.5 );">' + asvg + '</div>'); | memo.widgetEl.append( '<div style="width: 120px; height: 120px; margin: 10px auto; padding: 10px; border-radius: 6px; Xborder: 3px solid rgba( 213, 218, 38, 0.5 );">' + asvg + '</div>'); | ||
memo.widgetEl.append( '<p style="text-align: center; line-height: 22px;" class="huomio">' + astr + '</p>' ); | memo.widgetEl.append( '<p style="text-align: center; line-height: 22px;" class="huomio">' + astr + '</p>' ); | ||
Rivi 851: | Rivi 882: | ||
− | + | jQuery( '[data-toggle="tooltip"]' ).tooltip(); | |
memo.loaderEl.fadeOut( "slow", function() { memo.loaderEl.remove(); } ); | memo.loaderEl.fadeOut( "slow", function() { memo.loaderEl.remove(); } ); | ||
Rivi 969: | Rivi 1 000: | ||
memo.data.addColumn( { type: 'string', role: 'annotation' } ); | memo.data.addColumn( { type: 'string', role: 'annotation' } ); | ||
− | memo.options.series.push( { type: 'scatter', pointType: 'circle', pointSize: 9, color: memo.seriesA[ s ].color } ); | + | memo.options.series.push( { type: 'scatter', pointType: 'circle', pointSize: 9, color: memo.seriesA[ s ].color, XstrokeWidth: 2, Xstroke: '#000000' } ); |
if ( memo.seriesA[ s ].obses.length > 1 ) { | if ( memo.seriesA[ s ].obses.length > 1 ) { | ||
Rivi 1 040: | Rivi 1 071: | ||
} | } | ||
− | function | + | function addDataToSeasonWithReferencesChart(memo) { |
− | // | + | // do axis min and max |
+ | memo.axisMinDate = new Date( memo.curSeason, 0, 1 ); | ||
+ | memo.axisMaxDate = new Date( memo.curSeason, 11, 31 ); | ||
− | + | memo.data.addColumn( 'number', memo.obsMinYear + '-' + memo.obsMaxYear ); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | memo.data.addColumn( 'number', memo.obsMinYear + '-' + memo.obsMaxYear ); | ||
memo.data.addColumn( { id:'i0', type:'number', role:'interval' } ); | memo.data.addColumn( { id:'i0', type:'number', role:'interval' } ); | ||
memo.data.addColumn( { id:'i0', type:'number', role:'interval' } ); | memo.data.addColumn( { id:'i0', type:'number', role:'interval' } ); | ||
Rivi 1 062: | Rivi 1 087: | ||
//memo.options.trendlines[0] = { labelInLegend: i18n['trendline'][memo.lang], tooltip: false, color: colors['trend'], lineWidth: 2, opacity: 0.5, type: 'linear', visibleInLegend: memo.trendType!='moving' }; | //memo.options.trendlines[0] = { labelInLegend: i18n['trendline'][memo.lang], tooltip: false, color: colors['trend'], lineWidth: 2, opacity: 0.5, type: 'linear', visibleInLegend: memo.trendType!='moving' }; | ||
− | + | for (var o in memo.obsesA) { | |
− | |||
− | for (var o in memo.obsesA) { | ||
− | |||
dateStr = memo.obsesA[o].popup.match( /\([^)]*\)/g ); | dateStr = memo.obsesA[o].popup.match( /\([^)]*\)/g ); | ||
yearStr = dateStr[0].match( /[0-9]{4}/g ); | yearStr = dateStr[0].match( /[0-9]{4}/g ); | ||
memo.obsesA[o].popup = memo.obsesA[o].popup.replace( dateStr[0], '(' + yearStr[0] + ')' ); | memo.obsesA[o].popup = memo.obsesA[o].popup.replace( dateStr[0], '(' + yearStr[0] + ')' ); | ||
− | memo.dataA.push( [ memo.obsesA[o].obsdatetime, memo.obsesA[o].value, memo.obsesA[o].data.low/100, memo.obsesA[o].data.high/100, memo.obsesA[o].style, null, memo.obsesA[o].popup ] ); | + | memo.dataA.push( [ |
+ | memo.obsesA[o].obsdatetime, | ||
+ | memo.obsesA[o].value, | ||
+ | memo.obsesA[o].data.low/100, | ||
+ | memo.obsesA[o].data.high/100, | ||
+ | memo.obsesA[o].style, | ||
+ | null, | ||
+ | memo.obsesA[o].popup | ||
+ | ] ); | ||
} | } | ||
Rivi 1 085: | Rivi 1 115: | ||
memo.options.vAxis.viewWindow.min = 80; | memo.options.vAxis.viewWindow.min = 80; | ||
memo.options.vAxis.viewWindow.max = 82; | memo.options.vAxis.viewWindow.max = 82; | ||
− | + | ||
− | |||
memo.chart = new google.visualization.LineChart( memo.chartEl[0] ); // document.getElementById(memo.id) | memo.chart = new google.visualization.LineChart( memo.chartEl[0] ); // document.getElementById(memo.id) | ||
drawChart(memo); | drawChart(memo); | ||
+ | } | ||
− | + | function addDataToTrendWithHighLowChart (memo) { | |
− | + | //console.log( 'high low chart'); | |
// do axis min and max | // do axis min and max | ||
Rivi 1 104: | Rivi 1 134: | ||
memo.data.addColumn( 'number', memo.obsMinYear + '-' + memo.obsMaxYear ); | memo.data.addColumn( 'number', memo.obsMinYear + '-' + memo.obsMaxYear ); | ||
+ | memo.data.addColumn( { id:'i0', type:'number', role:'interval' } ); | ||
+ | memo.data.addColumn( { id:'i0', type:'number', role:'interval' } ); | ||
memo.data.addColumn( {'type': 'string', 'role': 'style' } ); | memo.data.addColumn( {'type': 'string', 'role': 'style' } ); | ||
memo.data.addColumn( { type: 'string', role: 'annotation' } ); | memo.data.addColumn( { type: 'string', role: 'annotation' } ); | ||
Rivi 1 109: | Rivi 1 141: | ||
// series for trend line | // series for trend line | ||
− | memo.options.trendlines[0] = { labelInLegend: i18n['trendline'][memo.lang], tooltip: false, color: colors['trend'], lineWidth: 2, opacity: 0.5, type: 'linear', visibleInLegend: memo.trendType!='moving' }; | + | //memo.options.trendlines[0] = { labelInLegend: i18n['trendline'][memo.lang], tooltip: false, color: colors['trend'], lineWidth: 2, opacity: 0.5, type: 'linear', visibleInLegend: memo.trendType!='moving' }; |
+ | //console.log( memo ); | ||
for (var o in memo.obsesA) { | for (var o in memo.obsesA) { | ||
− | + | ||
− | + | dateStr = memo.obsesA[o].popup.match( /\([^)]*\)/g ); | |
− | + | yearStr = dateStr[0].match( /[0-9]{4}/g ); | |
− | + | memo.obsesA[o].popup = memo.obsesA[o].popup.replace( dateStr[0], '(' + yearStr[0] + ')' ); | |
− | + | memo.dataA.push( [ memo.obsesA[o].obsdatetime, memo.obsesA[o].value, memo.obsesA[o].data.low/100, memo.obsesA[o].data.high/100, memo.obsesA[o].style, null, memo.obsesA[o].popup ] ); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
Rivi 1 135: | Rivi 1 159: | ||
} | } | ||
− | memo.options.series[0] = {type: ' | + | memo.options.seriesType = 'line'; |
− | + | memo.options.series[0] = { type: 'line', pointSize: 3, color: '#3366cc' }; | |
+ | memo.options.curveType = 'function'; | ||
+ | memo.options.intervals = { 'style': 'area' }; | ||
+ | |||
+ | memo.options.vAxis.viewWindow.min = 80; | ||
+ | memo.options.vAxis.viewWindow.max = 82; | ||
+ | |||
+ | |||
+ | memo.chart = new google.visualization.LineChart( memo.chartEl[0] ); // document.getElementById(memo.id) | ||
+ | |||
drawChart(memo); | drawChart(memo); | ||
− | } | + | } |
− | function | + | function addDataToTrendChart(memo) { |
− | memo.axisMinDate = new Date( memo. | + | // do axis min and max |
+ | memo.axisMinDate = new Date(memo.obsMinDate.getTime()); | ||
+ | memo.axisMaxDate = new Date(memo.obsMaxDate.getTime()); | ||
+ | memo.axisMinDate.setMonth(0); | ||
+ | memo.axisMaxDate.setMonth(11); | ||
memo.axisMinDate.setDate(1); | memo.axisMinDate.setDate(1); | ||
− | + | memo.axisMaxDate.setDate(31); | |
− | |||
− | memo.axisMaxDate.setDate( | ||
− | memo. | + | memo.data.addColumn( 'number', memo.obsMinYear + '-' + memo.obsMaxYear ); |
− | memo. | + | memo.data.addColumn( {'type': 'string', 'role': 'style' } ); |
+ | memo.data.addColumn( { type: 'string', role: 'annotation' } ); | ||
+ | memo.data.addColumn( { type: 'string', role: 'tooltip', 'p': { 'html': true } } ); | ||
− | for | + | // series for trend line |
+ | memo.options.trendlines[0] = { labelInLegend: i18n['trendline'][memo.lang], tooltip: false, color: colors['trend'], lineWidth: 2, opacity: 0.5, type: 'linear', visibleInLegend: memo.trendType!='moving' }; | ||
− | |||
− | |||
− | |||
− | |||
− | for (var o in memo. | + | for (var o in memo.obsesA) { |
− | // | + | //dataRow = []; |
− | + | ||
− | + | //if (!!memo.obsesA[o].addInfo) { | |
+ | //dataArr.push( [ memo.obsesA[o].obsdatetime, memo.obsesA[o].value, 0, memo.obsesA[o].value, memo.obsesA[o].value, 'point { size: 5; fill-color: #0076b0; stroke-width: 2; stroke-color: ' + maintColors[memo.obsesA[o].maintainer] + '; }', '', memo.obsesA[o].popup ] ); | ||
+ | //memo.dataA.push( [ memo.obsesA[o].obsdatetime, memo.obsesA[o].value, 'point { size: 5; fill-color: #0076b0; stroke-width: 2; stroke-color: ' + maintColors[memo.obsesA[o].maintainer] + '; }', null, memo.obsesA[o].popup ] ); | ||
+ | memo.dataA.push( [ memo.obsesA[o].obsdatetime, memo.obsesA[o].value, memo.obsesA[o].style, null, memo.obsesA[o].popup ] ); | ||
+ | //} else { | ||
+ | //dataArr.push( [ memo.obsesA[o].obsdatetime, memo.obsesA[o].value, 0, memo.obsesA[o].value, memo.obsesA[o].value, 'point { size: 4; fill-color: #5893b0; stroke-width: 2; stroke-color: ' + maintColors[memo.obsesA[o].maintainer] + '; }', '', memo.obsesA[o].popup ] ); | ||
+ | //memo.dataA.push( [ memo.obsesA[o].obsdatetime, memo.obsesA[o].value, 'point { size: 4; fill-color: #5893b0; stroke-width: 2; stroke-color: ' + maintColors[memo.obsesA[o].maintainer] + '; }', null, memo.obsesA[o].popup ] ); | ||
+ | //} | ||
+ | |||
+ | //memo.dataA.push( dataRow ); | ||
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | memo.options.hAxis.ticks = []; | |
− | + | for (i=memo.axisMinDate.getFullYear(); i<=memo.axisMaxDate.getFullYear(); i++) { | |
− | + | middleOfYear = new Date( i, 6, 1 ); | |
− | + | memo.options.hAxis.ticks.push({v: middleOfYear, f: String(i) }); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | memo.options.series[0] = {type: 'scatter', pointSize: 6, color: '#3366cc' }; | |
− | + | ||
− | memo.options.series[ | + | drawChart(memo); |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | function addDataToSeasonChart(memo) { | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | memo.axisMinDate = new Date( memo.obsMinCompDateMs ); | |
− | + | memo.axisMinDate.setDate(1); | |
+ | memo.axisMaxDate = new Date( memo.obsMaxCompDateMs ); | ||
+ | memo.axisMaxDate.setMonth( memo.axisMaxDate.getMonth()+1 ); | ||
+ | memo.axisMaxDate.setDate(0); | ||
− | + | memo.seasonsO = {}; | |
− | + | memo.seasonsA = []; | |
− | |||
− | |||
− | |||
− | |||
− | + | for (var o in memo.obsesA) { | |
− | |||
− | + | s = memo.obsesA[o].seriesId; | |
− | memo. | + | if (typeof memo.seasonsO[s] == 'undefined' ) { memo.seasonsO[s] = { 'obses': [] }; } |
− | + | memo.seasonsO[s].obses.push( memo.obsesA[o] ); | |
+ | } | ||
− | + | for (var o in memo.seasonsO) { memo.seasonsA.push(o); } memo.seasonsA.sort( function(a,b) { return b-a; } ); | |
− | |||
− | |||
− | |||
− | + | // create cols for each series | |
+ | var sc = 0; | ||
+ | |||
+ | |||
+ | for (var s in memo.seasonsA) { | ||
− | + | // data | |
− | + | if ( memo.season == 'summer' ) { | |
− | + | memo.data.addColumn( 'number', memo.seasonsA[s].toString() ); | |
− | + | } else { | |
− | + | memo.data.addColumn( 'number', memo.seasonsA[s].toString() + '-' + (parseInt(memo.seasonsA[s])+1).toString() ); | |
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | // style | |
− | // | + | memo.data.addColumn( { type: 'string', role: 'style' } ); |
− | + | // tooltip | |
− | + | memo.data.addColumn( { type: 'string', role: 'tooltip', 'p': { 'html': true } } ); | |
− | + | // annotation | |
− | + | memo.data.addColumn( { type: 'string', role: 'annotation' } ); | |
− | + | ||
− | + | // add to series | |
− | + | if ( memo.seasonsA[s] == memo.curSeason ) { | |
− | + | if ( memo.type == 'cat' ) { | |
− | + | memo.options.series[sc++] = { type: 'scatter', curveType: 'function', color: colors['curObses'], XpointSize: 3, lineWidth: 0, visibleInLegend: true, hideThis: false, origSize: 10 }; | |
+ | } else { | ||
+ | if ( memo.obscode == 'secchi' ) { | ||
+ | //console.log('secchi'); | ||
+ | memo.options.series[sc++] = { type: 'area', curveType: 'function', color: colors['curObses'], pointSize: 3, lineWidth: 4, visibleInLegend: true, hideThis: false, origSize: 10 }; | ||
+ | } else { | ||
+ | memo.options.series[sc++] = { type: 'scatter', curveType: 'function', color: colors['curObses'], XpointSize: 3, lineWidth: 4, visibleInLegend: true, hideThis: false, origSize: 10 }; | ||
} | } | ||
− | |||
− | |||
− | |||
} | } | ||
+ | } else { | ||
+ | memo.options.series[sc++] = { type: 'scatter', curveType: 'function', color: colors['obses'], XpointSize: 5, lineWidth: 0, visibleInLegend: false, hideThis: true, origSize: 5 }; | ||
} | } | ||
+ | } | ||
− | + | // legend entry for timespan | |
+ | memo.data.addColumn( 'number', memo.obsMinDate.getFullYear() + '-' + memo.obsMaxDate.getFullYear() ); | ||
+ | memo.options.series[sc++] = { type: 'scatter', color: colors['obses'], pointSize: 5, visibleInLegend: true, hideThis: false }; | ||
− | + | // series for average | |
− | + | memo.data.addColumn( 'number', i18n['average'][memo.lang] ); | |
− | + | if ( i18n[memo.obscode].trend.layout == 'area') { | |
− | + | memo.options.series[sc++] = { type: 'area', curveType: 'function', lineWidth: 2, pointSize: 0, color: colors['average'], areaOpacity: 0.25, lineDashStyle: [2,2], enableInteractivity: false, visibleInLegend: memo.trendType=='moving' }; | |
− | + | } else { | |
− | + | memo.options.series[sc++] = { type: 'line', curveType: 'function', lineWidth: 3, pointSize: 5, color: colors['average'], dataOpacity: 0.75, lineDashStyle: [6,3], enableInteractivity: false, visibleInLegend: memo.trendType=='moving' }; | |
− | + | } | |
+ | memo.data.addColumn( { id: 'dev', type: 'number', role: 'interval' } ); | ||
+ | memo.data.addColumn( { id: 'dev', type: 'number', role: 'interval' } ); | ||
− | memo. | + | if ( memo.seasonsA.length == 1 && memo.seasonsA[0] == memo.curSeason ) { |
− | + | memo.options.series[ sc-1 ].lineWidth = 0; | |
− | + | memo.options.series[ sc-1 ].pointSize = 0; | |
− | + | memo.options.series[ sc-1 ].labelInLegend = false; | |
− | + | memo.options.intervals = { 'style':'none' }; | |
− | + | } | |
− | + | ||
+ | // series for trend line | ||
+ | memo.data.addColumn( 'number', 'trend' ); | ||
+ | //memo.options.trendlines[sc] = { labelInLegend: i18n['trendline'][memo.lang], tooltip: false, color: colors['trend'], lineWidth: 2, opacity: 0.5, type: 'polynomial', degree: 15, visibleInLegend: memo.trendType!='moving' }; | ||
+ | memo.options.series[sc++] = { type: 'scatter', pointSize: 0, enableInteractivity: false, visibleInLegend: false, hideThis: false }; | ||
− | + | // do average | |
+ | if (memo.trendType == 'gaussian') { | ||
− | + | memo.gSmoothing = 4; | |
− | + | if ( i18n[memo.obscode]['type'] == 'cat') { | |
− | + | memo.distF = 0.1; | |
− | + | } else { | |
+ | memo.distF = 0; | ||
+ | } | ||
− | + | // sort according to compare date | |
− | memo. | + | memo.obsesA.sort( function( a, b ) { return a.compareDate - b.compareDate; }); |
− | |||
− | for ( var | + | // make week averages |
+ | memo.avgW = {}; | ||
+ | for (var o in memo.obsesA) { | ||
− | + | mwDate = new Date( memo.obsesA[o].compareDate.getFullYear(), memo.obsesA[o].compareDate.getMonth(), memo.obsesA[o].compareDate.getDate() ); | |
− | + | y = mwDate.getFullYear(); | |
+ | w = mwDate.getWeek(); | ||
+ | v = memo.obsesA[o].value + memo.distF*Math.random() - memo.distF*Math.random(); | ||
− | if ( y == | + | if ( typeof memo.avgW[y] == 'undefined' ) { memo.avgW[y] = {}; } |
− | |||
− | + | if ( typeof memo.avgW[y][w] == 'undefined' ) { | |
− | + | mwDate.setDate( mwDate.getDate() - mwDate.getDay() + 3 ) | |
− | + | memo.avgW[y][w] = { cDate: mwDate, values: [ v ], sum: v, count: 1, avg: v }; | |
− | + | } else { | |
− | + | memo.avgW[y][w].values.push( v ); | |
− | + | memo.avgW[y][w].sum += v; | |
− | memo. | + | memo.avgW[y][w].count++; |
− | + | memo.avgW[y][w].avg = memo.avgW[y][w].sum / memo.avgW[y][w].count; | |
− | + | } | |
+ | } | ||
+ | |||
+ | // calculate standard deviation | ||
+ | devSum = 0; | ||
+ | devC = 0; | ||
+ | devMax = 0; | ||
+ | for ( var y in memo.avgW ) { | ||
+ | for ( var w in memo.avgW[y] ) { | ||
+ | devC++; | ||
+ | devx = 0; | ||
+ | for (var vi in memo.avgW[y][w].values ) { | ||
+ | devx += Math.pow( (memo.avgW[y][w].values[vi] - memo.avgW[y][w].avg), 2 ); | ||
+ | } | ||
+ | memo.avgW[y][w].dev = Math.sqrt( devx/memo.avgW[y][w].count ); | ||
+ | devSum += memo.avgW[y][w].dev; | ||
+ | devMax = Math.max( memo.avgW[y][w].dev, devMax ); | ||
+ | } | ||
+ | } | ||
+ | devAvg = devSum/devC; | ||
− | + | for ( var y in memo.avgW ) { | |
− | memo. | + | for ( var w in memo.avgW[y] ) { |
+ | if ( memo.avgW[y][w].count < 5 ) { | ||
+ | //memo.avgW[y][w].dev = Math.max( memo.avgW[y][w].dev, devAvg ); | ||
+ | } | ||
+ | } | ||
+ | } | ||
− | + | memo.avgWlist = []; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | for ( var y in memo.avgW ) { | |
− | + | for ( var w in memo.avgW[y] ) { | |
− | + | memo.avgWlist.push( { y: parseInt(y), w: parseInt(w), avg: memo.avgW[y][w].avg, dev: memo.avgW[y][w].dev } ); | |
− | + | } | |
− | + | } | |
− | + | memo.avgWlist.sort( function(a, b) { return (a.y*100+a.w) - (b.y*100+b.w); }); | |
− | + | firstY = memo.avgWlist[0].y; | |
− | + | firstW = memo.avgWlist[0].w; | |
− | + | lastY = memo.avgWlist[memo.avgWlist.length-1].y; | |
+ | lastW = memo.avgWlist[memo.avgWlist.length-1].w; | ||
− | + | memo.avgMlist = []; | |
+ | memo.avgLlist = []; | ||
+ | memo.avgHlist = []; | ||
− | for ( var | + | for ( var y=firstY; y<=lastY; y++ ) { |
− | if ( | + | if ( y == firstY ) { w1 = firstW; } |
+ | else { w1 = 1; } | ||
− | + | if ( y == lastY ) { w2 = lastW; } | |
− | + | else { w2 = 52; } | |
− | |||
− | + | for ( var w=w1; w<=w2; w++) { | |
− | + | //console.log( y + '/' + w ); | |
− | + | if ( typeof(memo.avgW[y][w]) == 'undefined' ) { | |
− | |||
− | |||
− | + | memo.avgMlist.push( null ); | |
− | + | memo.avgLlist.push( null ); | |
− | + | memo.avgHlist.push( null ); | |
− | |||
− | |||
− | |||
− | + | } else { | |
− | + | memo.avgMlist.push( memo.avgW[y][w].avg ); | |
− | + | ||
+ | if ( memo.avgW[y][w].count < 2 ) { | ||
+ | d = Math.max( devMax, memo.avgW[y][w].dev ); | ||
+ | } else if ( memo.avgW[y][w].count < 4 ) { | ||
+ | d = Math.max( devAvg, memo.avgW[y][w].dev ); | ||
+ | } else { | ||
+ | d = memo.avgW[y][w].dev; | ||
+ | } | ||
− | + | if ( i18n[memo.obscode].type == 'cat' && ( memo.avgW[y][w].avg - 2*memo.avgW[y][w].dev ) < -memo.distF ) { | |
+ | memo.avgLlist.push( -memo.distF*Math.random()*2 ); | ||
+ | } else { | ||
+ | memo.avgLlist.push( memo.avgW[y][w].avg - 2*d ); //memo.avgW[y][w].dev ); | ||
+ | } | ||
− | } | + | memo.avgHlist.push( memo.avgW[y][w].avg + 2*d ); //memo.avgW[y][w].dev ); |
+ | } | ||
+ | } | ||
+ | } | ||
− | + | //console.log(memo.avgLlist); | |
− | + | for ( var i=0; i<memo.avgMlist.length; i++ ) { | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | if ( memo.avgMlist[i] === null ) { | |
− | |||
− | memo. | + | lastM = memo.avgMlist[i-1]; |
− | memo.avgLlist. | + | lastL = memo.avgLlist[i-1]; |
+ | lastH = memo.avgHlist[i-1]; | ||
− | + | for ( var ix=(i+1); ix < memo.avgMlist.length; ix++ ) { | |
− | |||
− | |||
− | + | if ( memo.avgMlist[ix] !== null ) { | |
− | + | memo.avgMlist[i] = lastM + (memo.avgMlist[ix]-lastM) / (ix-i+1); | |
− | + | memo.avgLlist[i] = lastL + (memo.avgLlist[ix]-lastL) / (ix-i+1); | |
− | + | memo.avgHlist[i] = lastH + (memo.avgHlist[ix]-lastH) / (ix-i+1); | |
− | + | break; | |
− | + | } | |
− | + | } | |
+ | } | ||
+ | } | ||
+ | |||
+ | if ( memo.avgMlist.length >= 52 ) { | ||
+ | |||
+ | memo.avgMlist = memo.avgMlist.slice( memo.avgMlist.length - memo.gSmoothing/2 - 2 ).concat( memo.avgMlist ).concat( memo.avgMlist.slice( 0, memo.gSmoothing/2 + 2 ) ); | ||
+ | memo.avgLlist = memo.avgLlist.slice( memo.avgLlist.length - memo.gSmoothing/2 - 2 ).concat( memo.avgLlist ).concat( memo.avgLlist.slice( 0, memo.gSmoothing/2 + 2 ) ); | ||
+ | memo.avgHlist = memo.avgHlist.slice( memo.avgHlist.length - memo.gSmoothing/2 - 2 ).concat( memo.avgHlist ).concat( memo.avgHlist.slice( 0, memo.gSmoothing/2 + 2 ) ); | ||
+ | |||
+ | //console.log( memo.avgMlist ); | ||
+ | |||
+ | } else { | ||
− | + | for (var x=0; x < ( memo.gSmoothing/2 + 3 ); x++) { | |
− | + | if ( memo.obscode == 'secchi' ) { | |
− | + | prev = Math.max ( memo.avgMlist[0], 0 ); | |
− | + | next = Math.max ( memo.avgMlist[memo.avgMlist.length-1], 0 ); | |
− | + | } else { | |
− | + | prev = Math.max ( 2 * memo.avgMlist[0] - memo.avgMlist[1], 0 ); | |
− | + | next = Math.max ( 2 * memo.avgMlist[memo.avgMlist.length-1] - memo.avgMlist[memo.avgMlist.length-2], 0 ); | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | memo.avgMlist.unshift( prev ); | |
− | + | memo.avgMlist.push( next ); | |
− | |||
− | |||
− | + | memo.avgLlist.unshift( prev - 2 * devAvg ); | |
− | + | memo.avgLlist.push( next - 2 * devAvg ); | |
− | + | memo.avgHlist.unshift( prev + 2 * devAvg ); | |
− | + | memo.avgHlist.push( next + 2 * devAvg ); | |
+ | } | ||
− | + | } | |
− | + | memo.avgMsmooth = smooth( memo.avgMlist, memo.gSmoothing ); | |
+ | memo.avgLsmooth = smooth( memo.avgLlist, memo.gSmoothing ); | ||
+ | memo.avgHsmooth = smooth( memo.avgHlist, memo.gSmoothing ); | ||
− | + | cc = memo.data.getNumberOfColumns(); | |
− | + | msW = 7*24*60*60*1000; | |
− | + | for ( var i=0; i < ( memo.avgMsmooth.length ); i++ ) { | |
− | |||
− | // | + | // put data into dataArr |
− | dataRow[ | + | dataRow = []; |
− | + | for (var e=0; e<cc; e++) { dataRow.push( null ); } | |
− | / | + | |
− | if ( memo. | + | xdate = new Date( memo.avgW[firstY][firstW].cDate.getTime() + ( i + 1 - memo.gSmoothing/2 ) * msW ); |
− | dataRow[ | + | if ( xdate.getTime() < memo.axisMinDate.getTime() ) { |
+ | dataRow[0] = memo.axisMinDate; | ||
+ | } else if ( xdate.getTime() > memo.axisMaxDate.getTime() ) { | ||
+ | dataRow[0] = memo.axisMaxDate; | ||
} else { | } else { | ||
− | dataRow[ | + | dataRow[0] = xdate; //new Date( memo.avgW[firstY][firstW].cDate.getTime() + ( i + 1 - memo.gSmoothing/2 ) * msW ); |
} | } | ||
− | dataRow[ | + | |
− | + | dataRow[cc-4] = memo.avgMsmooth[i]; | |
− | + | ||
− | if ( | + | if ( memo.obscode == 'level' ) { |
− | + | dataRow[cc-3] = memo.avgLsmooth[i]; | |
− | + | } else { | |
− | + | dataRow[cc-3] = Math.max( memo.avgLsmooth[i], 0 ); | |
− | |||
− | |||
− | |||
− | dataRow[ | ||
− | } else { | ||
− | dataRow[ | ||
} | } | ||
+ | dataRow[cc-2] = memo.avgHsmooth[i]; | ||
− | memo.dataA.push( dataRow ); | + | memo.dataA.push( dataRow ); |
+ | } | ||
+ | |||
+ | } else if (memo.trendType == 'moving') { | ||
− | } | + | // |
+ | } | ||
− | + | // add data to table | |
+ | cc = memo.data.getNumberOfColumns(); | ||
− | // | + | for (var s in memo.seasonsA) { |
+ | |||
+ | //console.log( s ); | ||
− | + | for (var o in memo.seasonsO[memo.seasonsA[s]].obses) { | |
− | |||
− | |||
− | + | obs = memo.seasonsO[memo.seasonsA[s]].obses[o]; | |
− | |||
− | |||
− | |||
− | |||
− | + | dataRow = []; | |
− | |||
− | |||
− | + | // fill row with nulls | |
+ | for (var i=0; i<cc; i++) { dataRow.push( null ); } | ||
− | + | // x axis value | |
− | + | dataRow[0] = obs.compareDate; | |
− | + | // data for series cols | |
− | + | if ( memo.seasonsA[s] == memo.curSeason ) { | |
− | + | dataRow[s*4+1] = obs.value; | |
− | + | } else { | |
+ | //console.log( memo.distF ); | ||
+ | dataRow[s*4+1] = obs.value + memo.distF*Math.random() - memo.distF*Math.random(); | ||
+ | } | ||
+ | dataRow[s*4+2] = obs.style; | ||
+ | dataRow[s*4+3] = obs.popup; | ||
+ | |||
+ | if ( ( today.getTime() - obs.compareDate.getTime() < 10*24*60*60*1000 ) && s == 0 && o == ( memo.seasonsO[memo.seasonsA[s]].obses.length - 1 ) ) { | ||
+ | |||
+ | //var diff = obs.value - memo.avgW[ obs.compareDate.getFullYear() ][ obs.compareDate.getWeek() ].avg; | ||
+ | //var diff = Math.round( diff*100 ); | ||
+ | //var diffStr = diff.toString() + ' cm'; | ||
+ | //if ( diff > 0 ) { diffStr = '+' + diffStr; } | ||
− | + | dataRow[s*4+4] = null; //diffStr; //annotation | |
+ | } else { | ||
+ | dataRow[s*4+4] = null; //annotation | ||
+ | } | ||
− | + | memo.dataA.push( dataRow ); | |
− | memo. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | } | |
− | + | } | |
− | + | // make ticks for x axis | |
− | |||
− | |||
− | + | var minM = memo.axisMinDate.getMonth(); | |
+ | var minY = memo.axisMinDate.getFullYear(); | ||
+ | var maxM = memo.axisMaxDate.getMonth(); | ||
− | + | if (maxM < minM) { | |
+ | mCount = 13 - minM + maxM; // 13-10+4 = 1+4 | ||
+ | } else { | ||
+ | mCount = maxM - minM + 1; | ||
+ | } | ||
− | + | memo.options.hAxis.viewWindow.min = memo.axisMinDate; | |
− | + | memo.options.hAxis.viewWindow.max = memo.axisMaxDate; | |
− | + | memo.options.hAxis.ticks = []; | |
− | + | for (i=0; i<mCount; i++) { | |
− | + | m = minM + i; | |
− | + | maxY = minY; | |
− | + | if (m > 11) { | |
− | + | m = minM + i - 12; | |
+ | maxY++; | ||
+ | } | ||
− | + | middleOfMonth = new Date( maxY, m, 16 ); | |
− | if ( | + | if (mCount < 5) { |
+ | memo.options.hAxis.ticks.push({v: middleOfMonth, f: i18n.months[m]['long'][memo.lang] }); | ||
+ | } else if ( mCount < 10 ) { | ||
+ | memo.options.hAxis.ticks.push({v: middleOfMonth, f: i18n.months[m]['short'][memo.lang] }); | ||
+ | } else { | ||
+ | memo.options.hAxis.ticks.push({v: middleOfMonth, f: i18n.months[m]['roman'] }); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | drawChart(memo); | ||
− | + | } | |
− | + | function drawChart(memo) { | |
− | + | ||
− | + | memo.loaderEl.fadeOut( "slow", function() { memo.loaderEl.remove(); } ); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | if (memo.dataA.length > 0) { | |
− | + | ||
− | + | memo.data.addRows(memo.dataA); | |
− | + | ||
− | + | if ( typeof memo.chart == 'undefined' ) { | |
− | + | memo.chart = new google.visualization.ComboChart( memo.chartEl[0] ); // document.getElementById(memo.id) | |
− | + | } | |
− | + | ||
− | + | //doResize(); | |
+ | |||
+ | memo.fullscreenEl.fadeIn( "slow" ); | ||
+ | if ( memo.download) { memo.downloadEl.fadeIn( "slow" ); } | ||
+ | |||
+ | memo.selectedCol = 0; | ||
+ | google.visualization.events.addListener( memo.chart, 'select', function () { | ||
+ | |||
+ | var selection = memo.chart.getSelection(); | ||
− | + | if (selection.length > 0) { | |
− | + | var col = selection[0].column; | |
− | for (var c in memo.options.series) { | + | for (var c in memo.options.series) { |
if (memo.options.series[c].hideThis) { | if (memo.options.series[c].hideThis) { | ||
memo.options.series[c].lineWidth = 0; | memo.options.series[c].lineWidth = 0; | ||
Rivi 1 575: | Rivi 1 642: | ||
memo.options.series[c].visibleInLegend = false; | memo.options.series[c].visibleInLegend = false; | ||
} | } | ||
− | } | + | } |
+ | |||
+ | if (col != memo.selectedCol && memo.options.series[(col-1)/4].hideThis) { | ||
+ | memo.selectedCol = col; | ||
+ | memo.options.series[(col-1)/4].lineWidth = 3; | ||
+ | //memo.options.series[(col-1)/4].pointSize = 12; | ||
+ | memo.options.series[(col-1)/4].color = colors['selObses']; | ||
+ | memo.options.series[(col-1)/4].visibleInLegend = true; | ||
+ | } else { | ||
+ | memo.selectedCol = 0; | ||
+ | } | ||
+ | |||
+ | } else { | ||
+ | |||
+ | memo.selectedCol = 0; | ||
+ | |||
+ | for (var c in memo.options.series) { | ||
+ | if (memo.options.series[c].hideThis) { | ||
+ | memo.options.series[c].lineWidth = 0; | ||
+ | //memo.options.series[c].pointSize = memo.options.series[c].origSize; | ||
+ | memo.options.series[c].color = colors['obses']; | ||
+ | memo.options.series[c].visibleInLegend = false; | ||
+ | } | ||
+ | } | ||
} | } | ||
Rivi 1 641: | Rivi 1 731: | ||
}); | }); | ||
− | // move current observations to top | + | // move current observations to top |
gEl = jQuery( document.getElementById(memo.id) ).find( 'svg' ).append( 'g' ); | gEl = jQuery( document.getElementById(memo.id) ).find( 'svg' ).append( 'g' ); | ||
− | jQuery( document.getElementById(memo.id) ).find( 'path[stroke="#3366cc"]' ).detach().appendTo( gEl ); | + | jQuery( document.getElementById(memo.id) ).find( 'path[stroke="#3366cc"]' ).detach().appendTo( gEl ); |
jQuery( document.getElementById(memo.id) ).find( 'circle[fill="#3366cc"]' ).detach().appendTo( gEl ); | jQuery( document.getElementById(memo.id) ).find( 'circle[fill="#3366cc"]' ).detach().appendTo( gEl ); | ||
jQuery( document.getElementById(memo.id) ).find( 'circle[stroke-width="3"]' ).each( function() { jQuery( this ).parent().append( jQuery( this ) ); }); | jQuery( document.getElementById(memo.id) ).find( 'circle[stroke-width="3"]' ).each( function() { jQuery( this ).parent().append( jQuery( this ) ); }); | ||
Rivi 1 651: | Rivi 1 741: | ||
//wait(); | //wait(); | ||
if ( typeof memo.chartEl != 'undefined' ) { | if ( typeof memo.chartEl != 'undefined' ) { | ||
− | setTimeout( wait, | + | setTimeout( wait, 500 ); |
} | } | ||
Rivi 1 711: | Rivi 1 801: | ||
'season': { 'winter': { 'fi': 'Talvi', 'en': 'Winter', 'sv': 'Vintern' } }, | 'season': { 'winter': { 'fi': 'Talvi', 'en': 'Winter', 'sv': 'Vintern' } }, | ||
'dec': { 'fi': ',', 'en': '.', 'sv': ',' }, | 'dec': { 'fi': ',', 'en': '.', 'sv': ',' }, | ||
− | 'sep': { 'fi': ' | + | 'sep': { 'fi': ';', 'en': ';', 'sv': ';' }, |
+ | 'obs': { | ||
+ | 'type': 'num', | ||
+ | 'season': 'summer', | ||
+ | 'trend': { 'type': 'gaussian', 'layout': 'line' }, | ||
+ | 'title': { 'fi': '', 'en': '', 'sv': '', 'ru': '' }, | ||
+ | 'unit': '', | ||
+ | 'axisTitleV': { 'fi': '', 'en': '', 'sv': '', 'ru': '' } | ||
+ | }, | ||
'alg': { | 'alg': { | ||
'type': 'cat', | 'type': 'cat', | ||
Rivi 1 726: | Rivi 1 824: | ||
'type': 'num', | 'type': 'num', | ||
'season': 'summer', | 'season': 'summer', | ||
− | + | 'min': 0, | |
'trend': { 'type': 'gaussian', 'layout': 'line' }, | 'trend': { 'type': 'gaussian', 'layout': 'line' }, | ||
'title': { 'fi': 'Pintaveden lämpötila', 'en': 'Surface water termperature', 'sv': 'Ytvattentemperatur', 'ru': '???' }, | 'title': { 'fi': 'Pintaveden lämpötila', 'en': 'Surface water termperature', 'sv': 'Ytvattentemperatur', 'ru': '???' }, | ||
Rivi 1 766: | Rivi 1 864: | ||
'snow_load': { | 'snow_load': { | ||
'catName': 'Lumikuorma', | 'catName': 'Lumikuorma', | ||
+ | 'valfield': 'load', | ||
'type': 'num', | 'type': 'num', | ||
'season': 'winter', | 'season': 'winter', | ||
'min': 0, | 'min': 0, | ||
− | 'trend': { 'type': ' | + | 'trend': { 'type': 'gaussian', 'layout': 'line' }, |
'title': { 'fi': 'Lumikuorma', 'en': 'Snow load', 'sv': 'Snöbelastning', 'ru': '???' }, | 'title': { 'fi': 'Lumikuorma', 'en': 'Snow load', 'sv': 'Snöbelastning', 'ru': '???' }, | ||
'unit': 'kg/m²', | 'unit': 'kg/m²', | ||
'axisTitleV': { 'fi': 'Lumikuorma, kg/m²', 'en': 'Snow load, kg/m²', 'sv': 'Snöbelastning, kg/m²', 'ru': 'm' } | 'axisTitleV': { 'fi': 'Lumikuorma, kg/m²', 'en': 'Snow load, kg/m²', 'sv': 'Snöbelastning, kg/m²', 'ru': 'm' } | ||
+ | }, | ||
+ | 'snow': { | ||
+ | 'catName': 'Lumen syvyys', | ||
+ | 'type': 'num', | ||
+ | 'season': 'winter', | ||
+ | 'min': 0, | ||
+ | 'trend': { 'type': 'gaussian', 'layout': 'line' }, | ||
+ | 'title': { 'fi': 'Lumipeitteen paksuus', 'en': 'Snow cover depth', 'sv': 'Snötäckets tjockhet', 'ru': '???' }, | ||
+ | 'unit': 'cm', | ||
+ | 'axisTitleV': { 'fi': 'Lumipeite, cm', 'en': 'Snow cover, cm', 'sv': 'Snötäcket, cm', 'ru': 'm' } | ||
}, | }, | ||
'ptot': { | 'ptot': { | ||
Rivi 1 805: | Rivi 1 914: | ||
}, | }, | ||
'o2s': { | 'o2s': { | ||
− | 'type': 'num', | + | 'type': 'num', |
− | 'season': 'summer', | + | 'season': 'summer', |
− | 'min': 0, | + | 'min': 0, |
− | 'direction': 1, | + | 'direction': 1, |
− | 'trend': { 'type': 'regression', 'layout': 'line' }, | + | 'trend': { 'type': 'regression', 'layout': 'line' }, |
− | 'title': { 'fi': 'Hapen kyllästysaste', 'en': 'Oxygen saturation', 'sv': 'Syremättnad', 'ru': '???' }, | + | 'title': { 'fi': 'Hapen kyllästysaste', 'en': 'Oxygen saturation', 'sv': 'Syremättnad', 'ru': '???' }, |
− | 'unit': '%', | + | 'unit': '%', |
− | 'axisTitleV': { 'fi': 'Hapen kyllästysaste, %', 'en': 'Oxygen saturation, %', 'sv': 'Syremättnad, %', 'ru': '%' } | + | 'axisTitleV': { 'fi': 'Hapen kyllästysaste, %', 'en': 'Oxygen saturation, %', 'sv': 'Syremättnad, %', 'ru': '%' } |
− | }, | + | }, |
− | 'secchi': { | + | 'secchi': { |
− | 'type': 'num', | + | 'type': 'num', |
− | 'season': 'summer', | + | 'season': 'summer', |
− | 'min': 0, | + | 'min': 0, |
− | 'direction': | + | 'direction': 1, |
− | 'trend': { 'type': 'gaussian', 'layout': 'line' }, | + | 'trend': { 'type': 'gaussian', 'layout': 'line' }, |
− | 'title': { 'fi': 'Näkösyvyys', 'en': 'Water transparency', 'sv': 'Siktdjupet', 'ru': '???' }, | + | 'title': { 'fi': 'Näkösyvyys', 'en': 'Water transparency', 'sv': 'Siktdjupet', 'ru': '???' }, |
− | 'unit': 'm', | + | 'unit': 'm', |
− | 'axisTitleV': { 'fi': 'Näkösyvyys, m', 'en': 'Secchi depth, m', 'sv': 'Siktdjupet, m', 'ru': 'm' } | + | 'axisTitleV': { 'fi': 'Näkösyvyys, m', 'en': 'Secchi depth, m', 'sv': 'Siktdjupet, m', 'ru': 'm' } |
+ | }, | ||
+ | 'level': { | ||
+ | 'title': { 'fi': 'Vedenkorkeus', 'en': 'Water level', 'sv': 'Vattenståndpunkt', 'ru': '???' }, | ||
+ | 'title2': { 'fi': 'Vedenkorkeus', 'en': '???', 'sv': '???', 'ru': '???' }, | ||
+ | 'type': 'num', | ||
+ | 'season': 'summer', | ||
+ | 'trend': { 'type': 'gaussian', 'layout': 'line' }, | ||
+ | 'unit': 'm', | ||
+ | 'axisTitleV': { 'fi': 'Vedenpinnan korkeus, m', 'en': 'Water level, m', 'sv': 'Vattennivå, m', 'ru': 'm' } | ||
+ | }, | ||
+ | 'avglevelsy': { | ||
+ | 'title': { 'fi': 'Keskivedenkorkeus', 'en': '', 'sv': '', 'ru': '???' }, | ||
+ | 'title2': { 'fi': 'Vedenkorkeus', 'en': '???', 'sv': '???', 'ru': '???' }, | ||
+ | 'type': 'num', | ||
+ | 'season': 'summer', | ||
+ | 'trend': { 'type': 'gaussian', 'layout': 'line' }, | ||
+ | 'unit': 'm', | ||
+ | 'axisTitleV': { 'fi': 'Vuosikeskiarvo, m', 'en': 'Water level, m', 'sv': 'Vattennivå, m', 'ru': 'm' } | ||
}, | }, | ||
− | ' | + | 'avglevelsw': { |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
'title': { 'fi': 'Keskivedenkorkeus', 'en': '', 'sv': '', 'ru': '???' }, | 'title': { 'fi': 'Keskivedenkorkeus', 'en': '', 'sv': '', 'ru': '???' }, | ||
'title2': { 'fi': 'Vedenkorkeus', 'en': '???', 'sv': '???', 'ru': '???' }, | 'title2': { 'fi': 'Vedenkorkeus', 'en': '???', 'sv': '???', 'ru': '???' }, | ||
Rivi 1 841: | Rivi 1 959: | ||
'unit': 'm', | 'unit': 'm', | ||
'axisTitleV': { 'fi': 'Vuosikeskiarvo, m', 'en': 'Water level, m', 'sv': 'Vattennivå, m', 'ru': 'm' } | 'axisTitleV': { 'fi': 'Vuosikeskiarvo, m', 'en': 'Water level, m', 'sv': 'Vattennivå, m', 'ru': 'm' } | ||
− | }, | + | }, |
'ski': { | 'ski': { | ||
'title': { 'fi': 'Hiihto', 'en': 'Skiing', 'sv': '', 'ru': '???' }, | 'title': { 'fi': 'Hiihto', 'en': 'Skiing', 'sv': '', 'ru': '???' }, | ||
Rivi 1 856: | Rivi 1 974: | ||
'ValueUnit': { 'fi': 'Arvon tyyppi', 'en': 'Value type', 'sv': 'Värdes typ', 'ru': '???' }, | 'ValueUnit': { 'fi': 'Arvon tyyppi', 'en': 'Value type', 'sv': 'Värdes typ', 'ru': '???' }, | ||
'Date': { 'fi': 'Päivämäärä', 'en': 'Date', 'sv': 'Datum', 'ru': '???' }, | 'Date': { 'fi': 'Päivämäärä', 'en': 'Date', 'sv': 'Datum', 'ru': '???' }, | ||
+ | 'Time': { 'fi': 'Kellonaika', 'en': 'Time', 'sv': 'Tid', 'ru': '???' }, | ||
'Additionalinfo': { 'fi': 'Lisätiedot', 'en': 'Additional info', 'sv': 'Tillägsinformation', 'ru': '???' }, | 'Additionalinfo': { 'fi': 'Lisätiedot', 'en': 'Additional info', 'sv': 'Tillägsinformation', 'ru': '???' }, | ||
'Image': { 'fi': 'Valokuva', 'en': 'Image', 'sv': 'Bild', 'ru': '???' }, | 'Image': { 'fi': 'Valokuva', 'en': 'Image', 'sv': 'Bild', 'ru': '???' }, |