poniedziałek, 22 lutego 2016

Interactive Presidential Election financing map

Return to the top
Time: 10-14 days

Original request

The project was done for Social Networks ([TASS]) course on my university. The task was to represent financing of candidates as a map in a neat way. The map was supposed to allow the user to choose between individual contributions and contributions via political committees. The choice of elections was left up to the student so I picked 2012 national election.

I chose to do project in Unity3D because it was a lifeboat for me. Originally I planned to use Google Maps API but since it requires JavaScript and I was too short on time to learn it I went for tools I've used before - Unity3D.




Warning: Code is a complete mess so if you decide to open it in order to analyze it you are doing it on your own risk. For in this code dragons and tentacle monsters await to do unspeakable things to you.

How to use

Project can be only viewed in Unity window. It can't be exported to exe. This is due to using standard C# reading data method instead of Unity reading method.

After opening the project there should be one object called "Master" on the scene. If it isn't there open scene <scene_1>.

After pressing "play" user sees "Main view".

Main view

  1. Map of USA with charts objects
  2. Panel for choosing types and size of contributions
  3. Panel for choosing the visible states charts
  4. Panel showing information about clicked state
  5. Code of clicked state
  6. Button allowing to go to the "State view"

  • Charts objects[1] - After clicking a chart, panel [5] displays detailed information about financing in the state. Financing criteria are based on tick-boxes in panel[2]. Click bars or space between them (not the text below).
  • Tick-boxes in panel[2] - Allows to choose which contributions will be used. It is allowed to choose size of contributions (small, medium, big, huge) and source of contribution (individual or authorized committee).
  • Tick-boxes in panel [3] - allows to enable or disable display of charts.
  • Button [6] - allows to go to the "State view"

Object details:
  • Charts - Two bars represent financing for each candidate (blue - Obama, red - Romney). Height of bars is proportional to the contributions gathered. Under the chart there is a text with code of the state and percentage share of contributions (first number is for Obama).
  • Tick-boxes in panel[2] - tick-boxes allow to restrict what kind of contributions will be used for the map. Based on single contribution size they are classified as: small (0-250$), medium(250$-500$), big (500-1000$), huge (1000$++)
  • Panel [4] - at first it doesn't show any information (marked as YY/YY). After clicking a state chart panel fills up with financing data in a state. Four rows <number>/<number> display information about how big percent make contributions of given size in reference to total of contributions. First number refers to Barrack Obama, second to Mitt Romney. Information is filtered according to the tick-boxes in panel [2]. If there is an error (tick-boxes filters all data) XX/XX is displayed.

State view

"State view" is similar to "Main view". Changes involve:
  • Chart for the biggest cities are displayed instead of charts of the states - cities were chosen from the list of 300 biggest cities in USA. There is a limit of 6 cities per state.
  • Panel [7] - represents contributions in areas that weren't covered by the cities
  • Button[8] - allows to switch to "Main view"


In order to make the project work it was needed to prepare set of data and scripts.

  • FEC csv files - 4 table containing as records single contributions. Separate files for individual and authorized political committees for 2 candidates (Barrack Obama and Mitt Romney).
  • Static Google map API - generates map image based on html request. Allows to set zoom, resolution, markers. API can get location either from geographical coordinates or from names (for example "AK+state+USA").
  • List of 300 biggest cities in USA (wikipedia)- needed for choosing cities in the "State view". Cities were limited to 6 per state.
  • Sorted list of states by total area (wikipedia) - order determines the zoom. Smaller states require bigger zoom

  • Java script for data aggregation - summing up records by size of contribution and location (city/state)
  • Java script for downloading maps - project requires one map serving as a background and series of maps with a single marker for finding states/cities
  • Java script for finding red marker location - scripts finds the peak of the marker in the image

Map building

Firstly the map with no marker was downloaded. This map serves as a background. Then for each state there was downloaded an image with single red marker pointing at state. In order to know where to place chart objects in Unity3D we need to use proportion. For each image with marker the position of the peak of the marker is found and saved in a text file. In addition we know the width and height of the image (in pixels) and the width and height of the image in Unity position units (using bound.size).

