Ero sivun ”Widget:XJwCharts” versioiden välillä
Järvi-meriwikistä
(123 välissä olevaa versiota samalta käyttäjältä ei näytetä) | |||
Rivi 5: | Rivi 5: | ||
<script type="text/javascript" src="https://www.jarviwiki.fi/citobsjs/jwapi.js"></script> | <script type="text/javascript" src="https://www.jarviwiki.fi/citobsjs/jwapi.js"></script> | ||
− | <script type="text/javascript"> | + | <script type="text/javascript"> |
− | google.charts.load( 'current', { 'packages':[ 'corechart' ] } ); | + | google.charts.load( 'current', { 'packages':[ 'corechart' ], 'language': 'fi' } ); |
google.charts.setOnLoadCallback( checkforjqready ); | google.charts.setOnLoadCallback( checkforjqready ); | ||
Rivi 19: | Rivi 19: | ||
function readytogo() { | function readytogo() { | ||
− | + | ||
− | + | jQuery( '.jwChartWidget' ).each( function() { | |
+ | |||
+ | var memo = { 'now': new Date() }; | ||
+ | |||
+ | memo.widgetEl = jQuery( this ); | ||
+ | if ( typeof memo.widgetEl.prop( 'id' ) == 'undefined' ) { memo.widgetEl.prop( 'id', 'jwChartWidget_' + memo.now.getTime() ); } | ||
+ | memo.widgetEl.css( 'position', 'relative' ); | ||
+ | |||
+ | memo.lang = memo.widgetEl.attr( 'data-lang' ); if (typeof memo.lang == 'undefined') { memo.lang = 'fi'; } | ||
+ | memo.obscode = memo.widgetEl.attr( 'data-obscode' ); if (typeof memo.obscode == 'undefined') { memo.lang = 'ice'; }; | ||
+ | memo.siteid = memo.widgetEl.attr( 'data-siteid' ); //'284245'; //'240829'; //'284245'; | ||
+ | |||
+ | // add chart container | ||
+ | memo.widgetEl.append( '<div class="jwChartContainer" style="position: absolute; z-index: 110; width: 100%; height: 100%;"></div>' ); | ||
+ | memo.chartEl = memo.widgetEl.find( '.jwChartContainer' ); | ||
+ | |||
+ | memo.widgetEl.append( '<div style="display: none;" class="jwloading"></div>' ); | ||
+ | memo.loadingEl = memo.widgetEl.find( '.jwloading' ); | ||
+ | |||
+ | // add fullscreen button | ||
+ | //memo.widgetEl.append( '<div class="obschartbutton fullscreen-button" style="Xdisplay: none; position: absolute; z-index: 120; float: right; top: 40px; right: 1.5px; background-color: rgba( 255, 255, 255, .9 ); border-radius: 50%; border: 1px solid rgba( 230, 230, 230, 0.75 ); width: 24px; height: 24px; padding: 0;"><button title="fullscreen" style="width: 24px; height: 24px; padding: 0; margin: 0; background: none; border: none; background-image: url( //www.jarviwiki.fi/widgets/img/fullscreen_16px.png ); background-size: 50%; background-position: center; background-repeat: no-repeat; "></button></div>' ); | ||
+ | memo.widgetEl.append( '<div class="obschartbutton fullscreen-button" style="Xdisplay: none; position: absolute; z-index: 120; float: right; top: 40px; right: 1.5px; background-color: rgba( 255, 255, 255, .9 ); border-radius: 50%; border: 1px solid rgba( 230, 230, 230, 0.75 ); width: 24px; height: 24px; padding: 0;"><button title="fullscreen" style="width: 24px; height: 24px; padding: 0; margin: 0; background: none; border: none; "><i class="fas fa-expand"></i></button></div>' ); | ||
+ | memo.fullscreenEl = jQuery( this ).find( '.fullscreen-button' ); | ||
+ | |||
+ | // add download data button | ||
+ | memo.widgetEl.append( '<div class="obschartbutton download-button" style="display: none; position: absolute; z-index: 120; float: right; top: 70px; right: 1.5px; background-color: rgba( 255, 255, 255, .9 ); border-radius: 50%; border: 1px solid rgba( 230, 230, 230, 0.75 ); width: 24px; height: 24px; padding: 0;"><button title="' + i18n['download'][memo.lang] + '" style="width: 24px; height: 24px; padding: 0; margin: 0; background: none; border: none;"><i class="fas fa-download"></i></button></div>' ); | ||
+ | memo.downloadEl = jQuery( this ).find( '.download-button' ); | ||
− | + | memo.jw = new jwApi(); | |
− | + | memo.loadingEl.show( 'slow' ); | |
− | + | ||
− | + | memo.jw.loadObses( { 'obscode': memo.obscode, 'siteid': memo.siteid, 'custom': '[[Jäätilanne::2||5]]' }, function( o ) { | |
+ | obsesReady( memo ); | ||
+ | }); | ||
+ | |||
+ | |||
+ | function obsesReady( memo ) { | ||
+ | |||
+ | // margin settings | ||
+ | memo.margins = { top: 0, right: 25, bottom: 60, left: 60 }; | ||
+ | |||
+ | if ( typeof i18n[ memo.obscode ].direction != 'undefined' ) { memo.vaxisdir = i18n[ memo.obscode ].direction; } else { memo.vaxisdir = 1; } | ||
+ | |||
+ | // defaults for all charts | ||
+ | memo.options = { | ||
+ | title: i18n[memo.obscode]['title'][memo.lang], | ||
+ | //titleTextStyle: { fontSize: 14 }, | ||
+ | backgroundColor: 'transparent', | ||
+ | chartArea: { top: memo.margins.top, left: memo.margins.left, width: (memo.widgetEl.width() - memo.margins.left - memo.margins.right), height: (memo.widgetEl.height() - memo.margins.top - memo.margins.bottom), backgroundColor: { fill: '#daf0fa', stroke: '#fff', strokeWidth: 6 }}, | ||
+ | legend: { position: 'bottom' }, | ||
+ | crosshair: { trigger: 'both' }, | ||
+ | tooltip: { isHtml: true }, | ||
+ | seriesType: 'scatter', | ||
+ | interpolateNulls: true, | ||
+ | |||
+ | vAxis: { | ||
+ | title: i18n[memo.obscode]['axisTitleV'][memo.lang], | ||
+ | titleTextStyle: { bold: true }, | ||
+ | slantedText: false, | ||
+ | maxAlternation: 1, | ||
+ | direction: memo.vaxisdir, | ||
+ | gridlines: { color: '#fff' }, | ||
+ | minorGridlines: { count: 0 }, | ||
+ | viewWindow: { } | ||
+ | }, | ||
+ | hAxis: { | ||
+ | title: '', | ||
+ | slantedText: false, | ||
+ | maxAlternation: 1, | ||
+ | gridlines: { color: '#fff' }, | ||
+ | minorGridlines: { count: 0 }, | ||
+ | viewWindow: { } | ||
+ | }, | ||
+ | series: [ ], | ||
+ | trendlines: [ ] | ||
+ | }; | ||
+ | |||
+ | memo.obsesTotal = 0; | ||
+ | memo.obsMinValue = Infinity; | ||
+ | memo.obsMaxValue = -Infinity; | ||
+ | memo.obsMinDateMs = Infinity; | ||
+ | memo.obsMaxDateMs = -Infinity; | ||
+ | memo.obsMinCompDateMs = Infinity; | ||
+ | memo.obsMaxCompDateMs = -Infinity; | ||
+ | |||
+ | memo.season = i18n[memo.obscode]['season']; | ||
+ | memo.curSeason = memo.now.getFullYear(); | ||
+ | if ( memo.season == 'winter' && memo.now.getMonth() < 8 ) { memo.curSeason--; } | ||
+ | |||
+ | // first loop | ||
+ | for ( var o in memo.jw.obs ) { | ||
+ | |||
+ | obs = memo.jw.obs[o]; | ||
+ | |||
+ | console.log( obs ); | ||
+ | |||
+ | memo.obsesTotal++; | ||
+ | |||
+ | memo.obsMinValue = Math.min( memo.obsMinValue, obs.value ); | ||
+ | memo.obsMaxValue = Math.max( memo.obsMaxValue, obs.value ); | ||
+ | |||
+ | memo.obsMinDateMs = Math.min( memo.obsMinDateMs, obs.obsdatetime.getTime() ); | ||
+ | memo.obsMaxDateMs = Math.max( memo.obsMaxDateMs, obs.obsdatetime.getTime() ); | ||
+ | |||
+ | // add compare date to obses | ||
+ | if ( memo.season == 'summer' || obs.obsdatetime.getMonth() > 7 ) { | ||
+ | obs.compareDate = new Date( memo.curSeason, obs.obsdatetime.getMonth(), obs.obsdatetime.getDate() ); | ||
+ | } else { | ||
+ | obs.compareDate = new Date( memo.curSeason+1, obs.obsdatetime.getMonth(), obs.obsdatetime.getDate() ); | ||
+ | } | ||
+ | ms = obs.compareDate.getTime(); | ||
+ | memo.obsMinCompDateMs = Math.min(ms, memo.obsMinCompDateMs); | ||
+ | memo.obsMaxCompDateMs = Math.max(ms, memo.obsMaxCompDateMs); | ||
+ | |||
+ | // add series id | ||
+ | if ( memo.graphType == 'trend' ) { | ||
+ | obs.seriesId = 0; | ||
+ | } else if ( memo.season == 'summer' || obs.obsdatetime.getMonth() > 7 ) { | ||
+ | obs.seriesId = obs.obsdatetime.getFullYear(); | ||
+ | } else { | ||
+ | obs.seriesId = obs.obsdatetime.getFullYear()-1; | ||
+ | } | ||
+ | |||
+ | // create popup for obs | ||
+ | obs.popup = '<div style="padding: 8px;">'; | ||
+ | obs.popup += '<div>'; | ||
+ | |||
+ | if ( i18n[memo.obscode]['type'] == 'cat') { | ||
+ | obs.popup +='<b>' + i18n[memo.obscode]['title'][memo.lang] + ': ' + i18n[memo.obscode]['catNames'][obs.value][memo.lang] + '</b> '; | ||
+ | } else if ( i18n[memo.obscode]['type'] == 'date') { | ||
+ | obs.popup +='<b>' + i18n[memo.obscode]['title'][memo.lang] + '</b> '; | ||
+ | } else { | ||
+ | obs.popup +='<b>' + i18n[memo.obscode]['title'][memo.lang] + ': ' + (Math.round(obs.value * 10)/10).toString().replace( '.', i18n['dec'][memo.lang] ) + ' ' + i18n[memo.obscode]['unit'] + '</b> '; | ||
+ | } | ||
+ | |||
+ | obs.popup += '(' + obs.obsdatetime.inRelationToToday(memo.lang) + ')'; | ||
+ | obs.popup += '</div>'; | ||
+ | |||
+ | if (!!obs.addInfo) { obs.popup += '<div style="margin-top: 5px;">' + obs.addInfo + '</div>'; } | ||
+ | obs.popup += '</div>'; | ||
+ | |||
+ | } | ||
+ | |||
+ | memo.obsMinDate = new Date( memo.obsMinDateMs ); | ||
+ | memo.obsMaxDate = new Date( memo.obsMaxDateMs ); | ||
+ | memo.obsMinYear = memo.obsMinDate.getFullYear(); | ||
+ | memo.obsMaxYear = memo.obsMaxDate.getFullYear(); | ||
+ | memo.obsMinCompDate = new Date( memo.obsMinCompDateMs ); | ||
+ | memo.obsMaxCompDate = new Date( memo.obsMaxCompDateMs ); | ||
+ | |||
+ | memo.obsesA = []; memo.dataA = []; | ||
+ | |||
+ | for (var o in memo.jw.obs) { | ||
+ | |||
+ | obs = memo.jw.obs[o]; | ||
+ | |||
+ | // style points | ||
+ | if ( obs.seriesId == memo.curSeason ) { | ||
+ | baseSize = 6; | ||
+ | } else if (memo.obsesTotal < 100) { | ||
+ | baseSize = 4; | ||
+ | } else if (memo.obsesTotal < 200) { | ||
+ | baseSize = 3; | ||
+ | } else if (memo.obsesTotal < 300) { | ||
+ | baseSize = 2; | ||
+ | } else { | ||
+ | baseSize = 2; | ||
+ | } | ||
+ | |||
+ | //if ( memo.graphType == 'dateofyear' ) { baseSize = baseSize + 1; } | ||
+ | |||
+ | if (!!obs.addInfo) { | ||
+ | //obs.style = 'point { shape-type: star; size: ' + (baseSize+3) + '; shape-dent: 0.5; fill-color: ' + colors['noticeObses'] + '; stroke-width: 0; stroke-color: ' + maintColors[memo.obses[o].maintainer] + '; }'; | ||
+ | //obs.style = 'point { size: ' + (baseSize+1) + '; stroke-width: 2; stroke-color: gold; }'; | ||
+ | obs.style = 'point { size: ' + (baseSize+1) + '; stroke-width: 3; stroke-color: ' + maintColors[obs.maintainer] + '; }'; | ||
+ | } else { | ||
+ | obs.style = 'point { size: ' + baseSize + '; stroke-width: 0.5; stroke-color: ' + maintColors[obs.maintainer] + '; }'; | ||
+ | } | ||
+ | |||
+ | memo.obsesA.push( obs ); | ||
+ | |||
+ | } | ||
+ | |||
+ | // sort | ||
+ | memo.obsesA.sort( function(a, b) { return a.obsdatetime - b.obsdatetime; }); | ||
+ | |||
+ | // create DataTable | ||
+ | memo.data = new google.visualization.DataTable(); | ||
+ | |||
+ | // col for xAxis values | ||
+ | memo.data.addColumn( 'date', 'time' ); | ||
+ | |||
+ | // make ticks for y axis on cat types | ||
+ | if ( i18n[memo.obscode]['type'] == 'cat' ) { | ||
+ | memo.options.vAxis.ticks = []; | ||
+ | for (var c in i18n[memo.obscode]['catNamesShort']) { | ||
+ | memo.options.vAxis.ticks.push({v: parseInt(c), f: i18n[memo.obscode]['catNamesShort'][c][memo.lang] }); | ||
+ | memo.options.vAxis.ticks.push({v: parseInt(c)+0.5, f: '' }); | ||
+ | } | ||
+ | memo.options.vAxis.ticks.sort( function(a, b) { return a.v-b.v } ); | ||
+ | memo.options.vAxis.viewWindow = { min: -0.5, max: parseInt(memo.options.vAxis.ticks[memo.options.vAxis.ticks.length-1].v)+0.5 }; | ||
+ | memo.options.vAxis.gridlines.color = '#fff'; | ||
+ | memo.options.vAxis.baselineColor = 'none'; | ||
+ | } else if ( typeof i18n[memo.obscode]['min'] != 'undefined' ) { | ||
+ | memo.options.vAxis.viewWindow = { min: i18n[memo.obscode]['min'] }; | ||
+ | } else if ( memo.obsMinValue >= 0) { | ||
+ | memo.options.vAxis.viewWindow = { min: 0 }; | ||
+ | } | ||
+ | |||
+ | if (memo.graphType == 'trend') { | ||
+ | |||
+ | //addDataToTrendChart(memo); | ||
+ | |||
+ | } else if (memo.graphType == 'season') { | ||
+ | |||
+ | //addDataToSeasonChart(memo); | ||
+ | |||
+ | } else if (memo.graphType == 'dateofyear') { | ||
+ | |||
+ | //addDataToDateOfYearChart(memo); | ||
+ | |||
+ | } | ||
+ | |||
+ | data = {}; | ||
+ | var firstW = 3000; lastW = 0; | ||
+ | var firstF = 500; var lastB = -500; | ||
+ | //var firstCd = new Date( memo.now.getFullyear(), 11, 31 ); var lastCd = new Date(); | ||
− | + | var cnewyear = new Date( memo.now.getFullYear()+1, 0, 1 ); | |
− | |||
− | |||
− | + | for ( var o in memo.jw.obsList ) { | |
− | + | var obs = memo.jw.obs[ memo.jw.obsList [ o ] ]; | |
− | + | obs.data = JSON.parse( obs.printouts.DataJSON ); | |
− | + | if ( obs.obsdatetime.getMonth() > -1 && obs.obsdatetime.getMonth() < 8 ) { | |
− | + | obs.winter = obs.obsdatetime.getFullYear()-1; | |
− | + | obs.comparedate = new Date( memo.now.getFullYear()+1, obs.obsdatetime.getMonth(), obs.obsdatetime.getDate() ); | |
− | + | } else { | |
− | + | obs.winter = obs.obsdatetime.getFullYear(); | |
− | + | obs.comparedate = new Date( memo.now.getFullYear(), obs.obsdatetime.getMonth(), obs.obsdatetime.getDate() ); | |
− | + | } | |
− | + | var days = ( obs.comparedate.getTime() - cnewyear.getTime() ) / ( 1000*60*60*24 ); | |
− | + | firstW = Math.min( firstW, obs.winter ); lastW = Math.max( lastW, obs.winter ); | |
+ | firstF = Math.min( firstF, days ); lastB = Math.max( lastB, days ); | ||
+ | |||
+ | if ( typeof data[ obs.winter ] == 'undefined' ) { data[ obs.winter ] = { 'winter': obs.winter }; } | ||
− | + | if ( obs.data.cat == 2 ) { | |
+ | data[ obs.winter ].freeze = obs.comparedate; //days; | ||
+ | } else if ( obs.data.cat == 5 ) { | ||
+ | data[ obs.winter ].breakup = obs.comparedate; //days; | ||
+ | } | ||
− | + | //console.log( winter ); | |
− | + | ||
− | + | //var freezeD = new Date( 2021', obs.obsdatetime.getMonth(), obs.obsdatetime.getDate() ); | |
− | + | //var freezeD = new Date( 2021', obs.obsdatetime.getMonth(), obs.obsdatetime.getDate() ); | |
− | |||
− | + | //row = [ winter ] | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | } | |
− | + | var table = []; | |
+ | |||
+ | firstW = Math.floor( firstW/10 ) * 10; | ||
+ | lastW = Math.floor( lastW/10+1 ) * 10; | ||
− | + | for ( var y=firstW; y<(lastW+1); y++ ) { | |
− | + | ||
− | + | var wn = 'Talvi ' + y.toString() + '-' + (y+1).toString(); | |
− | + | ||
− | + | if ( typeof data[y] != 'undefined' ) { | |
− | + | ||
− | + | row = [ y ]; | |
− | + | ||
− | + | if ( typeof data[y].freeze != 'undefined' && typeof data[y].breakup != 'undefined' ) { | |
− | + | icedays = Math.round( ( data[y].breakup.getTime() - data[y].freeze.getTime() ) / ( 1000*60*60*24 ) ); | |
− | + | row.push( data[y].freeze ); row.push( data[y].freeze ); | |
− | + | row.push( data[y].breakup ); row.push( data[y].breakup ); | |
+ | row.push( '<b>' + wn + '</b><br />Jääpeiteaika: ' + icedays + ' päivää' ); | ||
+ | } else { | ||
+ | row.push( null ); row.push( null ); | ||
+ | row.push( null ); row.push( null ); | ||
+ | row.push( null ); | ||
+ | } | ||
+ | |||
+ | if ( typeof data[y].freeze != 'undefined' ) { | ||
+ | row.push( data[y].freeze ); | ||
+ | row.push( '<b>' + wn + '</b><br />Jääpeitekausi alkoi ' + data[y].freeze.getDate() + '.' + (data[y].freeze.getMonth()+1) + '.' ); | ||
+ | } else { | ||
+ | row.push( null ); row.push( null ); | ||
+ | } | ||
+ | |||
+ | if ( typeof data[y].breakup != 'undefined' ) { | ||
+ | row.push( data[y].breakup ); | ||
+ | row.push( '<b>' + wn + '</b><br />Jäätön kausi alkoi ' + data[y].breakup.getDate() + '.' + (data[y].breakup.getMonth()+1) + '.' ); | ||
+ | } else { | ||
+ | row.push( null ); row.push( null ); | ||
+ | } | ||
+ | |||
+ | } else { | ||
+ | row = [ y, null, null, null, null, null, null, null, null, null ]; | ||
+ | } | ||
+ | |||
+ | table.push( row ); | ||
− | } | + | } |
− | + | ||
+ | memo.dataTable = new google.visualization.DataTable(); | ||
+ | memo.dataTable.addColumn( 'number', 'Talvei' ); | ||
+ | memo.dataTable.addColumn( 'date', 'Jääpeiteaika' ); | ||
+ | memo.dataTable.addColumn( 'date', '' ); | ||
+ | memo.dataTable.addColumn( 'date', '' ); | ||
+ | memo.dataTable.addColumn( 'date', '' ); | ||
+ | memo.dataTable.addColumn({ role: 'tooltip', 'p': { 'html': true } }); | ||
+ | memo.dataTable.addColumn( 'date', 'Jäätyminen' ); | ||
+ | memo.dataTable.addColumn({ role: 'tooltip', 'p': { 'html': true } }); | ||
+ | memo.dataTable.addColumn( 'date', 'Jäänlähtö' ); | ||
+ | memo.dataTable.addColumn({ role: 'tooltip', 'p': { 'html': true } }); | ||
+ | |||
+ | memo.dataTable.addRows( table ); | ||
+ | |||
+ | // margin settings | ||
+ | memo.margins = { top: 0, right: 25, bottom: 60, left: 60 }; | ||
− | + | memo.options = { | |
− | + | seriesType: "candlesticks", | |
− | + | series: { 1: { type: "scatter", color: '#3366cc', dataOpacity: 0.5 }, 2: { type: "scatter", color: '#3366cc', dataOpacity: 0.5 } }, | |
− | + | trendlines: { 1: { type: 'linear', color: 'orange' }, 2: { type: 'linear', color: 'orange' } }, | |
− | + | legend: 'bottom', | |
− | + | hAxis: { slantedText: false, maxAlternation: 1, format: '####' }, | |
− | + | vAxis: { format: 'MMM' }, | |
− | + | tooltip: { isHtml: true } | |
− | + | ||
+ | }; | ||
+ | |||
+ | memo.chart = new google.visualization.CandlestickChart( memo.chartEl[0] ); | ||
+ | memo.chart.draw( memo.dataTable, memo.options); | ||
+ | |||
+ | memo.widgetEl.find( '.jwloading' ).remove(); | ||
+ | |||
+ | memo.fullscreenEl.fadeIn( "slow" ); | ||
+ | memo.downloadEl.fadeIn( "slow" ); | ||
+ | |||
+ | doResize(); | ||
− | + | } // ObsesReady | |
+ | |||
+ | |||
+ | function addDataToDateOfYearChart( memo ) { | ||
+ | |||
+ | // do X axis min and max for this chart type | ||
+ | memo.options.hAxis.minValue = new Date( memo.obsMinDateMs ); | ||
+ | memo.options.hAxis.minValue.setMonth(0); | ||
+ | memo.options.hAxis.minValue.setDate(1); | ||
+ | memo.options.hAxis.viewWindow.min = memo.options.hAxis.minValue; | ||
+ | |||
+ | memo.options.hAxis.maxValue = new Date( memo.obsMaxDateMs ); | ||
+ | memo.options.hAxis.maxValue.setMonth(11); | ||
+ | memo.options.hAxis.maxValue.setDate(31); | ||
+ | memo.options.hAxis.viewWindow.max = memo.options.hAxis.maxValue; | ||
+ | |||
+ | memo.options.vAxis.ticks = []; | ||
+ | |||
+ | //memo.options.hAxis.gridlines.units = { years: { format: [ 'yyyy' ] } }; | ||
+ | //memo.options.hAxis.ticks = []; | ||
+ | |||
+ | // do Y axis min and max for this chart type | ||
+ | memo.options.vAxis.minValue = new Date( memo.obsMinCompDate.getTime() ); | ||
+ | memo.options.vAxis.minValue.setDate(1); | ||
+ | memo.options.vAxis.viewWindow.min = memo.options.vAxis.minValue; | ||
+ | |||
+ | memo.options.vAxis.maxValue = new Date( memo.obsMaxCompDate.getTime() ); | ||
+ | memo.options.vAxis.maxValue.setMonth( memo.options.vAxis.maxValue.getMonth()+1 ); | ||
+ | memo.options.vAxis.maxValue.setDate(0); | ||
+ | memo.options.vAxis.viewWindow.max = memo.options.vAxis.maxValue; | ||
+ | |||
+ | // do Y axis ticks and gridlines | ||
+ | memo.options.vAxis.gridlines = { color: 'transparent' }; | ||
+ | minM = memo.options.vAxis.minValue.getMonth(); | ||
+ | maxM = memo.options.vAxis.maxValue.getMonth(); | ||
+ | if (minM > maxM) { mc = 13-minM+maxM; } else { mc = maxM-minM+1; } | ||
+ | |||
+ | for ( mi = 0; mi < mc; mi++ ) { | ||
+ | |||
+ | mx = minM+mi; | ||
+ | yx = memo.options.vAxis.minValue.getFullYear(); | ||
+ | if ( mx > 11 ) { yx = maxD.getFullYear(); mx = mx - 12; } | ||
+ | |||
+ | startOfMonth = new Date( yx, mx, 1 ); | ||
+ | middleOfMonth = new Date( yx, mx, 15 ); | ||
+ | |||
+ | // ticks | ||
+ | memo.options.vAxis.ticks.push( { v: middleOfMonth, f: i18n['months'][mx]['long'][memo.lang] } ); | ||
+ | |||
+ | // gridlines except for first | ||
+ | memo.vAxisGridlines = []; | ||
+ | if (mi > 0) { | ||
+ | memo.vAxisGridlines.push( new Date( startOfMonth.getTime() ) ); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // data columns | ||
+ | memo.data.addColumn( 'date', memo.obsMinYear + '-' + memo.obsMaxYear ); | ||
+ | memo.data.addColumn( {'type': 'string', 'role': 'style' } ); | ||
+ | memo.data.addColumn( { type: 'string', role: 'annotation' } ); | ||
+ | memo.data.addColumn( { type: 'string', role: 'tooltip', 'p': { 'html': true } } ); | ||
+ | |||
+ | // scatter series | ||
+ | memo.options.series[0] = { type: 'scatter', pointType: 'circle', pointSize: 9, color: '#3366cc' }; | ||
+ | |||
+ | // linear 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' }; | ||
+ | |||
+ | // data columns for vAxis gridlines | ||
+ | for (g=0; g < memo.vAxisGridlines.length; g++) { | ||
+ | memo.data.addColumn( 'date', 'vAxis gridline_' + g ); | ||
+ | memo.options.series[g+1] = { type: 'line', pointSize: 0, lineWidth: 1, color: '#fff', XlineDashStyle: [3, 3], visibleInLegend: false }; | ||
+ | } | ||
+ | |||
+ | // add data | ||
+ | noc = memo.data.getNumberOfColumns(); | ||
+ | |||
+ | // add obses | ||
+ | for (var o in memo.obsesA) { | ||
+ | dataRow = []; | ||
+ | |||
+ | // fill row with nulls | ||
+ | for (var i=0; i<noc; i++) { dataRow.push( null ); } | ||
+ | |||
+ | centerOfYear = new Date( memo.obsesA[o].datetime.getTime() ); | ||
+ | centerOfYear.setMonth(6); | ||
+ | centerOfYear.setDate(1); | ||
+ | |||
+ | dataRow[0] = centerOfYear; | ||
+ | dataRow[1] = memo.obsesA[o].compareDate; | ||
+ | dataRow[2] = memo.obsesA[o].style; | ||
+ | // annotation | ||
+ | dataRow[4] = memo.obsesA[o].popup; | ||
+ | |||
+ | memo.dataA.push( dataRow ); | ||
+ | } | ||
+ | |||
+ | // add gridlines | ||
+ | for (g=0; g < memo.vAxisGridlines.length; g++) { | ||
+ | |||
+ | dataRow1 = []; | ||
+ | dataRow2 = []; | ||
+ | |||
+ | // fill rows with nulls | ||
+ | for (var i=0; i<noc; i++) { dataRow1.push( null ); dataRow2.push( null ); } | ||
+ | |||
+ | dataRow1[0] = memo.options.hAxis.minValue; | ||
+ | dataRow2[0] = memo.options.hAxis.maxValue; | ||
+ | |||
+ | dataRow1[5+g] = memo.vAxisGridlines[g]; | ||
+ | dataRow2[5+g] = memo.vAxisGridlines[g]; | ||
+ | |||
+ | memo.dataA.push( dataRow1 ); | ||
+ | memo.dataA.push( dataRow2 ); | ||
+ | } | ||
+ | |||
+ | drawChart(memo); | ||
+ | |||
+ | } | ||
+ | |||
+ | memo.fullscreenEl.on( 'click', function() { | ||
+ | |||
+ | var elem = memo.widgetEl[0]; | ||
+ | |||
+ | if (!!document.fullscreenElement) { | ||
+ | |||
+ | //memo.options.chartArea = { top: memo.margins.top, left: memo.margins.left, width: (memo.container.width() - memo.margins.left - memo.margins.right), height: (memo.container.height() - memo.margins.top - memo.margins.bottom), backgroundColor: { fill: '#daf0fa', stroke: '#fff', strokeWidth: 6 }}; | ||
+ | |||
+ | if (document.exitFullscreen) { | ||
+ | document.exitFullscreen(); | ||
+ | } else if (document.mozCancelFullScreen) { /* Firefox */ | ||
+ | document.mozCancelFullScreen(); | ||
+ | } else if (document.webkitExitFullscreen) { /* Chrome, Safari and Opera */ | ||
+ | document.webkitExitFullscreen(); | ||
+ | } else if (document.msExitFullscreen) { /* IE/Edge */ | ||
+ | document.msExitFullscreen(); | ||
+ | } | ||
+ | |||
+ | memo.fullscreenEl.find( 'button' ).html( '<i class="fas fa-expand"></i>' ); | ||
+ | |||
+ | } else { | ||
+ | |||
+ | if (elem.requestFullscreen) { | ||
+ | elem.requestFullscreen(); | ||
+ | } else if (elem.mozRequestFullScreen) { /* Firefox */ | ||
+ | elem.mozRequestFullScreen(); | ||
+ | } else if (elem.webkitRequestFullscreen) { /* Chrome, Safari and Opera */ | ||
+ | elem.webkitRequestFullscreen(); | ||
+ | } else if (elem.msRequestFullscreen) { /* IE/Edge */ | ||
+ | elem.msRequestFullscreen(); | ||
+ | } | ||
+ | |||
+ | memo.fullscreenEl.find( 'button' ).html( '<i class="fas fa-compress"></i>' ); | ||
+ | |||
+ | } | ||
+ | |||
+ | doResize(); | ||
+ | |||
+ | }); | ||
+ | |||
+ | memo.downloadEl.on( 'click', function() { | ||
+ | |||
+ | //console.log(memo); | ||
+ | |||
+ | var header = ''; | ||
+ | header += '\uFEFF'; // BOM | ||
+ | var csv = ''; | ||
+ | //csv += '\r\nsep=,\r\n'; | ||
+ | |||
+ | var headerCols = []; | ||
+ | var csvCols = []; | ||
+ | |||
+ | if ( i18n[memo.obscode].type == 'num' ) { | ||
+ | |||
+ | headerCols.push( 'Päivämäärä' ); | ||
+ | headerCols.push( 'Kellonaika' ); | ||
+ | headerCols.push( '"' + i18n[memo.obscode].axisTitleV[memo.lang] + '"' ); | ||
+ | headerCols.push( 'Lisätiedot' ); | ||
+ | headerCols.push( 'Valokuva' ); | ||
+ | headerCols.push( 'Havainnoijan status' ); | ||
+ | |||
+ | header += headerCols.join( i18n['sep'][memo.lang] ); | ||
+ | |||
+ | for ( var o in memo.obses ) { | ||
+ | |||
+ | csvCols = []; | ||
+ | |||
+ | csvCols.push( memo.obses[o].datetime.getFullYear() + '-' + ( memo.obses[o].datetime.getMonth() + 1 ) + '-' + memo.obses[o].datetime.getDate() ); | ||
+ | |||
+ | if ( memo.obses[o].datetime.getUTCHours() == 0 && memo.obses[o].datetime.getUTCMinutes() == 0 && memo.obses[o].datetime.getUTCSeconds() == 0 ) { | ||
+ | csvCols.push( '' ); | ||
+ | } else { | ||
+ | csvCols.push( ( "0" + memo.obses[o].datetime.getUTCHours() ).slice(-2) + ':' + ( "0" + memo.obses[o].datetime.getUTCMinutes() ).slice(-2) ); | ||
+ | } | ||
+ | |||
+ | csvCols.push( '"' + memo.obses[o].value.toString().replace( '.', i18n['dec'][memo.lang] ) + '"' ); | ||
+ | csvCols.push( memo.obses[o].addInfo ); | ||
+ | csvCols.push( '' ); | ||
+ | csvCols.push( memo.obses[o].maintainer ); | ||
+ | |||
+ | csv += '\r\n' + csvCols.join( i18n['sep'][memo.lang] ); | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | } else if ( i18n[memo.obscode].type == 'date' ) { | ||
+ | |||
+ | header += 'Vuosi'; | ||
+ | header += ';' + i18n[memo.obscode].title[memo.lang]; | ||
+ | header += ';' + 'Lisätiedot'; | ||
+ | header += ';' + 'Valokuva'; | ||
+ | header += ';' + 'Havainnoijan status'; | ||
+ | |||
+ | for ( var o in memo.obses ) { | ||
+ | |||
+ | csv += '\r\n'; | ||
+ | |||
+ | csv += memo.obses[o].datetime.getFullYear(); | ||
+ | |||
+ | csv += ';' + memo.obses[o].datetime.getDate() + '.' + (memo.obses[o].datetime.getMonth()+1); | ||
+ | |||
+ | csv += ';' + memo.obses[o].addInfo; | ||
+ | csv += ';'; | ||
+ | csv += ';' + memo.obses[o].maintainer; | ||
+ | |||
+ | } | ||
+ | |||
+ | } else if ( i18n[memo.obscode].type == 'cat' ) { | ||
+ | |||
+ | header += 'Päivämäärä'; | ||
+ | header += ';' + 'Kellonaika'; | ||
+ | header += ';' + i18n[memo.obscode].title[memo.lang]; | ||
+ | header += ';' + i18n[memo.obscode].title[memo.lang]; | ||
+ | header += ';' + utf8StringToUtf16String( 'Lisätiedot' ); | ||
+ | header += ';' + 'Valokuva'; | ||
+ | header += ';' + 'Havainnoijan status'; | ||
+ | |||
+ | for ( var o in memo.obses ) { | ||
+ | |||
+ | csv += '\r\n'; | ||
+ | |||
+ | csv += memo.obses[o].datetime.toLocaleDateString(); //.toISOString(); | ||
+ | |||
+ | if ( memo.obses[o].datetime.getUTCHours() == 0 && memo.obses[o].datetime.getUTCMinutes() == 0 && memo.obses[o].datetime.getUTCSeconds() == 0 ) { | ||
+ | csv += ';'; | ||
+ | } else { | ||
+ | csv += ';' + ( "0" + memo.obses[o].datetime.getUTCHours() ).slice(-2) + ':' + ( "0" + memo.obses[o].datetime.getUTCMinutes() ).slice(-2); | ||
+ | } | ||
+ | |||
+ | csv += ';' + memo.obses[o].value; | ||
+ | csv += ';' + i18n[memo.obscode].catNames[memo.obses[o].value][memo.lang]; | ||
+ | |||
+ | csv += ';' + memo.obses[o].addInfo; | ||
+ | csv += ';'; | ||
+ | csv += ';' + memo.obses[o].maintainer; | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | csv = header + csv; | ||
+ | |||
+ | var exportedFilename = 'test.csv'; | ||
+ | |||
+ | var blob = new Blob( [csv], { type: 'text/csv;charset=utf-16LE;' }); | ||
+ | |||
+ | if (navigator.msSaveBlob) { // IE 10+ | ||
+ | navigator.msSaveBlob(blob, exportedFilename); | ||
+ | } else { | ||
+ | var link = document.createElement("a"); | ||
+ | if (link.download !== undefined) { // feature detection | ||
+ | // Browsers that support HTML5 download attribute | ||
+ | var url = URL.createObjectURL(blob); | ||
+ | link.setAttribute("href", url); | ||
+ | link.setAttribute("download", exportedFilename); | ||
+ | link.style.visibility = 'hidden'; | ||
+ | document.body.appendChild(link); | ||
+ | link.click(); | ||
+ | document.body.removeChild(link); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | }); | ||
+ | |||
+ | |||
+ | jQuery( window ).resize(function() { | ||
+ | |||
+ | doResize(); | ||
+ | |||
+ | }); | ||
+ | |||
+ | function doResize() { | ||
+ | |||
+ | var w = memo.widgetEl.width(); | ||
+ | var l = Math.max( memo.margins.left, 0.1*w ); | ||
+ | var r = memo.margins.right; | ||
+ | var h = memo.widgetEl.height(); | ||
+ | var t = Math.max( memo.margins.top, 0.1*h ); | ||
+ | var b = Math.max( memo.margins.bottom, 0.15*h ); | ||
+ | |||
+ | if (!!document.fullscreenElement) { r += 24; } | ||
+ | |||
+ | if (!!document.fullscreenElement) { | ||
+ | //memo.options.chartArea = { top: memo.margins.top*2, left: memo.margins.left*2, width: (w - memo.margins.left*2 - memo.margins.right - 24), height: (h - memo.margins.top*2 - memo.margins.bottom*2), backgroundColor: { fill: '#daf0fa', stroke: '#fff', strokeWidth: 6 }}; | ||
+ | memo.options.chartArea = { top: t*2, left: l*2, width: (w - l*2 - r - 24), height: (h - t*2 - b*2), backgroundColor: { fill: '#daf0fa', stroke: '#fff', strokeWidth: 6 }}; | ||
+ | } else { | ||
+ | memo.options.chartArea = { top: memo.margins.top, left: memo.margins.left, width: (w - memo.margins.left - memo.margins.right), height: (h - memo.margins.top - memo.margins.bottom), backgroundColor: { fill: '#daf0fa', stroke: '#fff', strokeWidth: 6 }}; | ||
+ | } | ||
+ | memo.options.chartArea = { top: t, left: l, width: (w - l - r), height: (h - t - b), backgroundColor: { fill: '#daf0fa', stroke: '#fff', strokeWidth: 6 }}; | ||
+ | |||
+ | memo.chart.draw( memo.dataTable, memo.options ); | ||
+ | |||
+ | // hide every second vaxis gridline on cat charts | ||
+ | //if ( i18n[memo.obscode]['type'] == 'cat') { | ||
+ | // var glc = 0; | ||
+ | // jQuery( document.getElementById(memo.id) ).find( 'rect[height="1"]' ).each( function() { | ||
+ | // if ( ( glc++ % 2 ) == 0 ) { jQuery( this ).attr( 'fill', 'none' ); } | ||
+ | // }); | ||
+ | //} | ||
+ | |||
+ | // move current observations to top | ||
+ | gEl = memo.chartEl.find( 'svg' ).append( 'g' ); | ||
+ | |||
+ | //jQuery( document.getElementById(memo.id) ).find( 'circle[stroke-width="3"]' ).detach().appendTo( gEl ); | ||
+ | memo.chartEl.find( 'path[stroke="#3366cc"]' ).detach().appendTo( gEl ); | ||
+ | memo.chartEl.find( 'circle[fill="#3366cc"]' ).detach().appendTo( gEl ); | ||
+ | |||
+ | memo.chartEl.find( 'circle[stroke-width="3"]' ).each( function() { jQuery( this ).parent().append( jQuery( this ) ); }); | ||
+ | //jQuery( document.getElementById(memo.id) ).find( 'circle[fill="#3366cc"]' ).each( function() { jQuery( this ).parent().append( jQuery( this ) ); }); | ||
+ | //jQuery( document.getElementById(memo.id) ).find( 'path[stroke="#3366cc"]' ).each( function() { jQuery( this ).parent().append( jQuery( this ) ); }); | ||
+ | |||
+ | memo.chartEl.find( 'text[text-anchor="start"]:contains("' + i18n[memo.obscode].title[memo.lang] + '")' ).attr( 'y', (t-10).toString() ); | ||
+ | |||
+ | if (!!document.fullscreenElement) { | ||
+ | memo.fullscreenEl.css( 'margin-top', ( t-35 ).toString() + 'px' ).css( 'margin-right', '7px' ); | ||
+ | memo.downloadEl.css( 'margin-top', ( t-35 ).toString() + 'px' ).css( 'margin-right', '7px' ); | ||
+ | |||
+ | } else { | ||
+ | memo.fullscreenEl.css( 'margin-top', '0px' ).css( 'margin-right', '0px' ); | ||
+ | memo.downloadEl.css( 'margin-top', '0px' ).css( 'margin-right', '0px' ); | ||
+ | } | ||
+ | |||
+ | } | ||
− | + | }); | |
− | |||
} | } | ||
+ | |||
+ | var maintColors = { 'authority': '#bb1111', 'expert': '#ff9933', 'experienced': '#666666', 'user': '#aaaaaa'}; | ||
+ | |||
+ | var seriesC = [ 'lightgray', '#3366cc', 'orange' ]; | ||
+ | |||
+ | var colors = { 'average': 'BurlyWood', 'trend': 'orangered', 'obses': 'lightgray', 'curObses': '#3366cc', 'selObses': 'gold', 'noticeObses': 'tan' }; | ||
+ | |||
+ | var i18n = { | ||
+ | 'download': { 'fi': 'Lataa csv-muodossa', 'en': 'Download in csv format', 'sv': 'Ladda ner i csv-format' }, | ||
+ | 'fullscreen': { 'fi': 'Ota käyttöön/poista kokoruututila', 'en': 'Toggle fullscreen mode', 'sv': 'Växla helskärmsläge' }, | ||
+ | 'dec': { 'fi': ',', 'en': '.', 'sv': ',' }, | ||
+ | 'sep': { 'fi': '\t', 'en': ' ', 'sv': ' ' }, | ||
+ | 'alg': { | ||
+ | 'type': 'cat', | ||
+ | 'min': -0.5, | ||
+ | 'season': 'summer', | ||
+ | 'trend': { 'type': 'gaussian', 'layout': 'line' }, | ||
+ | 'title': { 'fi': 'Sinilevätilanne', 'en': 'XX', 'sv': 'Xxx', 'ru': '???' }, | ||
+ | 'catNames': { 0: { 'fi': 'Ei levää', 'en': 'No algae', 'sv': 'Inga alger' }, 1: { 'fi': 'Hieman levää', 'en': 'Some algae', 'sv': 'Lite med alger' }, 2: { 'fi': 'Runsaasti levää', 'en': 'Abundant with algae', 'sv': 'Rikligt med alger' }, 3: { 'fi': 'Erittäin runsaasti levää', 'en': 'Very abundant with algae', 'sv': 'Ytterst rikligt med alger' } }, | ||
+ | 'catNamesShort': { 0: { 'fi': 'Ei levää', 'en': 'No algae', 'sv': 'Inga alger' }, 1: { 'fi': 'Hieman', 'en': 'Some', 'sv': 'Lite' }, 2: { 'fi': 'Runsaasti', 'en': 'Abundant', 'sv': 'Rikligt' }, 3: { 'fi': 'Erit. runsaasti', 'en': 'Very abundant', 'sv': 'Ytterst rikligt' } }, | ||
+ | 'unit': '', | ||
+ | 'axisTitleV': { 'fi': '', 'en': '', 'sv': '', 'ru': '' } | ||
+ | }, | ||
+ | 'temp': { | ||
+ | 'type': 'num', | ||
+ | 'season': 'summer', | ||
+ | 'trend': { 'type': 'gaussian', 'layout': 'line' }, | ||
+ | 'title': { 'fi': 'Pintaveden lämpötila', 'en': 'Surface water termperature', 'sv': 'Ytvattentemperatur', 'ru': '???' }, | ||
+ | 'unit': '°C', | ||
+ | 'axisTitleV': { 'fi': 'Lämpötila, °C', 'en': 'Temperature, °C', 'sv': 'Temperatur, °C', 'ru': '°C' } | ||
+ | }, | ||
+ | 'ice': { | ||
+ | 'catName': 'Jäätilanne', | ||
+ | 'type': 'num', | ||
+ | 'season': 'winter', | ||
+ | 'min': 0, | ||
+ | 'direction': -1, | ||
+ | 'trend': { 'type': 'gaussian', 'layout': 'line' }, | ||
+ | 'title': { 'fi': 'Jään paksuus', 'en': 'Ice thickness', 'sv': 'Isens tjocklek', 'ru': '???' }, | ||
+ | 'unit': 'cm', | ||
+ | 'axisTitleV': { 'fi': 'Jääpeite, cm', 'en': 'Ice cover, cm', 'sv': 'Istäcket, cm', 'ru': 'm' } | ||
+ | }, | ||
+ | 'ice_cat': { | ||
+ | 'catName': 'Jäätilanne', | ||
+ | }, | ||
+ | 'ice_cat_5': { | ||
+ | 'type': 'date', | ||
+ | 'season': 'winter', | ||
+ | 'direction': -1, | ||
+ | 'trend': { 'type': 'regression', 'layout': 'line' }, | ||
+ | 'title': { 'fi': 'Jäätön aika alkoi', 'en': 'Ice break-up', 'sv': 'Isfri tid börjar', 'ru': '???' }, | ||
+ | 'unit': 'cm', | ||
+ | 'axisTitleV': { 'fi': '', 'en': '', 'sv': '', 'ru': '' } | ||
+ | }, | ||
+ | 'snow_load': { | ||
+ | 'catName': 'Lumikuorma', | ||
+ | 'type': 'num', | ||
+ | 'season': 'winter', | ||
+ | 'min': 0, | ||
+ | 'trend': { 'type': 'moving', 'layout': 'area' }, | ||
+ | 'title': { 'fi': 'Lumikuorma', 'en': 'Snow load', 'sv': 'Snöbelastning', 'ru': '???' }, | ||
+ | 'unit': 'kg/m²', | ||
+ | 'axisTitleV': { 'fi': 'Lumikuorma, kg/m²', 'en': 'Snow load, kg/m²', 'sv': 'Snöbelastning, kg/m²', 'ru': 'm' } | ||
+ | }, | ||
+ | 'secchi': { | ||
+ | 'type': 'num', | ||
+ | 'season': 'summer', | ||
+ | 'min': 0, | ||
+ | 'direction': -1, | ||
+ | 'trend': { 'type': 'gaussian', 'layout': 'line' }, | ||
+ | //'trend': { 'type': 'regression', 'layout': 'line' }, | ||
+ | 'title': { 'fi': 'Näkösyvyys', 'en': 'Water transparency', 'sv': 'Siktdjupet', 'ru': '???' }, | ||
+ | 'unit': 'm', | ||
+ | 'axisTitleV': { 'fi': 'Näkösyvyys, m', 'en': 'Secchi depth, m', 'sv': 'Siktdjupet, m', 'ru': 'm' } | ||
+ | }, | ||
+ | 'level': { | ||
+ | 'type': 'num', | ||
+ | 'season': 'summer', | ||
+ | 'trend': { 'type': 'gaussian', 'layout': 'line' }, | ||
+ | 'title': { 'fi': 'Vedenkorkeus', 'en': 'Water level', 'sv': 'Vattenståndpunkt', 'ru': '???' }, | ||
+ | 'unit': 'cm', | ||
+ | 'axisTitleV': { 'fi': 'Vedenkorkeus, cm', 'en': 'Water level, cm', 'sv': 'Vattenståndpunkt, cm', 'ru': 'cm' } | ||
+ | }, | ||
+ | 'average': { 'fi': 'Keskimäärin', 'en': 'Average', 'sv': 'Genomsnitt', 'ru': '???' }, | ||
+ | 'trendline': { 'fi': 'Trendiviiva', 'en': 'Trend line', 'sv': 'Trendlinje', 'ru': '???' }, | ||
+ | 'month': { 'fi': 'Kuukausi', 'en': 'Month', 'sv': 'Månad', 'ru': '???' }, | ||
+ | 'months': { | ||
+ | 0: { | ||
+ | 'long': { 'fi': 'Tammikuu', 'en': 'January', 'sv': 'Januari', 'ru': '???' }, | ||
+ | 'short': { 'fi': 'Tammi', 'en': 'Jan', 'sv': 'Jan', 'ru': '???' }, | ||
+ | 'roman': 'I' | ||
+ | }, | ||
+ | 1: { | ||
+ | 'long': { 'fi': 'Helmikuu', 'en': 'Febryary', 'sv': 'Februari', 'ru': '???' }, | ||
+ | 'short': { 'fi': 'Helmi', 'en': 'Feb', 'sv': 'Feb', 'ru': '???' }, | ||
+ | 'roman': 'II' | ||
+ | }, | ||
+ | 2: { | ||
+ | 'long': { 'fi': 'Maaliskuu', 'en': 'March', 'sv': 'Mars', 'ru': '???' }, | ||
+ | 'short': { 'fi': 'Maalis', 'en': 'Mar', 'sv': 'Mar', 'ru': '???' }, | ||
+ | 'roman': 'III' | ||
+ | }, | ||
+ | 3: { | ||
+ | 'long': { 'fi': 'Huhtikuu', 'en': 'April', 'sv': 'April', 'ru': '???' }, | ||
+ | 'short': { 'fi': 'Huhti', 'en': 'Apr', 'sv': 'Apr', 'ru': '???' }, | ||
+ | 'roman': 'IV' | ||
+ | }, | ||
+ | 4: { | ||
+ | 'long': { 'fi': 'Toukokuu', 'en': 'May', 'sv': 'Maj', 'ru': '???' }, | ||
+ | 'short': { 'fi': 'Touko', 'en': 'May', 'sv': 'Maj', 'ru': '???' }, | ||
+ | 'roman': 'V' | ||
+ | }, | ||
+ | 5: { | ||
+ | 'long': { 'fi': 'Kesäkuu', 'en': 'June', 'sv': 'Juni', 'ru': '???' }, | ||
+ | 'short': { 'fi': 'Kesä', 'en': 'Jun', 'sv': 'Jun', 'ru': '???' }, | ||
+ | 'roman': 'VI' | ||
+ | }, | ||
+ | 6: { | ||
+ | 'long': { 'fi': 'Heinäkuu', 'en': 'July', 'sv': 'Juli', 'ru': '???' }, | ||
+ | 'short': { 'fi': 'Heinä', 'en': 'Jul', 'sv': 'Jul', 'ru': '???' }, | ||
+ | 'roman': 'VII' | ||
+ | }, | ||
+ | 7: { | ||
+ | 'long': { 'fi': 'Elokuu', 'en': 'August', 'sv': 'Augusti', 'ru': '???' }, | ||
+ | 'short': { 'fi': 'Elo', 'en': 'Aug', 'sv': 'Aug', 'ru': '???' }, | ||
+ | 'roman': 'VII' | ||
+ | }, | ||
+ | 8: { | ||
+ | 'long': { 'fi': 'Syyskuu', 'en': 'September', 'sv': 'September', 'ru': '???' }, | ||
+ | 'short': { 'fi': 'Syys', 'en': 'Sep', 'sv': 'Sep', 'ru': '???' }, | ||
+ | 'roman': 'IX' | ||
+ | }, | ||
+ | 9: { | ||
+ | 'long': { 'fi': 'Lokakuu', 'en': 'October', 'sv': 'Oktober', 'ru': '???' }, | ||
+ | 'short': { 'fi': 'Loka', 'en': 'Oct', 'sv': 'Okt', 'ru': '???' }, | ||
+ | 'roman': 'X' | ||
+ | }, | ||
+ | 10: { | ||
+ | 'long': { 'fi': 'Marraskuu', 'en': 'November', 'sv': 'November', 'ru': '???' }, | ||
+ | 'short': { 'fi': 'Marras', 'en': 'Nov', 'sv': 'Nov', 'ru': '???' }, | ||
+ | 'roman': 'XI' | ||
+ | }, | ||
+ | 11: { | ||
+ | 'long': { 'fi': 'Joulukuu', 'en': 'December', 'sv': 'December', 'ru': '???' }, | ||
+ | 'short': { 'fi': 'Joulu', 'en': 'Dec', 'sv': 'Dec', 'ru': '???' }, | ||
+ | 'roman': 'XII' | ||
+ | } | ||
+ | } | ||
+ | }; | ||
</script> | </script> | ||
</includeonly> | </includeonly> |