New in this version:
o Cleaned up the code a bit. It's still a bit of a mess, though...
o Added scaling to graphs
o Only outputs the graph div, so it can be called by something else making the rest of the webpage.
Note: the code to html converter zaps the indenting. You may want to pass it through a pretty printer.
o Cleaned up the code a bit. It's still a bit of a mess, though...
o Added scaling to graphs
o Only outputs the graph div, so it can be called by something else making the rest of the webpage.
Note: the code to html converter zaps the indenting. You may want to pass it through a pretty printer.
#!/bin/sh
#
# * Copyright (c) 2008
# * Adam Keck. All rights reserved.
# *
# * Redistribution and use in source and binary forms, with or without
# * modification, are permitted provided that the following conditions
# * are met:
# * 1. Redistributions of source code must retain the above copyright
# * notice, this list of conditions and the following disclaimer.
# * 2. Redistributions in binary form must reproduce the above copyright
# * notice, this list of conditions and the following disclaimer in the
# * documentation and/or other materials provided with the distribution.
# * 3. The name Adam Keck may not be used to endorse or promote products derived from this software
# * without specific prior written permission.
# *
# * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# * SUCH DAMAGE.
INPUTFILE="undef"
SCALE="scale=1"
#Function to print Usage
usage () {
echo "$0
{-h|-help}
{
-f |--file=2-column-ACSII-csv-file
-h |--height=height-in-pixels
-w |--width=width-in-pixels
-c |--colors=comma-separated-list-of-css-colors
-bg|--background-color=css-backgroundcolor
-t |--title=title
}
"
}
# Make sure file exists and is ASCII
validatefile () {
if [ -z $1 ]
then
usage
return 1
fi
if [ -f $1 ]
then
if [ "`file $1| awk '{print $2}'`" = "ASCII" ]
then
return 0
else
echo "File is not ASCII text." 2>&1
return 1
fi
else
echo "File does not exist." 2>&1
return 1
fi
}
# Get maximum of column two.
get_max_column_value () {
FILE="${1}"
awk -F, '{gsub("[^0-9]", "", $2);if($2>a)a=$2}END{print a}' "${FILE}"
}
get_normalized_height () {
height="${1}"
local_minimum_column_value="${2}"
local_maximum_column_value="${3}"
if [ -z "${3}" ]; then
echo "${0}: needs three arguments: column_2_value minium_column_2_value max_column_2_value" 1>&2
fi
echo "${SCALE}; (${height} - ${minimum_column_value})/(${maximum_column_value} - ${minimum_column_value})" | bc -l
}
get_column_height () {
sigma="$1"
maximum_graph_height="$2"
echo "${sigma} * ${maximum_graph_height}" | bc
}
# Look up the color from the list of CSS colors supplied on the command line
lookupcolor () {
COLORNUMBER="${1}"
echo "${COLORNUMBER},${2}" | awk -F, '{print $($1+1)}'
}
# Process arguments
# If no arguments have been specified on the command line then print the usage
if [ "$#" = "0" ]
then
usage
exit 1
fi
# Loop through the arguments setting variables used the script.
while [ $# -gt 0 ] ; do
case "$1" in
-f|--file=*)
if [ "$1" = "-f" ] ; then
shift
if validatefile $1
then
INPUTFILE=$1
else
exit 1
fi
else
FILEHOLDER="`echo $1 | sed s,--file=,,`"
if validatefile $1
then
INPUTFILE="${FILEHOLDER}"
else
exit 1
fi
fi
;;
-c|--colors=*)
if [ "$1" = "-c" ] ; then
shift
COLORS=$1
else
COLORS="`echo $1 | sed s#--colors=##`"
fi
;;
-bg|--background-color=*)
if [ "$1" = "-bg" ] ; then
shift
BGCOLOR=$1
else
BGCOLOR="`echo $1 | sed s,--background-color=,,`"
fi
;;
-h|--height=*)
if [ "${1}" = "-h" ] ; then
shift
MAXIMUM_GRAPH_HEIGHT="${1}"
else
MAXIMUM_GRAPH_HEIGHT="`echo $1 | sed s,--height=,,`"
fi
;;
-w|--width=*)
if [ "${1}" = "-w" ] ; then
shift
COLUMN_WIDTH="${1}"
else
COLUMN_WIDTH=="`echo $1 | sed s,--width=,,`"
fi
;;
-t|--title=*)
if [ "$1" = "-t" ] ; then
shift
TITLE=$1
else
TITLE="`echo $1 | sed s,--title=,,`"
fi
;;
-h|-help)
usage
exit 0
;;
*)
usage
exit 1
;;
esac
shift
done
# Set some reasonable default colors in case they were not
# specified on the command line.
if [ -z $COLORS ]
then
COLORS=black
fi
if [ -z $BGCOLOR ]
then
BGCOLOR=lightgrey
fi
#Get graph width
WIDTH="`cat ${INPUTFILE} | wc -l `"
# CSS Style functions
emit_h2_style () {
echo -n "line-height: 1.5em; font-family: sans-serif; font-weight: normal;"
}
emit_graph_div_style () {
echo -n "width: `echo "${SCALE};${WIDTH}*(${COLUMN_WIDTH}+10)" | bc`px; height: `echo "${SCALE};${MAXIMUM_GRAPH_HEIGHT}" + 20 | bc`px; position: relative; background: $BGCOLOR;"
}
emit_graph_div_ul_style () {
echo -n "width: `echo "${SCALE};${WIDTH}*(${COLUMN_WIDTH}+10)" | bc`px; height: `echo "${SCALE};${MAXIMUM_GRAPH_HEIGHT}" + 20 | bc`px; margin: 0; padding: 0;"
}
emit_graph_div_li_style () {
echo -n "position: absolute; width: ${COLUMN_WIDTH}px; bottom: 20px; padding: 0 !important; margin: 0 !important; text-align: center; font-weight: normal; font-size: 9px; color: white; line-height: 2.5em; list-style-type: none; font-family: sans-serif;"
}
# Functions to print html
emit_title () {
echo -n "<h2 style=\"`emit_h2_style`\" >"${TITLE}"</h2>"
}
emit_open_graph_div () {
echo -n "<div style=\"`emit_graph_div_style`\">"
}
emit_open_graph_ul () {
echo -n "<ul style=\"`emit_graph_div_ul_style`\">"
}
emit_close_graph_ul () {
echo -n "</ul>"
}
emit_close_graph_div () {
echo -n "</div>"
}
emit_graph_li_set () {
# Initialize the line counter and the position of the first color in
# color list.
LINENUMBER="0"
COLORNUMBER="1"
# Get maximum column two value
maximum_column_value="`get_max_column_value ${INPUTFILE}`"
# Set minimum column two value to one
minimum_column_value="1"
# Loop through file creating list elements
cat "${INPUTFILE}" | while read LINE
do
# Remove non-numeric characters from the column two value of each line.
# If no characters remain, set the raw height to .1 so that in the
# creation of the list element for the column, the column will get 1 pixel
# for height
HEIGHTRAW="`echo ${LINE} | awk -F, '{gsub("[^0-9]", "", $2);print $2}'`"
if [ -z "${HEIGHTRAW}" ]
then
HEIGHTRAW="1"
fi
NORMALIZED_HEIGHT="`get_normalized_height ${HEIGHTRAW} ${minimum_column_value} ${maximum_column_value}`"
HEIGHT="`get_column_height ${NORMALIZED_HEIGHT} ${MAXIMUM_GRAPH_HEIGHT}`"
# Check the color number, i.e. the position in the color list
# from the command line. If it's more than the number of colors
# in the list, reset it to one.
if [ "${COLORNUMBER}" -gt "`echo ${COLORS} | awk -F, '{print NF}'`" ]
then
COLORNUMBER="1"
fi
# Get the color from the list of colors corresponding to the position in
# the list specified by the value of color number.
COLOR="`lookupcolor ${COLORNUMBER} ${COLORS}`"
# Write the list element corresponding to the line we are processing in the
# input file. The height of the column will be the second column times 10
# pixels. Each column is placed to right of the last one by 55 pixels.
# The header for the column is the value of the first column.
# The column one value is stripped of all non-alpha numberic characters.
echo -e "<li style=\" `emit_graph_div_li_style` height: "${HEIGHT}"px ; left: `echo "${SCALE}; ${LINENUMBER}*(${COLUMN_WIDTH}+10)" | bc`px; background-color: $COLOR;\" >`echo $LINE|awk -F, '{print $1}'`</li>\n\n"
# Increment the counters
LINENUMBER="`expr ${LINENUMBER} + 1`"
COLORNUMBER="`expr ${COLORNUMBER} + 1`"
done
}
# Write the graph
echo "
`emit_title`
`emit_open_graph_div`
`emit_open_graph_ul`
`emit_graph_li_set`
`emit_close_graph_ul`
`emit_close_graph_div`
"
Comments
Post a Comment