Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using it's URL and the proper URL extention.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <div id="PresidentialSpeeches" class="wrapper ng-cloak">
        <div class="copy-container">
<h1>The Rhetoric of Donald Trump</h1>
        <div class="copy-main">
            <p>Throughout this election cycle, Trump has become infamous for many things (his hair, his strange relationship with his daughter, his odd undying love for Putin), but above all for his taglines - "make American great again", "build a wall and make Mexico pay for it", "I love women", and so forth. Curious as to just how radical his rhetoric has been, I did a bit of analysis on both word frequency and average grade level, comparing a collection of his speeches with past presidential speeches. The difference was stark. Trump's speeches are on average <em>less than half</em> the average grade level (that is, the number of years of education needed to understand a text) than average presidential speech.</p>
            <p>Even more telling, however, were the most frequently used words. I removed a standard list of <a href="http://www.ranks.nl/stopwords">stop words</a> (that is, the most common words in the English language) from the results to improve the data. Normally, words such as "I", "we", and "you" are included in this list. However, Trump's usage of "I" represented such a high percentage in comparison to even the second most used word ("you") that I felt it statistically significant and worth retaining. By comparison, in past presidential speeches "our" is the most common word.</p>
        </div>
            <h2>Word Frequency and Grade Level of Donald Trump's Speeches</h2>
            <div class="copy-secondary">
                <p>With an average grade level of <em>5.2</em>, Trump's speeches focus mostly on - well, himself. "I" wins the race by a landslide, and "Don" (his own name) follows soon after ("Trump" makes an appearance as well). <a href="https://github.com/ryanmcdermott/trump-speeches">Data Source</a></p>
            </div>
            </div>
        <div class="graph-wrapper trump ng-cloak">
        <data-bar-graph data-graph-name="'trump'" data-spread-offset="12"></data-bar-graph>
            <div class="graph-grade-container">
                <p class="graph-grade-level">5.2</p>
                <p class="graph-grade-subtitle">Grade Level</p>
            </div>
            </div>
        <div class="copy-container">
         <h2>Word Frequency and Grade Level of Presidential Speeches (1789 - 2016)</h2>
            <div class="copy-secondary">
                <p>Past presidential speeches focus heavily on an overarching motif of unity and nationalism - words like "people", "united", "one", and so forth appear again and again. <a href="http://www.datasets.co/dataset/US-Presidential-Speeches">Data Source</a></p>
            </div>
        </div>
        <div class="graph-wrapper presidents ng-cloak">
<data-bar-graph data-graph-name="'presidents'" data-spread-offset="12"></data-bar-graph>
            <div class="graph-grade-container">
                <p class="graph-grade-level">10.8</p>
                <p class="graph-grade-subtitle">Grade Level</p>
            </div>
        </div>
