Winnability in non-reserved seats

In our last post, we have seen the extent to which parties give tickets to SC/ST candidates in non-reserved constituencies. In this post, we will compare the performance of SC/ST candidates with their general counterparts.

Here, we define relative winnability as the ratio of win% of group and total win%. That is, how much more often does a group win compared to the average.

Winnability in non-reserved seats

At the national level, relative winnability of ST candidates is more than SC candidate. Yet, ST candidates are given less seats in non-reserved seats.

Part-wise relative winnability of general, SC, ST candidate at non-reserved seats are:

Winnability by Party

Overall, most parties have higher general candidate winnability in non-reserved constituencies. BSP and LJP incurred heavy losses at places where it fielded SC/ST candidates. There seems to be a direct correlation between losses incurred by a party which gave higher share of seats to SC candidates. For example, BSP and LJP were highly inclined to give general seats to SC candidate and lost most of these seats.

In these analysis, we came across some interesting cases like:

  • SP lost all the general seats where it fielded a SC candidate and won only one general seat where it fielded ST candidate.
  • CPM, CPI, JD(U) lost all the general seats where it fielded a ST candidate.
  • Though LJP fields many SC/ST candidates in general seats, it didn’t win any of these seats.

There are quite few mainstream parties which give non-reserved seats to SC/ST candidates. It’s another story how the general public have voted in reserved seats. We shall take that it in another series.

Politics of non-reserved territories

In India, a large number of Parliament seats are reserved for SC / Dalits (84 seats – 15.5%) and ST / Tribes (47 seats – 8.7%).

In addition, SC/ST leaders are also elected from non-reserved constituencies. Though, many political parties claim to espouse the cause of SC/ST, in reality only few mainstream parties give tickets to SC/ST candidates in non-reserved constituencies.

Ratio of SC ST candidates

On analysing non-reserved (general) assembly seats from 2004-2013, we noticed regional heavy-weights SAD, DMK, PMK, TRS, and INLD have not given a single non-reserved seat to any SC/ST candidates.

A closer look at the two ratios tables reveals that:

  • BSP and LJP gave more seats to SC candidates and fewer seats to ST candidates when compared with national average.
  • The two major national parties, INC and BJP, are way below national average.
  • SDF, AGP and JKPDP, which topped in ST candidates list, didn’t give a seat to SC candidates in non-reserved seats.

SC candidates have higher participation than ST candidates in general seats. However, bucking the general trend, INC gives fewer tickets to SC candidates in non-reserved constituencies. Though, SC candidates’ participation is higher, ST candidates’ winnability is much higher.

Winnability of SC ST candidates

Note: We only considered parties that won at least 20 seats in total.

In our next post, we will see how candidates have fared at these places and compare the performance of SC/ST candidates.

Optimising the 2014 election results page

Once we had the design and back-end technology running, it was time to build the live election results page itself.

Counting day screenshot

Sever-side or client-side?

The key considerations here were speed and load. We wanted users to get the results as quickly as possible without overloading our servers.

Generating pages on the server lets us cache the results across users. This is how most pages at were built when analysing historical election. But while this reduces the load on the client-side, it increases the page size quite a bit. The alternative is to just send the data across and have the browser render it using Javascript.

These visuals are in SVG – so that already excludes IE8 and older browsers. For the rest of the browsers, as long as we kept the calculations simple, there would be no issue in terms of browser capability.

What libraries?

The easiest way for you to explore this is to look at its source. To begin with, here’s a snapshot of the URLs loaded by the page. (This is a snapshot taken on a mobile broadband connection to simulate the relatively slower modem-like speeds.)

URLs loaded and speed

After the main /live page is loaded, we load 6 CSS / Javascript files in parallel.

  1. Bootstrap 3 CSS
  2. Bootstrap 3 JS
  3. jQuery 2
  4. Underscore.js
  5. Our custom stylesheets: style.css
  6. Our internal Javascript utility belt: G.min.js

We did explore the possibility of keeping the page lighter and going without these libraries. But three things suggested otherwise. First, their size was only 54KB gzipped. In contrast, the rest of the page + data was 285KB. Second, there still are too many browser issues for us to get to a good browser speed. Lastly, most users on this page would be repeat visitors – so these libraries would be cached the first time and do not add to the burden.

We chose Bootstrap many months ago for the election analysis page and continued the choice here. Bootstrap requires jQuery.

Underscore.js, however, was chosen for a single reason: it’s templates. Ever since John Resig created a micro-templates, we’ve been a fan of this approach. For example, to create this table of candidates in each constituency (and yes, there really where 11 Chandu Lal Sahus contesting)…

Table of constituency results

… and to have it updated every time the results change, this is the code required:

Table micro-template

The key to the structuring of this visual was to load all static data upfront, and minimally refresh with the dynamic data.

Structuring the data

The only thing that changes during the elections is the number of votes for a candidate. So, theoretically, if we sent 8,000 numbers as updates every time, the browser can calculate the rest.

In practice, however, the votes are not available until much later. Only the winner / leading candidate is known. So we went for the a single JSON file that captures the minimal data required for display.

Summary JSON

(Why JSON instead of CSV? Because it supports hierarchies, browsers parse it natively, and when gzipped, it’s not much larger than CSV.)

This file grew from ~20KB (when all votes were 0) to ~65KB (after results were declared). When compressed, this is just 27KB, which makes the updates extremely light.

Summary JSON network

Filtering the data

Since all data is available at the client side, all filtering also happens on the client side. To ensure that the filtered URL is shareable, we use history.pushState to change it, but do the computations in-browser without accessing the server.

The URL structure of the filter closely matches that of the data columns. For example, filters those constituencies where BJP is leading in 2014. These filters can be selected multiply – so you can see the results of BJP + SS here – as well as independently – so you can see where BJP won in Rural India. This makes it intuitive to the developers to add new filters as well.

It’s all in the browser

As a result of client-side rendering and filtering, the only time the user accesses the server is to fetch new data. We provided a refresh button on the top-right, but for the anchors presenting on PPI device in the CNN-IBN office, we needed an auto-refresh facility that would refresh at least once every 10 seconds.


So we built a secret ?refresh= parameter and applied it on this device. We did not apply auto-refresh in the morning since we were worried about the kind of traffic load that the site could handle.

But once the traffic started decreasing at around 9:30am…


… it became obvious that a refresh of every 5 minutes wouldn’t hurt things, and would definitely improve the experience. We set it up to auto-refresh every 5 minutes by default.

You can always explore further by exploring the source at view-source: