Skip to content

Instantly share code, notes, and snippets.

@Sniksder16
Created June 29, 2016 02:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sniksder16/e4291ad2e2ac636a7caead64484ecac0 to your computer and use it in GitHub Desktop.
Save Sniksder16/e4291ad2e2ac636a7caead64484ecac0 to your computer and use it in GitHub Desktop.
*
Copyright (c) 2016, BrightPoint Consulting, Inc.
This source code is covered under the following license: http://vizuly.io/license/
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
// @version 1.0.35
//**************************************************************************************************************
//
// This is a test/example file that shows you one way you could use a vizuly object.
// We have tried to make these examples easy enough to follow, while still using some more advanced
// techniques. Vizuly does not rely on any libraries other than D3. These examples do use jQuery and
// materialize.css to simplify the examples and provide a decent UI framework.
//
//**************************************************************************************************************
var viz; // vizuly ui object
var viz_container; // html element that holds the viz (d3 selection)
var viz_title; // title element (d3 selection)
var theme; // Theme variable to be used by our viz.
// Variables that will be used to update the y scale and radius scale by the test container settings panel.
// value == 1 - linear scale
// value < 1 == log scale
var rScale = 0.5, yScale = 0.3;
// D3 formatters we will use for labels
var formatMonthYear = d3.time.format("%-m/%y");
var formatDate = d3.time.format("%b %d, 20%y");
var formatCurrency = function (d) {
return "$" + d3.format("0,000")(d)
};
// This example uses two data sources. One is static and one is live
// Each data source has different payload structures. We abstract the required properties for us to visualize into
// 'staticData' and 'liveData' objects which we store in the 'sources' object. This allows us to easily toggle between them.
var dataSource;
// RANKUP DATA
var staticData = {
rank: "Rank",
name: "Name",
value: "Value",
rufp: "RUFP",
url: "data/football_data.csv" //FILE LOCATION FOR DATA, CHANGED FROM "data/scatter_expenditure.csv"
};
/* BRANDON COMMENTED OUT!!!
Live data from sunlight.org (you can use the static one if you want - the public one uses our API key.)
var liveData = {
name: "candidate_name",
date: "expenditure_date_formatted",
dateParser: d3.time.format("%Y-%m-%d").parse,
amount: "expenditure_amount",
com_nam: "committee_name",
pty: "candidate_party_checked",
url: "http://realtime.influenceexplorer.com/api//independent-expenditures/?format=csv&page=1&page_size=10&support_oppose_checked=S&min_spent=10000&apikey=0e138d67832545b5bde92c1443637b52"
};
*/// url:"data/scatter_sunlight_static.csv"}; //commented out by BRANDON
// The sources object that stores data
var sources = {static: staticData}; //BRANDON CHANGED FROM {static: staticData, live: liveData} to current state
// Use jQuery to see when document is loaded
function loadData() {
/* BRANDON COMMENTED OUT
// Start by loading our live data
d3.csv(sources.live.url, function (err, csv) {
if (err) {
console.log("Could not load live data from sunlight.org")
}
// Get rid of any data older than 3/2015
sources.live.data = csv.filter(function (d) {
d[sources.live.date] = sources.live.dateParser(d[sources.live.date]);
return (Number(d[sources.live.date].getFullYear()) > 2014);
});
// We create keys for each candidate that we can later use to highlight
// all candidate plots for a given candidate.
sources.live.data.forEach(function (d) {
// Use regex to clean strings as needed for our keys
var can = String(d[sources.live.name]).replace(",", "_");
can = can.replace(/[\s+,'+,\.,\(,\),\"]/g, "");
can = can.toUpperCase();
d.key = can;
});
// Update our settings panel to let us know when the live data is ready
var opt = d3.selectAll("#dataSourceDiv li:last-child");
opt.attr("class", null);
opt.selectAll("span").text("Live - Sunlight.org");
d3.selectAll("#liveDataOption").html("<a>Live - Sunlight.org</a>").attr("disabled", null);
});
*/
//Here we grab our static data, meanwhile our live data is loading above;
d3.csv(sources.static.url, function (csv) {
sources.static.data = csv;
// We create keys for each candidate that we can later use to highlight
// all candidate plots for a given candidate.
sources.static.data.forEach(function (d) {
// Use regex to clean strings as needed for our keys
var can = String(d[sources.static.name]).replace(",", "_");
can = can.replace(/[\s+,'+,\.,\(,\),\"]/g, "");
can = can.toUpperCase();
//d[sources.static.date] = sources.static.dateParser(d[sources.static.date]); BRANDON COMMENTED OUT
d.key = can;
});
// Set our initial data source to this static data
dataSource = sources.static;
initialize();
});
}
// Vizuly follows an almost identical function chaining syntax as that of D3. If you know D3, vizuly will feel familiar to you,
// and if you are new to D3, programming vizuly will be a good introduction.
//
// In this routine we create our viz, set various properties, create a title and
// update the display.
//
function initialize() {
//Here we set our <code>viz</code> variable by instantiating the <code>vizuly.component.corona</code> function.
//All vizuly components require a parent DOM element at initialization so they know where to inject their display elements.
viz = vizuly.component.scatter(document.getElementById("viz_container"));
//Using the function chain syntax we can now set various properties of the bar chart.
//
//Both the <code>x</code> and <code>y</code> properties are used to map the data values
//to the corresponding x and y axis within the chart.
viz.data(dataSource.data)
.width(screenWidth).height(screenHeight) // initial component display size
.y(function (d, i) {
return Number(d[dataSource.value]); // property for y axis plot!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
})
.x(function (d, i) {
return d[dataSource.rufp]; // property for x axis plot!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
})
.r(function (d, i) {
return Number(d[dataSource.value]); // property for node radius plot!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
})
.duration(1500) // The length of time(ms) for any viz transitions to run
.on("validate", onValidate) // Callback for the validate event
.on("update", onUpdate) // Callback for update event
.on("measure", onMeasure) // Callback for measure event
.on("mouseout", onMouseOut); // Callback for mouseout event
//** Themes and skins ** play a big role in vizuly, and are designed to make it easy to make subtle or drastic changes
//to the look and feel of any component. Here we choose a theme and skin to use for our bar chart.
// *See this <a href=''>guide</a> for understanding the details of themes and skins.*
theme = vizuly.theme.scatter(viz)
.skin(vizuly.skin.SCATTER_OCEAN)
// Instead of attaching to the viz's mouseover event we are attaching to the theme's mouse over.
// This allows us to make style changes that don't clobber the ones the theme is making, but goes after them.
.on("mouseover", onMouseOver);
//The <code>viz.selection()</code> property refers to the parent
//container that was used at the object construction. With this <code>selection</code> property we can use D3
//add, remove, or manipulate elements within the component. In this case we add a title label and heading to our chart.
viz_title = viz.selection()
.select("svg")
.append("text")
.attr("class", "title")
.attr("x", viz.width() / 2)
.attr("y", 40).attr("text-anchor", "middle")
.style("fill", "#FFF")
.style("font-family", "Raleway")
.style("font-weight", 300);
// Update the yAxis ticks function to show currency.
viz.yAxis().tickFormat(function (d) {
return 1 + "pt";
});
//The <code>viz.update()</code> function tells the component to render itself to the display.
// Any property changes that have occurred since the last update (including changes to the data) will now be rendered.
viz.update();
/*
// This code is for the purposes of the demo and simply cycles through the various skins
// The user can stop this by clicking anywhere on the page.
var reel = vizuly.showreel(theme, ['Sunset', 'Neon', 'Ocean'], 2000).start();
d3.select("body").on("mousedown.reel", function () {
//Stop show reel
reel.stop();
//Remove event listener
d3.select("body").on("mousedown.reel", null);
})
*/
}
// Set appropriate axis labels after viz validates and automatically creates any public properties.
function onValidate() {
// Override automatically set linear scales to better fit this data using a pow scale.
// This is an example of how you can modify viz properties during the object life-cycle.
viz.rScale(d3.scale.pow().exponent(rScale));
viz.yScale(d3.scale.pow().exponent(yScale));
}
/*
// Just a simple function to make sure our title is centered if the <code>viz</code> measurements have changed.
function onMeasure() {
viz.yScale().domain([0, viz.yScale().domain()[1]]); //Want a zero based axis
viz_title.attr("x", viz.width() / 2);
viz.xAxis().tickFormat(formatMonthYear);
viz.yAxis().ticks(9);
viz.xAxis().ticks(14);
viz_title.style("font-size", Math.min(viz.width(), viz.height()) / 35);
}
*/
// We are going to add some meta data to our graph so we can filter out elements.
// For each plot we are going to add a dummy class based on the candidate id associated with the data for that plot.
// This will allow us to later select ALL plots related to a specific candidate on mouseover
function onUpdate() {
viz.selection().selectAll(".vz-scatter-node").each(function (d) {
d3.select(this).attr("class", function (d) {
return "vz-scatter-node " + d.key;
});
})
// Each time we update we want to see the TOTAL contributions for the data set so we can display it in the title.
// Here we loop through the data to get that total.
var total = 0;
dataSource.data.forEach(function (d) {
total += Number(d[dataSource.value]);
})
// Update the title text.
viz_title.transition().text("Total: " + formatCurrency(Math.round(total)));
}
// On mouse over we select all plots related to the candidate ID and highlight them.
function onMouseOver(e, d, i) {
viz.selection().selectAll(".vz-scatter-node." + d.key).style("fill", "#FFF").style("fill-opacity", .8).style("opacity", 1);
// We create our data tip
createDataTip(e, d);
}
// All we need to do here is remove the data tip when the user moves the mouse away and restore all elements.
function onMouseOut(e, d, i) {
restoreElements();
removeDataTip();
}
// Just re-applies the theme to clear all style changes we made.
function restoreElements() {
theme.apply();
}
// Removes the data tipe.
function removeDataTip(name) {
d3.selectAll(".vz-scatter-label").remove();
}
// Here is a template for our data tip
var datatip = '<div class="tooltip" style="width: 220px; background-opacity:.5">' +
'<div class="header1">HEADER1</div>' +
'<div class="header-rule"></div>' +
'<div class="header2"> HEADER2 </div>' +
'<div class="header-rule"></div>' +
'<div class="header3" style="font-size:12px;"> HEADER3 </div>' +
'<div class="header3"> HEADER4 </div>' +
'</div>';
// This function uses the above html template to replace values and then creates a new <div> that it appends to the
// document.body. This is just one way you could implement a data tip.
function createDataTip(e, d, total) {
/*Brandon Commented Out
var h1 = formatDate(d[dataSource.date]); BRANDON COMMENTED OUT
var h1 = d[dataSource.name];
var h3 = d[dataSource.com_nam];
var h4 = formatCurrency(d[dataSource.amount]);
*/
var h1 = dataSource.rufp;
var h2 = dataSource.name;
var h3 = dataSource.rank;
var h4 = dataSource.value;
var rect = viz.selection().selectAll(".vz-scatter-plot")[0][0].getBoundingClientRect();
var x = Number(d3.select(e).attr("cx")) + rect.left;
var y = Number(d3.select(e).attr("cy")) + rect.top;
var html = datatip.replace("HEADER1", h1);
html = html.replace("HEADER2", h2);
html = html.replace("HEADER3", h3);
html = html.replace("HEADER4", h4);
d3.select("body")
.append("div")
.attr("class", "vz-scatter-label")
.style("position", "absolute")
.style("top", (y - 155) + "px")
.style("left", (x - 110) + "px")
.style("opacity", 0)
.html(html)
.transition().style("opacity", 1);
}
//
// Functions used by the test container to set various properties of the viz
//
function changeSkin(val) {
if (!val) return;
theme.skin(val);
viz.selection().selectAll(".vz-bar").attr("height", 0).attr("y", viz.height());
viz_title.style("fill", theme.skin().labelColor);
viz.update();
}
function changeSize(val) {
var s = String(val).split(",");
viz.selection().selectAll(".vz-bar").attr("width", 0).attr("x", 0);
viz_container.transition().duration(300).style('width', s[0] + 'px').style('height', s[1] + 'px');
viz.width(s[0]).height(s[1]).update();
}
function changeRScale(val) {
rScale = 1 / Number(val);
viz.update();
}
function changeYScale(val) {
yScale = 1 / Number(val);
viz.update();
}
function changeData(val) {
dataSource = sources[val];
viz.data(dataSource.data).update();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment