Monday, August 11, 2014

Google Charts: How to change axis, legend styles beyond what is provided by the API

If you are familiar with Google Charts, you know that you need to pass a 'Configuration Options' object when drawing a chart. Properties of that object for bar charts are found here.

For a recent project I worked, I needed to show the axis and legend labels as 'clickable' links hence I needed to show the cursor as a 'hand/pointer' when hovered above them. But Google Charts API only provides a limited set of styling for axis and legend labels. More precisely it only supports color, fontName, fontSize, bold, italic & underline styles.

But after inspecting the generated HTML DOM for the charts, I figured out a simple way to manipulate the elements properties and change the styling the way you want.

I prefer jQuery so here goes how the vertical axis labels were manipulated:
 $('text[text-anchor=end]').each(
  function (index, value) {
   $(value).attr('cursor', 'pointer');
   ...
  });

Here's how the horizontal axis labels were manipulated:
 
 $('text[text-anchor=middle]').each(
  function (index, value) {
   $(value).attr('cursor', 'pointer');
   ...
  });

Here's how the legend labels were manipulated:
 
 $('text[text-anchor=start]').each(
  function (index, value) {
   $(value).attr('cursor', 'pointer');
   ...
  });

If you are a plain JavaScript guy, here you go:
 
 var labels = document.querySelectorAll('text[text-anchor=end]');
 for (var i = 0; i < labels.length; i++) {
  labels[i].setAttribute('cursor', 'pointer');
  ...
 }

Make sure you understand that the above hacks basically set the styling to every matching element found on the page. So if you have multiple charts on the same page and you need styling done individually, you will have to check additional properties of those elements inside the loops to determine which chart they belong to.

If you need further clarification on this, post it as a comment :)

Sunday, August 10, 2014

Android: Implementing a One-Way Lockable View Pager

While implementing a fun Android app, I came across a scenario where the ViewPager should only be swiped right-to-left. Visiting back should be restricted. Also at some points, I needed to lock the whole view pager so that it cannot be swiped at any direction.

The following code shows how I did it by extending the ViewPager class. Note that I was using the support library.


 
 import android.content.Context;
 import android.support.v4.view.ViewPager;
 import android.util.AttributeSet;
 import android.view.MotionEvent;

 public class OneWayLockableViewPager extends ViewPager {  
   private boolean enabled;  
   private float lastX;  

   public OneWayLockableViewPager(Context context, AttributeSet attrs) {  
     super(context, attrs);  
     this.enabled = true;  
   }  

   @Override  
   public boolean onTouchEvent(MotionEvent event) {  
     if (this.enabled) {  
       boolean lockScroll;  
       switch (event.getAction()) {  
         case MotionEvent.ACTION_MOVE:  
           lockScroll = lastX <= event.getX();  
           break;  
         default:  
           lockScroll = false;  
           lastX = event.getX();  
           break;  
       } 
       return lockScroll ? false : super.onTouchEvent(event);    
     }  
     return false;  
   }  

   @Override  
   public boolean onInterceptTouchEvent(MotionEvent event) {  
     if (this.enabled) {  
       return super.onInterceptTouchEvent(event);  
     }  
     return false;  
   }  

   public void lock() {  
     this.enabled = false;  
   }  

   public void unlock() {  
     this.enabled = true;  
   }  
 }  

It is quite easy to change it if you want to reverse the allowed direction of swiping. Just change the less than or equal sign to a greater than sign in line number 21.

Also when you want to lock down the whole view pager, just call the lock() method and swiping will be disabled.