// https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3 // https://en.wikipedia.org/wiki/List_of_International_Space_Station_expeditions // https://en.wikipedia.org/w/api.php?action=parse&page=List_of_International_Space_Station_expeditions&format=json§ion=1&prop=wikitext // https://www.mediawiki.org/wiki/API:Parsing_wikitext#Example_2:_Parse_a_section_of_a_page_and_fetch_its_table_data // To be kept up to date with the total number of json files loaded const maxDataSources = 4; // We keep track of how many data sources we have loaded. var dataSourcesLoaded = 0; // Maximum height for the Timeline var maxHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0) - 50; // Date and time variables for setting the Timeline to "now" var date = new Date(); var timespan = 60 * 24 * 180; /* About 6 months */ var sta = new Date(date.getTime() - (1000 * 60 * (timespan * 0.1))); var end = new Date(date.getTime() + (1000 * 60 * timespan)); // Timeline groups definition var groups = new vis.DataSet([ { id: 'EXP', content:'Expedition', groupOrder:'start' }, { id: 'CREW', content:'Equipaggi', groupOrder:'start',subgroupOrder:'content' }, { id: 'SOYUZ', content:'Soyuz', groupOrder:'start',subgroupOrder:'content' }, { id: 'EVA', content:'EVA', groupOrder:'start',subgroupOrder:'content' }, ]); // Timeline options // Templates are defined in app_handlebars.js var options = { start: sta.toISOString(), end: end.toISOString(), min: '2000-09-01T00:00:00.000Z', max: '2030-01-01T00:00:00.000Z', template: function (item) { var template = templates[item.template]; // choose the right template return template(item); // execute the template }, zoomMin: 1000 * 60 * 60 * 24, // one day in milliseconds zoomMax: 1000 * 60 * 60 * 24 * 31 * 12 * 5, // about two months in milliseconds locale: 'it_IT', maxHeight: maxHeight, showCurrentTime: true //clickToUse: true }; // Timeline items var items = new vis.DataSet({ type: { start: 'ISODate', end: 'ISODate' } }); // subscribe to any change in the DataSet items.on('*', function (event, properties, senderId) { // We want all data sources to be loaded before shifting the timeline. if (dataSourcesLoaded < maxDataSources) return; console.log('event', event, properties); maxDateTime = -1; for (var i = 0; i < properties.items.length; i++) { var key = properties.items[i]; var item = items.get(key); if (item.end != null) { var test = Number(moment.utc(item.end,'Y-M-D\Th:m:s.S\Z').format("X")); // console.log(item.end,test); if (test > maxDateTime) maxDateTime = test; } } maxDateTime = maxDateTime*1000; console.log("Last item detected: " + moment(maxDateTime).format('YYYY-MM-DDTHH:mm:ss.SSSZ')); timeline.setWindow(moment.utc(maxDateTime-(60*60*24*60*1000)).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),moment.utc(maxDateTime+(60*60*24*7*1000)).format('YYYY-MM-DDTHH:mm:ss.SSSZ'), {animation: true}); }); // DOM element where the Timeline will be attached var container = document.getElementById('visualization'); // Initialise trimeline, no items yet console.log("Creating Timeline now..."); var timeline = new vis.Timeline(container, items, groups, options); // load data via an ajax request. When the data is in, load the timeline $.ajax({ url: 'data/crew.json', dataType: 'json', success: function (data) { dataSourcesLoaded++; console.log("Loading crew.json"); // console.log(data); data.forEach(function (arrayItem) { arrayItem['type'] = 'range'; arrayItem['template'] = 'crew-template'; arrayItem['group'] = 'CREW'; }); items.update(data); }, error: function (err) { console.log('Error', err); } }); // load data via an ajax request. When the data is in, load the timeline var cls = true; $.ajax({ url: 'data/expedition.json', dataType: 'json', success: function (data) { dataSourcesLoaded++; console.log("Loading expedition.json"); // console.log(data); data.forEach(function (arrayItem) { arrayItem['type'] = 'background'; arrayItem['template'] = 'expedition-template'; arrayItem['group'] = 'EXP'; if (cls) { arrayItem['className'] = 'exp-positive'; } else { arrayItem['className'] = 'exp-negative'; } cls = !cls; }); items.update(data); }, error: function (err) { console.log('Error', err); } }); // load data via an ajax request. When the data is in, load the timeline $.ajax({ url: 'data/sojuz.json', dataType: 'json', success: function (data) { dataSourcesLoaded++; console.log("Loading sojuz.json"); // console.log(data); data.forEach(function (arrayItem) { arrayItem['type'] = 'range'; arrayItem['template'] = 'sojuz-template'; arrayItem['group'] = 'SOYUZ'; arrayItem['className'] = 'sojuz'; }); items.update(data); }, error: function (err) { console.log('Error', err); } }); // load data via an ajax request. When the data is in, load the timeline $.ajax({ url: 'data/eva.json', dataType: 'json', success: function (data) { dataSourcesLoaded++; console.log("Loading eva.json"); // console.log(data); data.forEach(function (arrayItem) { /*if (arrayItem['end'] == null) { arrayItem['type'] = 'point'; } else { arrayItem['type'] = 'range'; }*/ arrayItem['template'] = 'sojuz-template'; arrayItem['type'] = 'point'; arrayItem['group'] = 'EVA'; arrayItem['className'] = 'eva'; }); items.update(data); }, error: function (err) { console.log('Error', err); } }); //================================================================= // Handling click event (experimental) timeline.on('click', function (properties) { if (properties.group != 'EXP') return; // retrieve a filtered subset of the data var expItems = items.get({ filter: function (item) { return item.group == 'EXP'; } }); for (var i = 0; i < expItems.length; i++) { var t1 = moment.utc(properties.time); var c1 = t1.isAfter(expItems[i].start); var c2 = t1.isBefore(expItems[i].end); if (c1 && c2) { console.log(c1,c2); console.log(expItems[i]); break; } } if (c1 && c2) { var header = document.getElementById('modalTitle'); var description = document.getElementById('modalBody'); description.innerHTML = ''; header.innerHTML = ''; header.innerHTML = expItems[i].content; description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += 'Inizio: ' + expItems[i].start.substr(0, 16); description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += 'Fine: ' + expItems[i].end.substr(0, 16); description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += '
'; $("#myModal").modal(); } }); // Handling select event - clicking on an item, does not trigger for background items timeline.on('select', function (properties) { console.log(properties.items.length); if (properties.items.length != 1) return; showModalWindow(properties); }); // Show modal window function showModalWindow(properties) { var header = document.getElementById('modalTitle'); var description = document.getElementById('modalBody'); description.innerHTML = ''; header.innerHTML = ''; if (items.length == 0) return; var key = properties.items[0]; var item = items.get(key); console.log(item) if (item['group'] == 'CREW') { header.innerHTML = item['content']; description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += '
Info
'; description.innerHTML += ''; description.innerHTML += '
'; } if (item['group'] == "EVA") { // description.innerHTML = anchorme.js(decodeURIComponent(item.content)); header.innerHTML = item['content']; description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += '
Inizio
'; description.innerHTML += '
'+ item['start'] +'
'; description.innerHTML += '
'; if (item['end'] != null) { description.innerHTML += '
'; description.innerHTML += '
Fine
'; description.innerHTML += '
'+ item['end'] +'
'; description.innerHTML += '
'; var measuredTime = new Date(null); measuredTime.setSeconds(item['duration']); // specify value of SECONDS var MHSTime = measuredTime.toISOString().substr(11, 8); description.innerHTML += '
'; description.innerHTML += '
Durata
'; //description.innerHTML += '
'+ hours + ':' + minutes + ':' + seconds + '
'; description.innerHTML += '
'+ MHSTime + '
'; description.innerHTML += '
'; } description.innerHTML += '
'; description.innerHTML += '
Partecipanti
'; description.innerHTML += '
'+ item['spacewalkers'] +'
'; description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += '
Portello
'; description.innerHTML += '
'+ item['from'] +'
'; description.innerHTML += '
'; description.innerHTML += '
'; } if (item['group'] == "SOYUZ") { // description.innerHTML = anchorme.js(decodeURIComponent(item.content)); header.innerHTML = item['content']; description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += '
'; description.innerHTML += '
Inizio
'; description.innerHTML += '
'+ item['start'] +'
'; description.innerHTML += '
'; if (item['end'] != null) { description.innerHTML += '
'; description.innerHTML += '
Fine
'; description.innerHTML += '
'+ item['end'] +'
'; description.innerHTML += '
'; } description.innerHTML += '
'; } /* else { description.innerHTML += JSON.stringify(properties); description.innerHTML += JSON.stringify(item); } */ $("#myModal").modal(); }