Last active
December 25, 2015 15:39
-
-
Save pauljm/7000013 to your computer and use it in GitHub Desktop.
Histogram Scala/Twirl/HTML
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@* Helper to draw <font> tags *@ | |
@font(size: Option[Int] = Some(12), bold: Option[Boolean] = Some(false), color: Option[String] = None) = {<!-- | |
--><font face='@Html(ctx.fontFace)'@{ if (color.isDefined) s" color='${color.get}'" else "" } style='@if(size.isDefined) { font-size: @{size.get}px; } @if(bold.isDefined) { font-weight: @{ if (bold.get) "bold" else "normal"}; }'><!-- | |
-->} | |
@* Draw a spacer cell with text inside so Outlook doesn't ignore it *@ | |
@spacerCell(width: Option[Any] = None, height: Option[Int] = None, rowspan: Int = 1, colspan: Int = 1, bgcolor: Option[String] = None) = { | |
<td rowspan=@rowspan colspan=@colspan@{ if (width.isDefined) s" width='${width.get}'" else "" }@{ if (height.isDefined) s" height='${height.get}'" else "" }@{ if (bgcolor.isDefined) s" bgcolor='${bgcolor.get}'" else "" } style='@{ if (height.isDefined) s"font-size: ${height.get}px; line-height: ${height.get}px;" else "font-size: 0; line-height: 0;" }'> </td> | |
} | |
@* Add commas to numbers 1,000 or greater *@ | |
@formattedInt(i: Int) = @{ i.toString.reverse.grouped(3).mkString(",").reverse } | |
@* Draw a histogram *@ | |
@histogram(labels: Seq[String], upValues: Seq[Int], downValues: Seq[Int], | |
heightIncrement: Int, numIncrements: Int, spacing: Int, labelHeight: Int, | |
upTotalLabel: String, downTotalLabel: String) = { | |
<table cellpadding=0 cellspacing=0 width="100%" style='text-align: center;'> | |
@* Top row provides pading and sets column widths *@ | |
<tr> | |
@spacerCell(width = Some(spacing), height = Some(spacing), bgcolor = Some("#E4F1F5")) | |
@for(i <- (0 until labels.length)) { | |
@spacerCell(width = Some(28), bgcolor = Some("#E4F1F5")) @* Columns divide available space *@ | |
@spacerCell(width = Some(spacing), bgcolor = Some("#E4F1F5")) @* Padding between columns *@ | |
} | |
@* Write total and label for upward histogram. (Downward histogram total is written with first row of down histogram.) *@ | |
@histogramTotalCells(numIncrements, spacing, "#6DB2C8", "#E4F1F5", upValues, upTotalLabel) | |
</tr> | |
@* Draw upward histogram, with bars spanning multiple rows *@ | |
@for(i <- (0 until numIncrements)) { | |
@histogramRow(i, true, upValues, heightIncrement, numIncrements, spacing, "#6DB2C8", "#E4F1F5", upTotalLabel) | |
} | |
@* Draw bucket labels *@ | |
<tr> | |
@spacerCell(Some(spacing), Some(labelHeight)) | |
@for(label <- labels) { | |
<td align='center' valign='middle'>@font(size = Some(11))@label</font></td> | |
@spacerCell() | |
} | |
@spacerCell(colspan = 4) @* Cell between total and label *@ | |
</tr> | |
@* Draw downward histogram, with bars spanning multiple rows. Write total at right. *@ | |
@for(i <- (0 until numIncrements)) { | |
@histogramRow(i, false, downValues, heightIncrement, numIncrements, spacing, "#E68265", "#F9E9E3", downTotalLabel) | |
} | |
@* Bottom padding *@ | |
<tr> | |
@spacerCell(width = None, height = Some(spacing), colspan = 2 * labels.length + 1, bgcolor = Some("#F9E9E3")) | |
</tr> | |
</table> | |
} | |
@* Draw a row of the histogram table *@ | |
@histogramRow(row: Int, up: Boolean, values: Seq[Int], | |
heightIncrement: Int, numIncrements: Int, spacing: Int, color: String, | |
bgcolor: String, totalLabel: String) = { | |
<tr> | |
@* Left-hand padding *@ | |
@spacerCell(width = Some(spacing), height = Some(heightIncrement), bgcolor = Some(bgcolor)) | |
@* Draw bars *@ | |
@for(i <- (0 until values.size)) { | |
@* Each column has two cells, one for the bar and one for the space above/below the bar *@ | |
@defining(((values(i).toDouble / values.max.toDouble) * numIncrements).ceil.toInt) { bucketIncrements => | |
@defining(bucketIncrements * heightIncrement >= 15) { roomForLabel => | |
@if(bucketIncrements > 0 && | |
(up && row == numIncrements - bucketIncrements || ! up && row == 0)) { | |
<td bgcolor='@{color}' rowspan=@bucketIncrements valign='@{ if (up) "top" else "bottom" }'>@if(roomForLabel){ @font(size = Some(9), color = Some("#FFFFFF"))@{values(i)}</font> }</td> | |
} | |
@if(bucketIncrements < numIncrements && | |
(up && row == 0 || ! up && row == bucketIncrements)) { | |
<td bgcolor='@{bgcolor}' rowspan=@{numIncrements - bucketIncrements} valign='@{ if (up) "bottom" else "top" }'>@if(! roomForLabel){ @font(size = Some(9))@{values(i)}</font> }</td> | |
} | |
} | |
} | |
@* Padding between bars *@ | |
@if(row == 0) { | |
@spacerCell(rowspan = numIncrements, bgcolor = Some(bgcolor)) | |
} | |
} | |
@* For downward histogram, write total at right. (Upward histogram total is written in top padding row of table.) *@ | |
@if(row == 0 && ! up) { | |
@histogramTotalCells(numIncrements, spacing, color, bgcolor, values, totalLabel) | |
} | |
</tr> | |
} | |
@* Draw the total counts to the right of a set of histogram bars *@ | |
@histogramTotalCells(numIncrements: Int, spacing: Int, color: String, | |
bgcolor: String, values: Seq[Int], totalLabel: String) = { | |
<td width=97 rowspan=@{numIncrements + 1} align='right' valign='middle' bgcolor='@{bgcolor}'> | |
@font(size = Some(32), bold = Some(true), color = Some(color))@formattedInt(values.sum)</font> | |
</td> | |
@spacerCell(width = Some(spacing), rowspan = numIncrements + 1, bgcolor = Some(bgcolor)) | |
<td width=97 rowspan=@{numIncrements + 1} align='left' valign='middle' bgcolor='@{bgcolor}'> | |
@font(size = Some(16), color = Some(color))@{totalLabel}</font> | |
</td> | |
@spacerCell(width = Some(spacing), rowspan = numIncrements + 1, bgcolor = Some(bgcolor)) | |
} | |
@* Draw a histogram based on data in stats.volumeOneWeek *@ | |
@histogram( | |
stats.volumeOneWeek.buckets.slice(0, 7).map { startDate => | |
Seq("", "M", "Tu", "W", "Th", "F", "Sa", "Su")(startDate.getDayOfWeek) | |
}, | |
stats.volumeOneWeek.out, | |
stats.volumeOneWeek.in, | |
3, // Height increment of histogram bars | |
20, // Number of increments in full bar | |
12, // Padding around histogram and spacing between bars | |
20, // Height of bucket label row | |
"sent", | |
"received" | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment