From b1262d77a3dfd57701b45a0f215314b5b3ebdd5a Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Thu, 12 Jun 2014 17:07:34 +0200 Subject: Add visualizer for hashtags vs users brands prefs ./run-psql csv "WITH q AS ($(cat queries/userbrand.sql)) SELECT brand, lhashtag as hashtag, sum, total, percentage FROM q" > drugs.csv --- addicted-brands.html | 77 ++++++++++++++++++++++++++++++ js/addicted-brands.js | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100644 addicted-brands.html create mode 100644 js/addicted-brands.js diff --git a/addicted-brands.html b/addicted-brands.html new file mode 100644 index 0000000..d8f9d9c --- /dev/null +++ b/addicted-brands.html @@ -0,0 +1,77 @@ + + + + +Addicted Brands + + + + + +
+
+ + + + + diff --git a/js/addicted-brands.js b/js/addicted-brands.js new file mode 100644 index 0000000..69f2412 --- /dev/null +++ b/js/addicted-brands.js @@ -0,0 +1,130 @@ +/* jshint devel:true, browser:true */ +/* global d3 */ +'use strict'; + +// scaling factor to enlarge bars to fit the canvas. +var FACTOR = 9; + +function main() { + d3.csv('drugs.csv') + .row(function (d) { + return { + hashtag: d.hashtag, + brand: d.brand, + sum: +d.sum, + total: +d.total, + percentage: FACTOR * d.sum / d.total + //percentage: d.percentage / 100 + }; + }) + .get(function (errors, rows) { + if (errors) { + console.log('Failed to load CSV:', errors); + return; + } + processData(rows); + }); +} + +function processData(rows) { + // map from hashtags to a map from brands to percentages + // { hashtag: String, brands: [ { brand: String, percent: int }... ] } + var data = {}; + // values of the data map + var dataArr = []; + var brands = ['samsung', 'apple', 'htc', 'sony', 'lg', 'huawei']; + var colors = ["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c"]; + + rows.forEach(function (d) { + if (!(d.hashtag in data)) { + data[d.hashtag] = { + hashtag: d.hashtag, + brands: [] + }; + dataArr.push(data[d.hashtag]); + } + data[d.hashtag].brands.push({ + brand: d.brand, + percentage: d.percentage, + // extra details + sum: d.sum + }); + + // Find all available brands, add brand as key with dummy value + if (brands.indexOf(d.brand) < 0) { + console.log('AAAAAH! Unknown brand, adding:', d.brand); + brands.push(d.brand); + } + }); + console.log(data); + + d3.select('#legenda') + .selectAll('span') + .data(brands) + .enter() + .append('span') + .style('background', function (d, i) { + return colors[i]; + }) + .text(function (brand) { + return brand; + }); + + var graph = d3.select('#charts').selectAll('.graph') + .data(dataArr, keyFnHashtag) + .enter() + .append('div') + .attr('class', 'graph'); + + graph.append('span') + .attr('class', 'hashtag') + .text(function (d) { + return d.hashtag; + }); + + // bars! + var bar = graph.selectAll('.bar') + .data(function (d) { + return d.brands; + }) + .enter() + // bar itself + .append('div') + .attr('class', 'bar') + .text(function (d) { + return d.percent; + }) + .style('background', function (d) { + return colors[brands.indexOf(d.brand)]; + }) + .style('left', function (d) { + return (10 + 50 * brands.indexOf(d.brand)) + 'px'; + }) + .style('height', function (d) { + return (150 * d.percentage) + 'px'; + }); + // text with percentage + bar.append('span') + .attr('class', 'perc') + .text(function (d) { + return (100 * d.percentage / FACTOR).toFixed(2); + }); + // number of users mentioning this tag with this brand preference + bar.append('span') + .attr('class', 'details') + .text(function (d) { + return d.sum; + }); + // brand name + bar.append('span') + .attr('class', 'brand') + .text(function (d) { + return d.brand; + }); +} + +function keyFnHashtag(d) { + return d.hashtag; +} + +main(); -- cgit v1.2.1