Android Open Source - VisEQ Preference Visualizer






From Project

Back to project page VisEQ.

License

The source code is released under:

Copyright (c) 2012, Spotify AB All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:...

If you think the Android project VisEQ listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.lsu.vizeq;
// w ww. j  a  va 2 s  .c  om
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;

import android.graphics.Color;
import android.util.Log;

//pure data with no view components.
//takes care of all the logic for creating/packing circles
//includes ways to visualize according to artist, album, track, and genre

//keeps track of Circles instead of PreferenceCircles - the difference being that the latter is a view and the former is not

public class PreferenceVisualizer {
  
  private ArrayList<Track> requests;
  private final int MAX_CIRCLES = 20;
  private double MAX_RADIUS;
  private int res_x, res_y;
  //private double ar_x, ar_y;    //aspect ratio: <float>:1
  private String sortType;
  private List<PVCircle> circles;
  int totalWeight;
  
  
  public PreferenceVisualizer(ArrayList<Track> requests, int res_x, int res_y)
  {
    this.requests = requests;
    this.res_x = res_x;
    this.res_y = res_y-200;
    this.MAX_RADIUS = (res_x > res_y) ? res_y : res_x;
    circles = new ArrayList<PVCircle>();
  }
  
  
  private void sortByWeight()
  {
    //sort all circles by their weight
    for(int i=1; i<circles.size(); i++)
    {
      PVCircle temp = circles.get(i);
      int thisWeight = circles.get(i).getWeight();
      int j;
      for(j=i-1; j>=0; j--)
      {
        int compWeight = circles.get(j).getWeight();
        if(thisWeight < compWeight)
          break;
        else
          circles.set(j+1, circles.get(j));
      }
      circles.set(j+1, temp);
    }
    
  }
  
  private void initCircles_()
  {
    circles.clear();
    for(int i=0; i<requests.size(); i++)
    {
      //Log.d("initCircles", "processing request " + i);
      //later
      String artistName = requests.get(i).mArtist;
      String trackName = requests.get(i).mTrack;
      String albumName = requests.get(i).mAlbum;
      String uri = requests.get(i).mUri;
      String requester = requests.get(i).mRequester;
      
      Track track = requests.get(i);
      
      boolean exists = false;
      //add track to appropriate circle
      for(int j=0; j<circles.size(); j++)
      {
        if(sortType.equals("artist") && circles.get(j).getName().equals(artistName))
        {
          exists = true;
          circles.get(j).getTrackList().add(track);
        }
        else if(sortType.equals("album") && circles.get(j).getName().equals(albumName))
        {
          exists = true;
          circles.get(j).getTrackList().add(track);
        }
        else if(sortType.equals("track") && circles.get(j).getName().equals(trackName))
        {
          exists = true;
          circles.get(j).getTrackList().add(track);
        }
      }
      
      //if circle didn't exist, then make a new one
      if(!exists)
      {
        PVCircle circle = new PVCircle();
        if(sortType.equals("artist"))
        {
          circle.setName(artistName);
          circle.getTrackList().add(track);
        }
        else if(sortType.equals("album"))
        {
          circle.setName(albumName);
          circle.getTrackList().add(track);
        }
        else if(sortType.equals("track"))
        {
          circle.setName(trackName);
          circle.getTrackList().add(track);
        }
        circles.add(circle);
      }
    }
    
    //after all tracks allocated, get weights and set colors!
    totalWeight = 0;
    Random rng = new Random();
    for(int i=0; i<circles.size(); i++)
    {
      //get individual weight
      //count num unique requesters
      Set<String> uniqueRequesters = new HashSet<String>();
      for(int j=0; j<circles.get(i).getTrackList().size(); j++)
      {
        uniqueRequesters.add(circles.get(i).getTrackList().get(j).mRequester);
      }
      //weight = unique requesters * unique tracks
      int weight = uniqueRequesters.size() * circles.get(i).getTrackList().size();
      totalWeight += weight;
      circles.get(i).setWeight(weight);
      circles.get(i).setScale(res_y);
      //randomly set color
      switch(rng.nextInt(5))
      {
      case 0: circles.get(i).setColor(Color.rgb(203, 32, 38)); break;
      case 1: circles.get(i).setColor(Color.rgb(100, 153, 64)); break;
      case 2: circles.get(i).setColor(Color.rgb(0, 153, 204)); break;
      case 3: circles.get(i).setColor(Color.rgb(155, 105, 172)); break;
      case 4: circles.get(i).setColor(Color.rgb(245, 146, 30)); break;
      }
    }
    
    //set our radii
    for(int i=0; i<circles.size(); i++)
    {
      double percentage = (double) circles.get(i).getWeight() / (double) totalWeight;
      int areaAvailable = (int) ((0.3) * (res_x * res_y));
      double radius = (int) Math.sqrt((areaAvailable * percentage)/Math.PI);
      circles.get(i).setRadius(radius);
    }
    
    //sort our circles by weight
    sortByWeight();
  }
  
  private boolean checkCollision(PVCircle circle, int maxIndx, int indx)
  {
    boolean collision = false;
    if((circle.getX() - circle.getRadius()) < 0 || (circle.getX() + circle.getRadius()) > res_x)
      collision = true;
    else if((circle.getY() - circle.getRadius()) < 0 || (circle.getY() + circle.getRadius()) > res_y)
      collision = true;
    else
    {
      //check against each circle
      for(int i=0; i<maxIndx; i++)
      {
        PVCircle nextCircle = circles.get(i);
        if(i == indx) continue;
        double distance = getDistance(circle, nextCircle);
        if(distance < (nextCircle.getRadius() + circle.getRadius()))
        {
          collision = true;
          break;
        }
      }
    }
    return collision;
  }
  
  private double getDistance(PVCircle c1, PVCircle c2)
  {
    double distance = Math.sqrt(Math.pow(c1.getX() - c2.getX(), 2.0) + Math.pow(c1.getY() - c2.getY(), 2.0));
    return distance;
  }
  
  
  
  private void positionCircles_()
  {
    //use iterator to be able to remove
    Iterator<PVCircle> it = circles.iterator();
    int indx = 0;
    Random rng = new Random();
    while (it.hasNext())
    {  
      PVCircle currCircle = it.next();
      //currCircle.setRadius(MAX_RADIUS * (double) currCircle.getWeight() / totalWeight);
      boolean collision = true;
      int loopCount = 0;
      while(collision && loopCount < 100)
      {
        currCircle.setPosition(res_x * rng.nextDouble(), res_y * rng.nextDouble());
        collision = checkCollision(currCircle, indx, indx);
        loopCount++;
      }
      if(loopCount == 100)
      {
        //Log.d("position", "Circle too big to fit");
        it.remove();
      }
      else indx++;
    }
  }
  
  public void sortByArtist()
  {
    sortType = "artist";
    initCircles_();
    positionCircles_();
  }
  
  public void sortByTrack()
  {
    sortType = "track";
    initCircles_();
    positionCircles_();
  }
  
  public void sortByAlbum()
  {
    sortType = "album";
    initCircles_();
    positionCircles_();
  }
  
  public void sortByGenre()
  {
    sortType = "genre";
    initCircles_();
    positionCircles_();
  }
  
  public List<PVCircle> getCircles()
  {
    return circles;
  }
  
}




Java Source Code List

com.lsu.vizeq.AboutActivity.java
com.lsu.vizeq.Artist.java
com.lsu.vizeq.BackableActivity.java
com.lsu.vizeq.HostActivity.java
com.lsu.vizeq.HostMenuActivity.java
com.lsu.vizeq.HostProfileActivity.java
com.lsu.vizeq.HostSoundVisualizationActivity.java
com.lsu.vizeq.Installation.java
com.lsu.vizeq.LibSpotifyWrapper.java
com.lsu.vizeq.LoginActivity.java
com.lsu.vizeq.MyApplication.java
com.lsu.vizeq.MyCanvas.java
com.lsu.vizeq.PVCircle.java
com.lsu.vizeq.PacketParser.java
com.lsu.vizeq.PlayerActivity.java
com.lsu.vizeq.PreferenceCircle.java
com.lsu.vizeq.PreferenceVisualizationActivity.java
com.lsu.vizeq.PreferenceVisualizer.java
com.lsu.vizeq.ProfileActivity.java
com.lsu.vizeq.RemoteControlReceiver.java
com.lsu.vizeq.RequestDetailsActivity.java
com.lsu.vizeq.RoleActivity.java
com.lsu.vizeq.SearchActivity.java
com.lsu.vizeq.SearchPartyActivity.java
com.lsu.vizeq.ServiceBinder.java
com.lsu.vizeq.SettingsActivity.java
com.lsu.vizeq.SoundVisualizationActivity.java
com.lsu.vizeq.SpotifyService.java
com.lsu.vizeq.TrackRow.java
com.lsu.vizeq.Track.java
com.lsu.vizeq.VisualizerView.java
com.lsu.vizeq.VizEQ.java
com.lsu.vizeq.WebService.java
com.lsu.vizeq.util.SystemPropertiesProxy.java
com.lsu.vizeq.util.SystemUiHiderBase.java
com.lsu.vizeq.util.SystemUiHiderHoneycomb.java
com.lsu.vizeq.util.SystemUiHider.java
com.lsu.vizeq.util.TunnelPlayerWorkaround.java