Sidenote: marker used are reds because they stand out from green-blue colours used in map. While searching from peak of the marker scripts start from bottom right and goes up. This makes sure that first pixel that is red enough is the peak of the marker

Background image

Image with Louisiana marked

Piece of text file used for positioning charts on USA map. Format of lines: <x pixel position of peak>, <width of image>, <y pixel position of peak>, <height of image>

Proportions for chart position explained. Only "x position in Unity" is unknown.

In order to display right image (the image of picked state and not any of other ones) in the "State view" function "Resources.LoadAll<Sprite> ()" was used.

Click on self

Before I switched to Unity I was working in Stencyl. Stencyl has a nice event called "When pressed on self" which triggers event whenever a player pressed mouse while on the sprite of the Game object. I know that in Unity this is usually done by using raycasting. Since I'm not yet familiar with raycasting and I felt comfortable with using Stencyl thinking I wrote Unity version of "When pressed on self".

Code is realized by "OnClickScript" script.

How it works:
  1. Object is created
  2. Object is assigned a sprite
  3. Object calls "ignite" function giving as parameters coordinates of left top and right bottom corners of sprite. Coordinates in Unity position units.
  4. For object <mode> variable is set. This says which function will trigger upon clicking on the object.
  5. When mouse is clicked mouse position is translated from pixels to Unity position units. If object is clickable (as marked by <clickable> bool variable) and mouse is inside the rectangle ("created" during "ignite call") the function is called. The choice of function is based on <mode> variable.

The reason why "ignite" function takes corners (green points) and not sprite as argument is because by giving corners user can click on any place between the corners, even space between the bars, and it will still trigger a function.

Setting <clickable> as false can temporary disable the script. This is useful when user switches to "State view". States charts are only made invisible (they are not destroyed) but in order not to make something stupid clicking invisible objects must be disabled. That's when setting <clickable> as false comes in.

Scaling the bars (the right way)

Hierarchy of chart object:
  • chart - main object
  • TextObject - contains text under chart
  • BlueGuardian - used for scaling
    • BlueObject - blue bar

  • RedGuardian - used for scaling

    • RedObject - red bar

    BlueObject and RedObject are placed in such way that the bottom of the bar is at the centre of BlueGuardian and RedGuardian objects. This is important because we want bars to grow and not scale along their centre.

    Point shows the centre of BlueGuardian. Blue bar(BlueObject) is placed so it's bottom is at the centre of BlueGuardian.

    Scaling explained: 1 - chart object; 2- BlueObject with scale y=2, not really what we want; 3 -BlueGuardian with scale y=2, exactly what we wanted


    While making the project several things made my life more difficult.

    Data parsing:
    • In the csv file if column in form of "\" would make the program unresponsive.
    • A lot of random dots, commas, spacebars in places where they shouldn't be
    • For the "State view" there was a need to generate pictures with state as background and the marker on the single city. Name of the images must have described what was in the picture. Using spacebar was confusing as you don't know whether you mean spacebar as separation between city and state or separation between two words of the state (New <spacebar> York). In the end the naming convention was <state with "_" as separator if name of the state had more than one word in name> "+" < city with "_" as separator if name of the city had more than one word in name>

    Static Google maps:

    This can be very tricky. If you ask for place not detailed enough you can get strange results. Asking for "USA+LA" gives Laos. Asking for "Washington+USA" gives Washington D.C. and not the state of Washington. In some cases the marker can be placed out of the picture. While using static Google maps be sure to check if there is actually marker on the map.

    Negative contribution:

    I don't know how does it work but in the contribution data there are records which have negative values. These data have been omitted.

    There were others problems as well but they were more kind of one time thing that something that was causing trouble through the project. Of course you can deal with these problems but while being overworked and tired dealing with random commas is something extremely irritating.

    Thank you for reading. If you have any questions be sure to ask on Newgrounds, Twitter or in the comments below.

    Tags: Election, map, static, Google, 2012, maps, FEC, presidential, president, vote, campaign, contribution, financing, money, Obama, Barrack, Mitt, Romney, finance, support, Republican, Democrat, API

    Brak komentarzy:

    Prześlij komentarz