ActBlue Donations

84 of 122

Use conditional styling to highlight various types of information.

Result Full HTML CSS JS
Edit Download

Who's Benefiting Most From ActBlue?

Active candidates who raised the most from individuals using ActBlue, by share of all individual contributions made via ActBlue, since January 2017.

[[index.actblueShare]]%

Source: Federal Election Comission

Read more at FiveThirtyEight

Full Code

<!DOCTYPE html>
<html class="zg-html">

<head>
  <meta charset="utf-8">
  <title>ZingGrid: ActBlue Donations</title>
  <script src="https://cdn.zinggrid.com/zinggrid.min.js" defer></script>
  <link href="https://fonts.googleapis.com/css?family=Roboto+Mono:300,400,700|Roboto:400,700" rel="stylesheet">
  <style>
    .zg-body {
      padding: 30px;
      background: #ffffff;
      font-family: 'Roboto', sans-serif;
    }

    /* Grid */

    zing-grid {
      max-width: 800px;
      margin: 0 auto;
      font-family: 'Roboto', sans-serif;
      border-left: none;
      border-right: none;
      font-size: 13px;
      color: #212121;
      opacity: 1;
    }

    zing-grid.loading {
      opacity: 0;
      transition: opacity .3s ease-out;
    }

    zing-grid.loading * {
      opacity: 0;
    }

    zing-grid a {
      color: #2772a0;
    }

    zing-grid a:hover {
      color: #212121;
    }

    zg-caption {
      background: white;
      color: #222222;
      padding: 10px 0 0 0;
    }

    zg-caption h1 {
      font-weight: bold;
      font-size: 23px;
      margin-bottom: 0;
    }

    zg-caption h2 {
      font-weight: normal;
      font-size: 15px;
      line-height: 1.5;
    }

    zg-cell {
      margin-right: 0px;
    }

    zg-control-bar {
      display: none;
    }

    zg-head {
      border-bottom: 2px solid black;
      letter-spacing: .5px;
    }

    zg-head,
    zg-head-cell {
      font-size: 10px;
      text-transform: uppercase;
      background: white;
      align-items: flex-end;
    }

    zg-head-cell[depth="1"],
    zg-head-cell[parent]:not([depth="1"]) {
      padding-bottom: 5px;
    }

    zg-icon {
      max-width: 14px;
    }

    zg-row,
    zg-cell {
      padding: 0 15px;
      height: 35px;
    }

    zg-cell:nth-child(1) {
      font-weight: bold;
    }

    zg-cell:nth-child(5),
    zg-cell:nth-child(6),
    zg-cell:nth-child(7) {
      font-family: 'Roboto Mono', monospace;
      text-align: right;
    }

    zg-cell:nth-child(7) {
      text-align: center;
    }

    zg-cell.heat-map {
      background: #5ea8e5;
    }

    zg-row:last-child {
      border: none;
    }

    zg-footer {
      font-size: 11px;
      padding-top: 25px;
      display: flex;
      justify-content: space-between;
      color: #999999;
      font-family: 'Roboto Mono', monospace;
    }

    /* Ratings */

    .zg-body .republican {
      color: #d44f4f;
    }

    .zg-body .democrat {
      color: #008fd5;
    }

    .zg-body .neither {
      color: #878787;
    }

    zing-grid[loading] {
      height: 1229px;
    }
  </style>
</head>

