Gå til innhold
Arkivverket

Tidslinje personsøk


Bård Hansen
 Del

Recommended Posts

Kort fortalt: Jeg har laget noe Javascript kode for å legge til tidslinje i bunnen av et personsøk.

 

 

 

Den følgende koden eller diskusjonen som er presentert nedenfor, kan inneholde eksempler eller forslag til å omgå Content-Security-Policy (CSP). Det er viktig å merke seg at omgåelse av CSP kan føre til alvorlige sikkerhetsrisikoer og bør ikke prøves uten nøye overveielse og forståelse av konsekvensene.


Deltakelse i eller implementering av kode som omgår CSP skjer på egen risiko. Forfatteren og alle involverte bidragsytere fraskriver seg ethvert ansvar for eventuelle skader, tap eller sikkerhetssårbarheter som kan oppstå som følge av bruken av slik kode. Det anbefales sterkt å følge beste praksis for nettutvikling og respektere hensikten bak Content-Security-Policy for å opprettholde en trygg og sikker nettopplevelse.

Innholdet i denne posten er kun til informasjonsformål og bør ikke tolkes som oppfordring til å omgå sikkerhetsforanstaltninger.

 

Bruk av koden og eksemplene gitt her er underlagt følgende betingelser. Koden som er utviklet og delt i dag, kan fritt brukes, endres og distribueres for personlig eller kommersiell bruk uten noen restriksjoner. Imidlertid må du være oppmerksom på at implementasjonen av Highcharts-biblioteket, som er nevnt i koden, krever en gyldig Highcharts-lisens for produksjonsbruk. Koden som viser bruk av Highcharts er kun ment for testing og utvikling, og vi fraskriver oss ethvert ansvar for bruk av denne koden i produksjonsmiljøer uten en gyldig Highcharts-lisens. For å dra full nytte av Highcharts i produksjonsmiljøer, anbefales det sterkt å skaffe en lisens fra Highcharts-leverandøren. Vi påtar oss ikke ansvar for eventuelle konsekvenser av bruken av Highcharts uten en gyldig lisens.

 

 

 

For å kunne kjøre koden har jeg brukt Chrome extension Disable Content-Security-Policy.

 

Koden må pastes inn i Console i tre omganger, slik at første bibliotek lastes før andre bibliotek osv.

 

Første snutt:

// Opprett den første script-tagen
var script1 = document.createElement('script');
// Angi kilden (URL) til den første eksterne JavaScript-filen
script1.src = 'https://code.highcharts.com/highcharts.js';
// Legg til script1 i head-elementet (eller et annet sted på siden)
document.head.appendChild(script1);

 

 

Andre snutt:

// Opprett den andre script-tagen
var script2 = document.createElement('script');
// Angi kilden (URL) til den andre eksterne JavaScript-filen
script2.src = 'https://code.highcharts.com/modules/timeline.js';
// Legg til script2 i head-elementet (eller et annet sted på siden)
document.head.appendChild(script2);

 

 

Til slutt:


function removeConsecutiveWhitespace(inputString) {
	// Resultatet starter med det første tegnet i strengen
	var result = inputString[0];
	
	// Gå gjennom hver karakter i strengen, starter fra indeks 1
	for (var i = 1; i < inputString.length; i++) {
		var currentChar = inputString[i];
		
		// Sjekk om gjeldende tegn er et mellomrom, tabulator, retur eller linjeskift
		if (' \t\r\n'.includes(currentChar)) {
			// Sjekk om gjeldende tegn ikke er det samme som forrige tegn
			if (currentChar !== inputString[i - 1]) {
				result += currentChar;
			}
			} else {
			result += currentChar;
		}
	}
	return result;
}

var resultListContainer = document.getElementById('resultListContainer');
// Opprett en ny div
var nyDiv = document.createElement('div');
// Sett id-en til den nye div-en
nyDiv.id = 'timeline-container';
// Legg til klassene til den nye div-en
nyDiv.className = 'col-xs-12 col-md-8 col-lg-9';
// Legg til innhold eller attributter til den nye div-en om nødvendig
nyDiv.textContent = 'Dette er den nye div-en';
// Sett inn den nye div-en etter resultListContainer
resultListContainer.parentNode.insertBefore(nyDiv, resultListContainer.nextSibling);

// Hent alle elementene med klassen "data-item"
var dataItems = document.querySelectorAll(".data-item");
// Sett starttidspunktet basert på ditt behov (for eksempel 1800-01-01)
var pointStart = Date.parse('1800-01-01');
// Sett avstanden mellom punktene til én dag
var pointInterval = 24 * 3600 * 1000; // Én dag i millisekunder

// Opprett et tomt array for å lagre tidslinjedata
var timelineData = [];
// Gå gjennom hver "data-item"
dataItems.forEach(function (item, index) {
	// Hent datoen fra den relevante <td>
	var dateElement = item.querySelector('td:nth-child(6)'); // Juster indeksen basert på plasseringen av datoen i din HTML-struktur
	var date = dateElement.textContent.trim();
	// Beregn tidspunktet for datapunktet basert på pointStart og den faktiske datoen
	var pointTime = Date.parse(date);
	
	// Hent relevante <td> elementer
	var tdElements = item.querySelectorAll('td');
	// Opprett en midlertidig array for å lagre tekstinnholdet av hver <td>
	var tdContentArray = [];
	// Hent textContent fra hver <td>, trim og fjern påfølgende mellomrom
	tdElements.forEach(function (td) {
		var content = removeConsecutiveWhitespace(td.textContent.trim()) || '';
		tdContentArray.push(content);
	});
	// Opprett et JavaScript-objekt med etiketter og verdier
	var data = {
		'navn': tdContentArray[0],
		'fodselsdato': tdContentArray[1],
		'fodested': tdContentArray[2],
		'stillingOgStand': tdContentArray[3],
		'bosted': tdContentArray[4],
		'hendelsesdato': tdContentArray[5],
		'rolle': tdContentArray[6],
		'kilde': tdContentArray[7]
	};
	
	// Lag en beskrivelse ved å kombinere textContent fra alle <td> elementer, unntatt det siste
	var description = data.navn + '<br>' +
					  'Født: ' + data.fodselsdato + ' ' + data.fodested + '<br>' +
					  'Fødested: ' + data.fodested + '<br>' +
					  'Stilling og stand: ' + data.stillingOgStand + '<br>' +
					  'Bosted: ' + data.bosted + '<br>' +
					  'Rolle: ' + data.rolle + '<br>' +
					  'Kilde: ' + data.kilde;
	
	var words = data.kilde.split(' ');
	var name = words[0].replace('bok', '') + ' ' + data.hendelsesdato.substring(0,4) + ' ' + data.rolle + '<br>';
	// Legg til datapunkt i tidslinjen
	timelineData.push({
		name: name,
		label: name + data.navn,
		x: Date.parse(date),
		y: 0, // Y-verdi kan være 0 for tidslinjediagram
		description: description,
	});
});




// Konfigurer Highcharts tidslinjediagram
var chart = Highcharts.chart('timeline-container', {
	chart: {
		type: 'timeline',
		zoomType: 'x',
	},
	xAxis: {
		type: 'datetime',
		tickInterval: 5 * 365 * 24 * 3600 * 1000, // Hvert femte år i millisekunder
		dateTimeLabelFormats: {
			year: '%Y', // Vis bare år på aksen
		},
	},
	yAxis: {
		gridLineWidth: 1,
		title: null,
		labels: {
			enabled: false,
		},
	},
	legend: {
		enabled: false,
	},
	title: {
		text: 'Tidslinje',
	},
	subtitle: {
		text: ''
	},
	tooltip: {
		style: {
			fontSize: '16px', // Juster størrelsen etter behov
			width: 350,
		}
	},
	series: [{
		data: timelineData,
		pointStart: pointStart,
		pointInterval: pointInterval,
		dataLabels: {
			allowOverlap: false,
			format: '<span style="color:{point.color}"></span>' +
			'<span style="font-weight: bold;" >{point.x:%Y-%m-%d}</span><br>' +
			'<span style="font-weight: normal;">{point.label}</span>',
			style: {
				fontSize: '14px' // Juster størrelsen etter behov
			},
		},
		marker: {
			symbol: 'circle'
		}
	}],
});

 

Søk brukt i eksempel: https://www.digitalarkivet.no/search/persons/advanced?from=&to=&firstname=Fridjof&lastname=Nansen&birth_year_from=1861&birth_year_to=1861&birth_date=&birth_place=&domicile=&position=&event_year_from=&event_year_to=&event_date=&related_first_name=&related_last_name=&related_birth_year=&sort=ed

 

Fornavn: Fridjof

Etternavn; Nansen

Fødselsår: 1861

 

 

Resultat:

