Experiment #1 – Sliding filter for user-rated content

This experiment came about because I was looking at the way Digg allows you to filter comments based on their rating.
For those that haven’t seen it, all comments can be given a thumbs up or thumbs down changing the rating for that comment by +1 or -1. Digg allows you to set the visibility of comments based on how they are rated. This is a really good idea, in our increasingly time-poor lives, anything which helps us to separate out the things worth spending time on from those that are a waste of time is a good thing.

The challenge that I spotted was how to offer this functionality with a simpler and more flexible interface. The set number of options on Digg become useless if all comments have been rated highly – beyond the scope of their set filtering options.
The answer I came up with was to based the filter on the range of ratings present in the list. Secondly to replace the set options for filtering with a sliding scale from “not filtered” to “highly filtered” – abstract by design.

The first job was to work out the mathematics of the problem.
Firstly we need to find the range of ratings present, then work out each rating as a percentage of that range and finally given an input value for the amount of filtering, work out the scale of the applied filter for each rated item.

In order to build the user interface it made sense to start with a utility library, I used to be a prototype /script.aculo.us fan but I recently started working with jQuery due to it’s more compact nature. In order to make the slider I added Interface Elements for jQuery.

I don’t consider myself a JavaScript expert so the code could probably be optimised a little better but this is just a proof of concept work to look at the way the data is displayed and manipulated by the user.

Firstly I set global variables to store the array of ratings and the smallest and largest values. I’ve extended the array object to include min and max functions.

var arrRange;
var rMin;
var rMax; 

function getRange(){
  arrRange = new Array();
  arrRange.max = function( array ){ return Math.max.apply( Math, array );};
  arrRange.min = function( array ){ return Math.min.apply( Math, array );};
  $('.rating').each(
    function(){
      arrRange.push(parseInt(this.innerHTML));
    }
  );
  rMin = arrRange.min(arrRange);
  rMax = arrRange.max(arrRange);
}

Next I needed to do the maths to calculate each rated item as a percentage of the range of values present.

$('.post').each( function(i){
  var IP = ((arrRange[i]-rMin)/(rMax - rMin))*100; //Item Percentage
}

Finally we need to use our slider input value and using the range and item percentages, apply a visual effect to those items which require filtering.

For the first example, each item is hidden if the applied effect exceeds 95% for that item. When the filter slider is at 100%, only the items rated in the top 5% are still visible.

function updatePosts(EP){
  // populate the hidden field with the slider percentage - used to re-apply the effect if the list is regenerated
  document.getElementById('filterval').value=EP;
  $('.post').each(
    function(i){
      var IP = ((arrRange[i]-rMin)/(rMax - rMin))*100; //Item Percentage
      var AP = Math.floor(100 - (EP-IP)); //Apply Percentage
      if((EP-IP) > 0){
  &nbsp; &nbsp; &nbsp; if(AP < 95){
  &nbsp; &nbsp; &nbsp;   $("#" + this.id).hide();
 &nbsp; &nbsp; &nbsp;  }else{
 &nbsp; &nbsp; &nbsp; &nbsp;  $("#" + this.id).show();
   &nbsp; &nbsp;  }
 &nbsp; &nbsp;  } else {
 &nbsp; &nbsp; &nbsp;  $("#" + this.id).show();
 &nbsp; &nbsp;  }
 &nbsp;  }
  );
}

Try it out

The second example doesn’t remove any items, the font size is reduced for the as the applied effect for each item increases i.e. the font size is set to 100 – Applied Effect. This allows the user to easily pick out the higher rated items from the list without losing visibility of the other items which, in a conversation, may still be relevant despite lower ratings.

function updatePosts(EP){
  // populate the hidden field with the slider percentage - used to re-apply the effect if the list is regenerated
  document.getElementById('filterval').value=EP;
  $('.post').each(
    function(i){
      var IP = ((arrRange[i]-rMin)/(rMax - rMin))*100; //Item Percentage
      var AP = Math.floor(100 - (EP-IP)); //Apply Percentage
      if(AP==0) AP=1;
      if((EP-IP) > 0){
        $("#" + this.id).css("font-size" , Math.floor(AP).toString() + "%");
      } else {
        $("#" + this.id).css("font-size" , "100%");
      }
    }
  );
}

Try it out

Obviously there’s plenty more that we can do with this;

  • We could alter the opacity of the items and have them blink out of existance once they become sufficiently transparent.
  • To save on processor load, the updates could be done when the slider is stopped using the onChange event.

Download the source and have a play, please let me know if you use this idea or improve on it.

1 Response

Leave a Reply