<body class="zg-body">

  <zing-grid src="https://zinggrid-examples.firebaseio.com/actblue-top-donations-2017-alt" layout="row" layout-controls="disabled" sort class="loading">
    <zg-caption>
      <h1>Who's Benefiting Most From ActBlue?</h1>
      <h2>Active candidates who raised the most from individuals using ActBlue, by share of all individual contributions made via ActBlue, since January 2017.</h2>
    </zg-caption>
    <zg-colgroup>
      <zg-column index="candidate"></zg-column>
      <zg-column index="chamber"></zg-column>
      <zg-column index="race" type="url">
        <template>
            <a href="[[index.race.raceLink]]" target="_blank" cross-origin>[[index.race.raceName]]</a>
          </template>
      </zg-column>
      <zg-column index="rating" renderer="renderRating"></zg-column>
      <zg-column index="individualContributions.total" type="currency">
      </zg-column>
      <zg-column index="individualContributions.actblue" type="currency">
      </zg-column>
      <zg-column index="actblueShare" type="number" header="ActBlue Share" cell-class="_renderCellHeatmap">
        [[index.actblueShare]]%
      </zg-column>
    </zg-colgroup>
    <zg-footer>
      <p>Source: Federal Election Comission</p>
      <p>Read more at <a href="https://fivethirtyeight.com/features/how-actblue-is-trying-to-turn-small-donations-into-a-blue-wave/" target="_blank">FiveThirtyEight</a></p>
    </zg-footer>
  </zing-grid>

  <script>
    // Set 'Rating' Color
    function renderRating(value) {
      let type = 'neither';
      switch (value) {
        case 'Lean R':
        case 'Likely R':
          type = 'republican';
          break;
        case 'Lean D':
        case 'Likely D':
          type = 'democrat';
          break;
      }
      return `<span class="${type}">${value}</span>`;
    }

    // Render the background based on percentage
    function _renderCellHeatmap(value, $cellRef, cellInfo) {
      // get percentage value
      let opacityValue = Number(value.split('.')[0]);
      // make value between 0-1
      opacityValue = opacityValue / 100;
      // set background color
      $cellRef.style.background = `rgba(94, 168, 229, ${opacityValue})`;
    }

    // window:load event for Javascript to run after HTML
    // because this Javascript is injected into the document head
    window.addEventListener('load', () => {
      // Javascript code to execute after DOM content

      // Register methods to grid namespace
      ZingGrid.registerMethod(renderRating);
      ZingGrid.registerMethod(_renderCellHeatmap);
    });

    // Custom loading class for CSS handling
    const zgLoaded = document.querySelector('zing-grid');
    zgLoaded.addEventListener('grid:ready', () => {
      setTimeout(() => zgLoaded.classList.remove('loading'), 0);
    });
  </script>
</body>

</html>
<!DOCTYPE html>
<html class="zg-html">
  <head>
    <meta charset="utf-8">
    <title>ZingGrid: ActBlue Donations</title>
    <script src="https://cdn.zinggrid.com/zinggrid.min.js" defer></script>
    <link href="https://fonts.googleapis.com/css?family=Roboto+Mono:300,400,700|Roboto:400,700" rel="stylesheet">
  </head>
  <body class="zg-body">
    
    <zing-grid 
      src="https://zinggrid-examples.firebaseio.com/actblue-top-donations-2017-alt" 
      layout="row"
      layout-controls="disabled"
      sort
      class="loading"
    >
			<zg-caption>
        <h1>Who's Benefiting Most From ActBlue?</h1>
        <h2>Active candidates who raised the most from individuals using ActBlue, by share of all individual contributions made via ActBlue, since January 2017.</h2>
      </zg-caption>
      <zg-colgroup>
        <zg-column index="candidate"></zg-column>
		    <zg-column index="chamber"></zg-column>
        <zg-column index="race" type="url">
          <template>
            <a href="[[index.race.raceLink]]" target="_blank" cross-origin>[[index.race.raceName]]</a>
          </template>
        </zg-column>
        <zg-column index="rating" renderer="renderRating"></zg-column>
        <zg-column index="individualContributions.total" type="currency">
        </zg-column>
        <zg-column index="individualContributions.actblue" type="currency">
        </zg-column>
        <zg-column index="actblueShare" type="number" header="ActBlue Share" cell-class="_renderCellHeatmap">
        	[[index.actblueShare]]%
        </zg-column>
      </zg-colgroup>
      <zg-footer>
        <p>Source: Federal Election Comission</p>
        <p>Read more at <a href="https://fivethirtyeight.com/features/how-actblue-is-trying-to-turn-small-donations-into-a-blue-wave/" target="_blank">FiveThirtyEight</a></p>
      </zg-footer>
    </zing-grid>
    
  </body>
