/** * 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, 300, 300); } public GoogleHistogramChartGen() { this(null, 300, 300); } 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 + "\" />"; } }