</div>
    
    <script type="text/javascript">
    window.bootstrap = window.bootstrap || {};
    window.bootstrap.graphData = 
                       {
                           "trump": [
    {
      "title": "i",
      "value": 5678
    },
    {
      "title": "you",
      "value": 3526 
    },
    {
      "title": "we",
      "value": 2876 
    },
    {
      "title": "going",
      "value": 2271 
    },
    {
      "title": "people",
      "value": 1493  
    },
    {
      "title": "don",
      "value": 1114  
    },
    {
      "title": "me",
      "value": 866   
    },
    {
      "title": "like",
      "value": 761  
    },
    {
      "title": "think",
      "value": 752  
    },
    {
      "title": "great",
      "value": 726   
    },
    {
      "title": "get",
      "value": 716   
    },
    {
      "title": "no",
      "value": 619    
    },
    {
      "title": "right",
      "value": 608   
    },
    {
      "title": "say",
      "value": 583   
    },
    {
      "title": "country",
      "value": 548   
    },
    {
      "title": "money",
      "value": 436   
    },
    {
      "title": "look",
      "value": 434   
    },
    {
      "title": "good",
      "value": 404   
    },
    {
      "title": "make",
      "value": 374   
    },
    {
      "title": "love",
      "value": 338   
    },
    {
      "title": "never",
      "value": 319   
    },
    {
      "title": "time",
      "value": 316   
    },
    {
      "title": "win",
      "value": 314   
    },
    {
      "title": "take",
      "value": 310   
    },
    {
      "title": "trump",
      "value": 306    
    },
    {
      "title": "big",
      "value": 304    
    },
    {
      "title": "things",
      "value": 272    
    },
    {
      "title": "believe",
      "value": 271    
    },
    {
      "title": "again",
      "value": 258    
    },
    {
      "title": "okay",
      "value": 256    
    },
    {
      "title": "world",
      "value": 253    
    },
    {
      "title": "everybody",
      "value": 242    
    },
    {
      "title": "deal",
      "value": 242    
    }
  ],
        "presidents": [
    {
      "title": "our",
      "value": 154164 
    },
    {
      "title": "we",
      "value": 149014  
    },
    {
      "title": "i",
      "value": 144220  
    },
    {
      "title": "states",
      "value": 63619  
    },
    {
      "title": "government",
      "value": 60738  
    },
    {
      "title": "people",
      "value": 52196   
    },
    {
      "title": "united",
      "value": 52039   
    },
    {
      "title": "you",
      "value": 50782    
    },
    {
      "title": "congress",
      "value": 36762   
    },
    {
      "title": "one",
      "value": 35066   
    },
    {
      "title": "country",
      "value": 32438    
    },
    {
      "title": "president",
      "value": 30256    
    },
    {
      "title": "time",
      "value": 29820     
    },
    {
      "title": "war",
      "value": 29296    
    },
    {
      "title": "great",
      "value": 28848    
    },
    {
      "title": "world",
      "value": 28762    
    },
    {
      "title": "american",
      "value": 27868    
    },
    {
      "title": "new",
      "value": 26094    
    },
    {
      "title": "year",
      "value": 26048    
    },
    {
      "title": "every",
      "value": 25506    
    },
    {
      "title": "public",
      "value": 23640    
    },
    {
      "title": "peace",
      "value": 23198    
    },
    {
      "title": "state",
      "value": 21503    
    },
    {
      "title": "power",
      "value": 20110    
    },
    {
      "title": "make",
      "value": 18810    
    },
    {
      "title": "nation",
      "value": 18236     
    },
    {
      "title": "law",
      "value": 17858     
    },
    {
      "title": "first",
      "value": 17790     
    },
    {
      "title": "against",
      "value": 17086     
    },
    {
      "title": "without",
      "value": 16728     
    },
    {
      "title": "men",
      "value": 16488     
    },
    {
      "title": "general",
      "value": 16360     
    },
    {
      "title": "think",
      "value": 16071     
    }
  ]
                       }
    
</script>
              
            
!

CSS

              
                html {
    box-sizing: border-box;
}

*,
*:before,
*:after {
    box-sizing: inherit;
}

@mixin media($breakpoint) {
    @media (max-width: $breakpoint) {
        @content;
    }
}

// ------------- VARIABLES ------------- //
$serif-font: "Playfair Display";
$sans-serif-font: "Montserrat";
// ------------- GENERAL ------------- //
.ng-cloak {
    opacity: 0;
}

body {
    font-family: $serif-font;
    color: #5b5b5b;
    ::selection {
        background-color: rgba(46, 49, 52, .7);
        color: #f5f5f1;
    }
    ::-moz-selection {
        background-color: rgba(46, 49, 52, .7);
        color: #f5f5f1;
    }
}

em {
    font-style: italic;
}