</html>
.zg-body {
  padding: 30px;
	background:#ffffff;
	font-family: 'Roboto', sans-serif;
}

/* Grid */
zing-grid {
	max-width: 800px;
  margin: 0 auto;
	font-family: 'Roboto', sans-serif;
  border-left: none;
  border-right: none;
  font-size: 13px;
  color: #212121;
  opacity: 1;
}
zing-grid.loading { opacity:0; transition:opacity .3s ease-out; }
zing-grid.loading * { opacity:0; }

zing-grid a {
  color: #2772a0;
}

zing-grid a:hover {
  color: #212121;
}

zg-caption {
 	background: white;
  color: #222222;
  padding: 10px 0 0 0;
}

zg-caption h1 {
  font-weight: bold;
	font-size: 23px; 
  margin-bottom: 0;
}

zg-caption h2 {
  font-weight: normal;
	font-size: 15px;
  line-height: 1.5;
}

zg-cell {
  margin-right: 0px;
}

zg-control-bar {
  display: none;
}

zg-head {
  border-bottom: 2px solid black;
	letter-spacing: .5px;
}

zg-head, zg-head-cell {
	font-size: 10px;
  text-transform: uppercase;
  background: white;
  align-items: flex-end;
}

zg-head-cell[depth="1"],
zg-head-cell[parent]:not([depth="1"]) {
  padding-bottom: 5px;
}

zg-icon {
 	max-width: 14px; 
}

zg-row, zg-cell {
  padding: 0 15px; 
  height: 35px;
}

zg-cell:nth-child(1) {
  font-weight: bold;
}

zg-cell:nth-child(5),
zg-cell:nth-child(6),
zg-cell:nth-child(7) {
  font-family: 'Roboto Mono', monospace;
	text-align: right;
}

zg-cell:nth-child(7) {
 text-align: center; 
}

zg-cell.heat-map { 
  background: #5ea8e5; 
}

zg-row:last-child {
  border: none;
}

zg-footer {
  font-size: 11px;
  padding-top: 25px;
  display: flex;
  justify-content: space-between; 
  color: #999999;
  font-family: 'Roboto Mono', monospace;
}

/* Ratings */
.zg-body .republican { color: #d44f4f; }
.zg-body .democrat { color: #008fd5; }
.zg-body .neither { color: #878787; }
// Set 'Rating' Color
function renderRating(value) {
  let type = 'neither';
  switch (value) {
    case 'Lean R': 
    case 'Likely R':
      type = 'republican'; 
      break;
    case 'Lean D': 
    case 'Likely D':
      type = 'democrat'; 
      break;
  }
  return `<span class="${type}">${value}</span>`;
}

// Render the background based on percentage
function _renderCellHeatmap(value, $cellRef, cellInfo) {
  // get percentage value
  let opacityValue = Number(value.split('.')[0]);
  // make value between 0-1
  opacityValue = opacityValue/100;
  // set background color
  $cellRef.style.background = `rgba(94, 168, 229, ${opacityValue})`;
}

// window:load event for Javascript to run after HTML
// because this Javascript is injected into the document head
window.addEventListener('load', () => {
  // Javascript code to execute after DOM content
  
  // Register methods to grid namespace
	ZingGrid.registerMethod(renderRating);
	ZingGrid.registerMethod(_renderCellHeatmap);
});

// Custom loading class for CSS handling
const zgLoaded = document.querySelector('zing-grid');
zgLoaded.addEventListener('grid:ready', () => {
  setTimeout(() => zgLoaded.classList.remove('loading'), 0);
});

Interested in this demo? Modify it to your needs in ZingSoft Studio, our testing sandbox. It's free to sign up, and you can come back and edit at any time!

Edit in Studio

Demo Gallery