Tag Clouds: Usability and Math
by Jurgen Appelo

Listing One

Public Function GetWriters(ByVal maxCount As Integer, _
        ByVal ignoreNoise As Boolean, ByVal fromDate As DateTime, _
        ByVal toDate As DateTime) As DataTable
    Dim query As String = String.Format( _
        "SELECT * FROM (SELECT TOP {0} ID, Text, " & _
        "Count FROM Writers ORDER BY Count DESC) sub " & _
        "ORDER BY Text ASC", maxCount)
    'TODO: also filter on ignoreNoise, fromDate and toDate
    Dim adapter As New SqlDataAdapter(query, _ConnectionString)
    Dim table As New DataTable
    adapter.Fill(table)
    Return table
End Function


Listing Two

Public Shared Function FromBellCurve( _
        ByVal weights As ICollection(Of Decimal), _
        ByVal minSize As Decimal, ByVal maxSize As Decimal) _
        As ICollection(Of Decimal)
    'First, calculate the mean weight.
    Dim meansum As Decimal = 0
    For Each w As Decimal In weights
        meansum += w
    Next
    Dim mean As Double = meansum / weights.Count
    'Second, calculate the standard deviation of the weights.
    Dim sdsum As Double = 0
    For Each w As Decimal In weights
        sdsum += (w - mean) ^ 2
    Next
    Dim sd As Double = ((1 / weights.Count) * sdsum) ^ 0.5
    'Now calculate the slope of a straight line from -2*sd to +2*sd.
    Dim slope As Double
    If sd > 0 Then
        slope = (maxSize - minSize) / (4 * sd)
    End If
    'Get the value in the middle between minSize and maxSize.
    Dim middle As Double = (minSize + maxSize) / 2
    'Calculate the result for the given deviation from mean.
    Dim output As New List(Of Decimal)

    For Each w As Decimal In weights
        If (sd = 0) Then
            'With sd=0 all tags have the same weight.
            output.Add(CDec(middle))
        Else
            'Calculate the distance from mean for this weight.
            Dim distance As Double = w - mean
            'Calculate the position on the slope for this distance.
            Dim result As Double = CDec(slope * distance + middle)
            'If the tag turned out too small, set minSize.
            If result < minSize Then result = minSize
            'If the tag turned out too big, set maxSize.
            If result > maxSize Then result = maxSize
            output.Add(CDec(result))
        End If
    Next
    Return output
End Function


Listing Three

Public Shared Function FromParetoCurve( _
        ByVal weights As ICollection(Of Decimal), _
        ByVal minSize As Decimal, ByVal maxSize As Decimal) _
        As ICollection(Of Decimal)
    'Convert each weight to its log value.
    Const BASE As Double = Math.E
    Dim logweights As New List(Of Decimal)
    For Each w As Decimal In weights
        logweights.Add(CDec(Math.Log(w, BASE)))
    Next
    'First, find the min and max weight.
    Dim min As Decimal = Decimal.MaxValue
    Dim max As Decimal = Decimal.MinValue
    For Each w As Decimal In logweights
        If w < min Then min = w
        If w > max Then max = w
    Next
    'Now calculate the slope of a straight line, from min to max.
    Dim slope As Double
    If max > min Then
        slope = (maxSize - minSize) / (max - min)
    End If
    'Get the value in the middle between minSize and maxSize.
    Dim middle As Double = (minSize + maxSize) / 2
    'Calculate the result for each of the weights.
    Dim output As New List(Of Decimal)
    For Each w As Decimal In logweights
        If (max <= min) Then
            'With max=min all tags have the same weight.
            output.Add(CDec(middle))
        Else
            'Calculate the distance from the minimum for this weight.
            Dim distance As Double = w - min

            'Calculate the position on the slope for this distance.
            Dim result As Double = CDec(slope * distance + minSize)
            'If the tag turned out too small, set minSize.
            If result < minSize Then result = minSize
            'If the tag turned out too big, set maxSize.
            If result > maxSize Then result = maxSize
            output.Add(CDec(result))
        End If
    Next
    Return output
End Function


Listing Four

Dim url1 As String = "<a href='{0}' style='font-size:{1}px;'>{2}</a>"
Dim url2 As String = "<a href='{0}' style='font-size:{1}em;'>{2}</a>"
Dim url3 As String = "<a href='{0}' class='class{1}'>{2}</a>"
Dim url4 As String = "<em>...<em><a href='{0}'>{2}</a></em>...</em>"


3


