maanantai 27. huhtikuuta 2015

Yli 2 miljoonaa "swaippausta", Kandideitti oli menestys

Julkaisimme vaalien alla Kandideitti-nimisen sovelluksen, joka tunnettiin myöhemmin myös Vaalitinder-nimellä.

Kandideitti oli eräänlainen minivaalikone, jonka avulla sopivaa ehdokas etsittiin viiden asiakysymyksen kautta perustuen pelkästään ehdokkaiden kasvokuvaan, ikään ja etunimeen. Idea oli lainattu suositusta treffipalvelu Tinderistä.

Ehdokkaat saattoi joko hyväksyä tai hylätä annettujen tietojen perusteella. (Kuva 1)

Kandideitin tarkoitus oli lisätä erityisesti sellaisten ihmisten kiinnostusta vaaleihin, jotka eivät tavallisesti vaaleista innostu. Miten tämä tavoite täytty lukujen valossa?

Google Analytics -lukujen mukaan Kandideitillä oli noin 50 000 yksilöityä käyttäjää. Nämä käyttäjät hylkäsivät ja hyväksyivät ehdokkaita 2 150 000 kertaa. Eli reilut kaksi miljoonaa kertaa. Sovelluksen käyttäjät olivat siis erittäin ahkeria. Keskimäärin yksittäinen käyttäjä kävi läpi yli 40 ehdokasta, joka on todella suuri luku.

Tämä kertoo, että Kandideitti löysi erittäin aktiivisen käyttäjäryhmän, joka koki sovelluksen siinä määrin erittäin hyödylliseksi, että sen parissa viettiin paljon aikaa. Vaikeampi kysymys on arvioida ovatko nämä käyttäjät olleet etenkin sellaisia, jotka eivät muuten kiinnostu vaaleista. Ja vielä vaikeampi kysymys on saiko Kandideitti nämä ihmiset äänestämään tai vaikuttiko Kandideitti heidän äänestyspäätökseensä.

Kuten odottaa saattoi oli hylkääminen (1 800 000) erittäin paljon hyväksymistä (350 000) yleisempää. Löytöjä syntyi noin 57 %:ssa hyväksymisistä, joka on käytännössä sama kuin löydölle asetettu raja-arvo (3/5 asiakysymyksestä tuli olla samaa mieltä).

Kävijämäärä oli lopulta pienoinen pettymys. Odotimme jutulle yli 100 000 klikkausta, mutta jäimme tavoitteesta. Jutulla on tällä hetkellä ComScoren mukaan noin 79 000 klikkiä. Mutta ehkä näissä luvuissa näkyy juuri se, että Kandideitti oli kuitenkin lopulta pienemmän kohderyhmän niche-palvelu verrattuna Ylen muihin vaalituotteisiin (Vaalikone ja Vaaligalleria).

sunnuntai 19. huhtikuuta 2015

KML to GeoJSON to TopoJSON on Mac OS X

These introductions help you to convert a KML file to TopoJSON which allows you to reduce filesize.

Converting KML to TopoJSON


# Get KML (File -> Download -> KML)
https://www.google.com/fusiontables/DataSource?docid=153JjwSASwB6C4r1o0itwZr7imkDfuedEGIjk4LHr#map:id=3

# Install node via ports or brew (if not yet available)
port install npm
brew install node.js

# Install togeojson (might need admin privilidges)
npm install -g togeojson

# Rename file to data.kml
cd Downloads
mv Kuntarajat\ 2015.kml data.kml

# Convert KML to GeoJson with togeojson
togeojson data.kml > data.json

# Install topojson (might need admin privilidges)
npm install -g topojson

# Convert GeoJson to TopoJson
topojson data.json -o data.tjson -p Name

# Simplify if needed
topojson data.json -o data.tjson --simplify-proportion=0.5 -p Name

# Use tools to determinate appropriate simplify value
http://www.mapshaper.org/
http://shancarter.github.io/distillery/



Implementation guidelines


# Get TopoJSON library
https://github.com/mbostock/topojson

# In your implementation define a map
var map = new google.maps.Map($('.map_container')[0], {
    center:new google.maps.LatLng(60.25, 24.87),
    mapTypeControl:false,
    mapTypeId:google.maps.MapTypeId.ROADMAP,
    minZoom:9,
    overviewMapControl:true,
    panControl:true,
    scaleControl:false,
    streetViewControl:false,
    zoom:yleApp.zoom,
    styles:styler,
    zoomControl:true
});

# Attach polygons to the map
$.getJSON('data.tjson', function (data) {
    yleApp.map.data.addGeoJson(topojson.feature(data, data.objects.data));
});

# Define polygon styles
yleApp.map.data.setStyle(function (feature) {
  return {
    cursor:'pointer',
    fillColor:'#f00',
    fillOpacity:0.6,
    strokeColor:'#666',
    strokeWeight:0.5
  }
});

# Attach listeners
map.data.addListener('mouseover', function (event) {
  yleApp.map.data.overrideStyle(event.feature, {
    fillOpacity:0.8,
    strokeWeight:1
  });
});

map.data.addListener('mouseout', function (event) {
  map.data.revertStyle();
});