a {
    color: #2c2c2c;
    text-decoration: underline;
    transition: .2s;
    &:hover {
        color: rgba(#2c2c2c, .6);
    }
}

h1 {
    font-size: 4rem;
    line-height: 1.15;
    font-weight: 900;
    letter-spacing: -.05rem;
    color: #2c2c2c;
    text-align: center;
    margin-bottom: 1em;
    @include media(720px) {
        font-size: 3rem;
    }
    @include media(400px) {
        font-size: 2.4rem;
    }
}

h2 {
    color: #2c2c2c;
    font-size: 1.9rem;
    line-height: 1.3;
    margin-bottom: 1.1em;
    &:before {
        content: "";
        height: 6px;
        width: 120px;
        background-color: #ebebeb;
        display: block;
        margin: 2.5em auto;
        @include media(420px) {
            margin: 1.8em auto;
        }
    }
    @include media(720px) {
        font-size: 1.7rem;
    }
}

.wrapper {
    margin-top: 4.5em;
    @include media(420px) {
        margin-top: 2.5em;
    }
}

.copy {
    &-container {
        margin: 0 auto;
        max-width: 680px;
        @include media(720px) {
            padding-left: 1.5em;
            padding-right: 1.5em;
        }
    }
    &-main {
        font-size: 1.2rem;
        line-height: 1.5;
        P + P {
                margin-top: 2em;
            }
        @include media(720px) {
            font-size: 1.1rem; 
        }
    }
    &-secondary {
        font-family: $sans-serif-font;
        color: #979797;
        font-size: .85rem;
        line-height: 1.6;
    }
}

// ------------- GENERAL ------------- //
.graph {
    &-wrapper {
        max-width: 1000px;
        margin: 4em auto;
        position: relative;
    }
    &-container {
        display: flex;
    }
    &-values {
        text-align: right;
        display: flex;
        flex-direction: column;
        justify-content: space-around;
        min-width: 120px;
        padding-right: 10px;
        @include media(590px) {
            min-width: 100px;
            padding-right: 5px;
        }
        @include media(450px) {
            min-width: 80px;
        }
        @include media(380px) {
            min-width: 60px;
        }
        &-item {
            font-family: $sans-serif-font;
            font-size: .8rem;
            color: #979797;
            text-transform: uppercase;
            letter-spacing: .05rem;
            transition: .2s;
            &.active {
                color: #000;
            }
            @include media(590px) {
                font-size: .65rem;
            }
            @include media(450px) {
                font-size: .55rem;
            }
            @include media(380px) {
                font-size: .4rem;
            }
        }
    }
    &-svg {
        flex-grow: 1;
        > svg {
            stroke: #fff;
            rect {
                transition: .2s;
                @include media(600px) {
                    stroke-width: 1;
                }
            }
            .trump & {
                rect:nth-child(even) {
                    fill: rgba(#ae0001, .2);
                }
                rect:nth-child(odd) {
                    fill: rgba(#ae0001, .4);
                }
                rect:hover {
                    fill: rgba(#ae0001, .8);
                }
            }
            .presidents & {
                rect:nth-child(even) {
                    fill: rgba(#0062cd, .2);
                }
                rect:nth-child(odd) {
                    fill: rgba(#0062cd, .4);
                }
                rect:hover {
                    fill: rgba(#0062cd, .8);
                }
            }
        }
    }
    &-grade {
        &-container {
            position: absolute;
            bottom: 0;
            right: 20px;
            text-align: center;
            border: 5px solid #ebebeb;
            border-radius: 10px;
            box-shadow: 5px 5px 0 #fbfbfb;
            width: 196px;
            height: 196px;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            @include media(775px) {
                font-size: 3.3rem;
                width: 120px;
                height: 120px;
            }
            @include media(500px) {
                position: static;
                margin: .5em auto;
            }
        }
        &-level {
            font-weight: 900;
            font-size: 5rem;
            line-height: 1;
            margin-bottom: .15em;
            letter-spacing: -.1rem;
            @include media(775px) {
                font-size: 3rem;
            }
            @include media(400px) {
                font-size: 2.6rem;
            }
        }
        &-subtitle {
            font-family: "Montserrat";
            font-size: .8rem;
            color: #979797;
            text-transform: uppercase;
            letter-spacing: .05rem;
        }
    }
}
              
            
!

JS

              
                class DataStore {

    constructor() {
        this._graphData = window.bootstrap.graphData;
    }

    get graphData() {
        return this._graphData;
    }

    /**
    ** getSortedGraphValues :: object -> array
    ** Returns array of numerical graph values from graph data
    */ 
    get getSortedGraphValues() {
        return _.flow([
            this._getGraphValues, 
            this._filterNaNs,
            _.sortBy
        ]);
    }

    /**
    ** getRangeValues :: array -> array
    ** Returns array of rounded range values from graph values
    */ 
    get getRangeValues() {
        return _.flow([
            this._returnRange,
            this._roundValues
        ]);
    }

    /**
    ** getRangeSpread :: array -> number
    ** Returns value of spread of array of range values
    */ 
    get getRangeSpread() {
        return _.flow([
            this.getRangeValues, 
            this._determineSpread
        ]);
    }

    /**
    ** getInitialValue :: array -> number
    ** Returns first value of array of range values
    */ 
    get getInitialValue() {
        return _.flow([
            this.getRangeValues, 
            _.first
        ]);
    }

    /**
    ** getLengthOfLongestString :: array -> number
    ** Returns length of longest string from an array
    */ 
    get getLengthOfLongestString() {
        return _.flow([
            this._filterNotStrings,
            this._getStringLengths,
            _.uniq,
            this._getGreatest
        ]);
    }

    /**
    ** getGraphValues :: object -> array
    ** Returns array of values from graph data
    */ 
    _getGraphValues(graphData, value) {
        return _.map(graphData, value);
    }

    /**
    ** getGraphTitles :: object -> array
    ** Returns array of titles from graph data
    */ 
    getGraphTitles(graphData) {
        return _.map(graphData, "title");
    }

    /**
    ** filterNaNs :: array -> array
    ** Returns array of safe number values 
    */ 
    _filterNaNs(values) {
        return values.filter(value => !Number.isNaN(value));
    }

    /**
    ** filterNotStrings :: array -> array
    ** Returns array of safe strings from array
    */ 
    _filterNotStrings(strings) {
        return strings.filter(string => _.isString(string));
    }

    /**
    ** returnRange :: array -> array
    ** Returns array of appropriately stepped range values from sorted values based on spread offset
    */ 
    _returnRange(sortedValues, spread) {
        const spreadOffset = this._determineSpread(sortedValues) / spread;
        const firstRangeValue = (_.first(sortedValues) - spreadOffset);
        const lastRangeValue = (_.last(sortedValues) + spreadOffset * 2);
        return _.range(
                firstRangeValue > 0 ? firstRangeValue : 0, 
                lastRangeValue, 
                spreadOffset
            );
    }

    /**
     ** roundValues :: array -> array
     ** Returns array of values rounded to the nearest tenth
     */ 
    _roundValues(rangeValues) {
        return rangeValues.map(val => Math.round(10 * val) / 10);
    }

    /**
    ** determineSpread :: array -> number
    ** Returns spread of sorted graph values
    */ 
    _determineSpread(sortedValues) {
        return (_.last(sortedValues) - _.first(sortedValues));
    }

    /**
    ** getStringLengths :: array -> array
    ** Returns array of lengths of each string from an array of strings
    */ 
    _getStringLengths(strings) {
        return strings.map(string => string.length);
    }

    /**
    ** getGreatest :: array -> number
    ** Returns greatest value in an array of numbers
    */ 
    _getGreatest(values) {
        return values.reduce((prev, curr) => (curr - prev) > 0 ? curr : prev);
    }

}

barGraph.$inject = ['$timeout', '$sce'];

function barGraph($timeout, $sce) {

    return {
        restrict: 'E',
        scope: {
            graphName: '=',
            spreadOffset: '='
        },
        replace: true,
        controller: 'BarGraphController',
        controllerAs: 'barGraphController',
        bindToController: true,
        templateUrl: $sce.trustAsResourceUrl('https://codepen.io/eehayman/pen/xEPRoy.html'),
        link: link
    };

    function link(scope, element, attrs, ctrl) {

}

}

class BarGraphController {

    static get $inject() {
        return ['dataStore'];
    }
    
    constructor(dataStore) {
        this._dataStore = dataStore;
        this._activeValue = -1;
    }
    
    get currentReportData() {
        return this._dataStore.graphData[this.graphName];
    }

    get rangeSpread() {
        return this._dataStore.getRangeSpread(this.sortedGraphValues, this.spreadOffset);
    }
    
    get isMobile() {
        return window.innerWidth < 600 ? true : false;
    }

    get barWidth() {
        return this.isMobile ? (this.rangeSpread / this.currentReportData.length) * 2 : this.rangeSpread / this.currentReportData.length;
    }

    get sortedGraphValues() {
        return this._dataStore.getSortedGraphValues(this.currentReportData, "value");
    }

    get yAxisRange() {
        return this._dataStore.getRangeValues(this.sortedGraphValues, this.spreadOffset);
    }

    get viewBoxWidth() {
        return this.currentReportData.length * this.barWidth;
    }

    get viewBoxHeight() {
        return this.rangeSpread;
    }

    get graphInitialValue() {
        return this._dataStore.getInitialValue(this.sortedGraphValues, this.spreadOffset);
    }

    get viewBox() {
        if (this.currentReportData) {
            return this.isMobile ? "0 0 " + this.viewBoxWidth / 2 + " " + this.viewBoxHeight * 2 : "0 0 " + this.viewBoxWidth + " " + this.viewBoxHeight;
        }
    }

    get xAxisRange() {
        if (this.currentReportData) {
            return this._dataStore.getGraphTitles(this.currentReportData);
        }
    }

    get activeValue() {
        return this._activeValue;
    }

    get offsetPadding() {
        if (this.xAxisRange) {
            return (this._reportDataStore.getLengthOfLongestString(this.xAxisRange) * 7);
        }
    }

    updateActiveValue(value) {
        this._activeValue = value;
    }

}

angular.module('PresidentialSpeeches', [])
    .config(['$compileProvider', function ($compileProvider) {
        $compileProvider.debugInfoEnabled(false);
    }])
    .service('dataStore', DataStore)
    .controller('BarGraphController', BarGraphController)
    .directive('barGraph', barGraph);

angular.element(document).ready(function () {
    angular.bootstrap(document.getElementById("PresidentialSpeeches"), ['PresidentialSpeeches']);
})




              
            
!
999px

Console