Project: Flume-Hive
/**
 * Licensed to Cloudera, Inc. under one 
 * or more contributor license agreements.  See the NOTICE file 
 * distributed with this work for additional information 
 * regarding copyright ownership.  Cloudera, Inc. licenses this file 
 * to you under the Apache License, Version 2.0 (the 
 * "License"); you may not use this file except in compliance 
 * with the License.  You may obtain a copy of the License at 
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */
package com.cloudera.flume.reporter.charts.google; 
 
import java.util.SortedSet; 
 
import com.cloudera.flume.reporter.histogram.HistogramChartGen; 
import com.cloudera.util.Histogram; 
import com.cloudera.util.Pair; 
 
/**
 * Google charts has quite a few string encoding things to compact the size of 
 * the url used to generate the chart. 
 *  
 * Type T is the class used to bin values into histograms. 
 */
 
class GoogleHistogramChartGen<T> extends HistogramChartGen<T> { 
  final public static String BASE_URL = "http://chart.apis.google.com/chart?"
 
  int height, width; 
  String title; 
  boolean scaled = true
 
  public GoogleHistogramChartGen(String title, int height, int width, 
      boolean scaled) { 
    this.title = title; 
    this.height = height; 
    this.width = width; 
    this.scaled = scaled; 
  } 
 
  public GoogleHistogramChartGen(String title, int height, int width) { 
    this(title, height, width, true); 
  } 
 
  public GoogleHistogramChartGen(String title) { 
    this(title, 300300); 
  } 
 
  public GoogleHistogramChartGen() { 
    this(null300300); 
  } 
 
  private String size() { 
    return "chs=" + width + "x" + height; 
  } 
 
  // Text encoding 
  // This is limited to values 0-100 inclusive. If a value is > 100, it is 
  // marked as 100. 
  // API says good for about 500 pixel graphs. 
  private String histoSortFreqs(Histogram<T> h) { 
    if (h.size() == 0
      return ""// No data 
 
    SortedSet<Pair<T, Integer>> s = h.sorted(); 
    StringBuilder data = null
    for (Pair<T, Integer> p : s) { 
      if (data == null) { 
        data = new StringBuilder(); 
        data.append(p.getRight()); 
      } else { 
        data.append("," + p.getRight()); 
      } 
    } 
    return data.toString(); 
  } 
 
  // Text encoding with data scaling 
  private String histoSortFreqsS(Histogram<T> h) { 
    if (h.size() == 0
      return ""// No data 
 
    SortedSet<Pair<T, Integer>> s = h.sorted(); 
    String data = null
    int max = 0
    int sum = 0
    int cnt = 0
    for (Pair<T, Integer> p : s) { 
      max = p.getRight() > max ? p.getRight() : max; 
      cnt++; 
      sum += p.getRight(); 
      if (data == null) { 
        data = "" + p.getRight(); 
      } else { 
        data += "," + p.getRight(); 
      } 
    } 
 
    // truncate y axis at avg 
    int avg = sum / cnt; 
    String limits = "&chds=0," + avg; 
    // add axis 
    String axis = "&chxt=y,x&chxl=0:|0|" + avg + "|1:|0|" + cnt; // last doesn't 
    // have a '|' 
 
    String charttype = "&cht=bvg"
    if (cnt > 10) { 
      charttype = "&cht=lc"
    } 
 
    return charttype + "&chd=t:" + data + limits + axis; 
  } 
 
  @Override 
  public String generate(Histogram<T> h) { 
    String title = ""
    if (this.title != null) { 
      // TODO (check string, need to escape spaces with '+'). 
      title = "&chtt=" + this.title; 
    } 
 
    String data = scaled ? histoSortFreqsS(h) : histoSortFreqs(h); 
 
    return "<img src=\"" + BASE_URL + size() + title + data + "\" />"
  } 
 
}