resultat.thumb.png.880eab25d8fcb74e9db5c30107c07079.png

 

 

Zoomet inn:

zoom.thumb.png.e6c9febdf9fd0689f5e68f410a06c701.png

 

Lenke til kommentar
Del på andre sider

Hei @Renathe-Johanne Wågenes - Arkivverkether bør du gå inn og påpeke at alle brukere i dette tilfelle denne @wittrupsom skal ha både for og etternavn med i visningsnavnet sitt . Samt legge ut lenke / lenker til bruksanvisning for hvordan man forandrer visningsnavnet til et fullt og gyldig visningsnavn .

 

Og kanskje du også seriøst burde vurdere om dette er SPAM 

Lenke til kommentar
Del på andre sider

@Bjørn Andreas Johansønn Løkken, takk.

Profil oppdatert @Renathe-Johanne Wågenes - Arkivverket.

 

For øvrig sendt inn scriptene via kontaktskjema også, adressert til utviklere ved digitalarkivet.


 

Akkurat ferdig med sortering og visualisering av emigrantprotokoll.

Da blir resultatet slik, med dato og antall personer for Utreisedato, ved å holde musen over vises navnene på de som reiste den dagen (utifra søket som er gjort).

emigrantprotokoll_tidslinje.thumb.JPG.81809f98c1a55ac671fd68e6f8d719db.JPG

 

 

Kode her:

// SORTERING:
var dataItems = document.querySelectorAll(".data-item");
var i = dataItems.length - 1;
while (0 < i) {
    var rowCurrent = document.querySelectorAll(".data-item")[i];
    var dateTextCurrent = rowCurrent.querySelector('td:nth-child(7)').textContent.trim();
    var dateCurrent = new Date(dateTextCurrent);  // Konverter datotekst til en JS Date-objekt

    var rowBefore = document.querySelectorAll(".data-item")[i - 1];
    var dateTextBefore = rowBefore.querySelector('td:nth-child(7)').textContent.trim();
    var dateBefore = new Date(dateTextBefore);

    if (dateCurrent < dateBefore) {
        // Dytt gjeldende rad mot starten av listen
        var parent = rowCurrent.parentNode;
        var detached = parent.removeChild(rowCurrent);
        parent.insertBefore(detached, rowBefore);
        i = dataItems.length - 1; // Start løkken på nytt etter endring i rekkefølge
    } else {
        i--; // Gå videre til neste rad i den opprinnelige rekkefølgen
    }
}



// DATA GENERERING:
var dataItems = document.querySelectorAll(".data-item");
var timelineData = [];

dataItems.forEach(function (item) {
    var name = item.querySelector('td:nth-child(2)').textContent.trim();
    var dateText = item.querySelector('td:nth-child(7)').textContent.trim();
    var date = new Date(dateText);

    // Sjekk om datoen allerede er i timelineData
    var existingData = timelineData.find(function (data) {
        return data.x === date.getTime();
    });

    if (existingData) {
        // Legg til navnet i beskrivelsen hvis datoen allerede finnes
        existingData.description += '<br>' + name;
		existingData.label++;
    } else {
        // Legg til nytt objekt i timelineData hvis datoen ikke finnes
        timelineData.push({
            x: date.getTime(),
            label: 1,
            description: '<b>' + dateText + '</b><br>' + name,
        });
    }
});

// Sorter timelineData basert på x-verdien (dato)
timelineData.sort(function (a, b) {
    return a.x - b.x;
});



// Oppdater tidslinjedata i diagrammet
chart.update({series: [{data: timelineData}]});

 

Endret av Bård Hansen
code fix
Lenke til kommentar
Del på andre sider

Join the conversation

Du kan poste nå og registrere deg senere. If you have an account, sign in now to post with your account.

Gjest
Skriv svar til emnet...

×   Du har limt inn tekst med formatering.   Fjern formatering

  Only 75 emoji are allowed.

×   Lenken din har blitt bygget inn på siden automatisk.   Vis som en ordinær lenke i stedet

×   Ditt forrige innhold har blitt gjenopprettet .   Tøm tekstverktøy

×   You cannot paste images directly. Upload or insert images from URL.

 Del

  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...

Viktig Informasjon

Arkivverket bruker cookies (informasjonskapsler) på sine nettsider for å levere en bedre tjeneste. De brukes til bl.a. skjemaoppdateringer og innlogging. Bruk siden som normalt, eller lukk informasjonsboksen for å akseptere bruk av cookies.