d3.csv("data.csv", function(error, data) {
//1. load data and throw error if there is one
if (error) throw error;
//2. define reset and draw functions
//default to location - declare variables, reset_data and draw charts
var search_opt = 'location'
var options_list = [];
var all_options = true;
function generate_id(){
//charcodes - 0-9 are 48-57, A-Z are 65-90
}
function draw_list(search_opt,options_list,all_options){
//dynamically draws the list_radio checkboxes
debugger;
//1. Set the list title and sort the options_list
document.getElementById('list_title').innerHTML = search_opt.toUpperCase() + " (click to filter)";
options_list.sort()
//2. get distinct values of search_opt from data
//dynamically create radio button with none selected
radio_string = ""
for (i = 0; i < options_list.length; i++) {
radio_string += "
";
}
document.getElementById('list_radio').innerHTML = radio_string;
//set the on_change event to redraw charts whenever a checkbox option is selected
d3.selectAll('input[name="options"]')
.on('change', function() {
//return a list of 'selected' checkboxes or none if there are none
all_options = options_selected()
//redraw charts according to selections
new_draw_map(data,options_list,search_opt,all_options)
})
}
function reset_data(){
//creates a set of distinct 'option' values dependent on search_opt
//used to populate list_radio
var options_set = d3.set();
var my_val = ""
data.forEach(function(d) {
//if a long string, only shows the first 20 characters
my_val = check_length(d[search_opt],20)
options_set.add(my_val);
});
options_list = options_set.values()
}
function check_length(my_val,len_no){
//ensures a string is only as long as len_no and adds .. after to
//indicate string has been cropped
if (my_val.length > len_no){
my_val = my_val.slice(0,len_no) + ".."
} else{
my_val = my_val
}
return my_val;
}
function options_selected(){
//looks at dynamically drawn options and adds any 'checked' values to the list
var checked = document.querySelectorAll('input[name="options"]:checked');
checked = Array.prototype.slice.call(checked);
my_list = []
if (checked.length === 0) {
// there are no checked checkboxes
} else {
// there are some checked checkboxes
checked.forEach(function(d){
my_list.push(d.id)
})
}
return my_list;
}
function draw_charts(){
//draws the charts (functions in effective_plots.js)
draw_list(search_opt,options_list)
new_draw_map(data,options_list,search_opt)
}
//set on_change event for search option
d3.selectAll('input[name="search_option"]')
.on('change', function() {
//reset the global var search_opt
search_opt = document.querySelector('input[name="search_option"]:checked').value
//reset data and draw charts
reset_data()
draw_charts()
})
reset_data()
draw_charts()
function apply_filters(data,search_opt,filter_by){
//used by both bars, line and donut
//filters the data by values in filter_by if a filtering list exists
if (filter_by === undefined){
filter_by = []
}
if (filter_by.length > 0) {
my_data = data.filter(function(d){
d[search_opt] = check_length(d[search_opt],20)
return filter_by.indexOf(d[search_opt]) > -1;;
});
} else{
my_data = data;
}
return my_data;
}
function new_draw_map(data,options_list,search_opt,filter_by) {
//1. Set the list title
//document.getElementById('map_title').innerHTML = "Map for selected " + search_opt.toUpperCase();
//2. Apply filters
my_data = apply_filters(data,search_opt,filter_by);
var bound = new google.maps.LatLngBounds();
for (m in my_data){
long = +my_data[m].longitude
lat = +my_data[m].latitude
if(isNaN(my_data[m].longitude)==true){
my_data.splice(m,1)
} else{
bound.extend(new google.maps.LatLng(lat, long));
}
}
var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
d3.selectAll('#map')
.attr("width",width-200);
// Create the Google Map…
var map = new google.maps.Map(d3.select("#map").node(), {
zoom: 1,
center: new google.maps.LatLng(-25.363, 131.044),
mapTypeId: google.maps.MapTypeId.TERRAIN
});
map.fitBounds(bound);
var overlay = new google.maps.OverlayView();
// Add the container when the overlay is added to the map.
overlay.onAdd = function() {
var layer = d3.select(this.getPanes().overlayMouseTarget).append("div")
.attr("class", "effective");
// Draw each marker as a separate SVG element.
// We could use a single SVG, but what size would it have?
overlay.draw = function() {
var projection = this.getProjection(),
padding = 10;
var tooltip = d3.select("body")
.append("div")
.attr("class", "tooltip_map")
.html("");
var marker = layer.selectAll("svg")
.data(my_data)
.each(transform) // update existing markers
.enter().append("svg")
.each(transform)
.attr("class", "marker");
;
// Add a circle.
marker.append("circle")
.attr("r", 12)
.attr("cx", padding+5)
.attr("cy", padding+5)
.on("mouseover", function(d){
//sets tooltip. t_text = content in html
debugger;
t_text = "Dashboard: " + d.dashboard +" City: " + d.city
tooltip.html(t_text)
return tooltip.style("visibility", "visible");
})
.on("mousemove", function(){return tooltip.style("top", (event.pageY-10)+"px").style("left",(event.pageX+10)+"px");})
.on("mouseout", function(){return tooltip.style("visibility", "hidden");});
function transform(d) {
d = new google.maps.LatLng(+d.latitude, +d.longitude);
d = projection.fromLatLngToDivPixel(d);
return d3.select(this)
.style("left", (d.x - padding) + "px")
.style("top", (d.y - padding) + "px");
}
};
};
// Bind our overlay to the map…
overlay.setMap(map);
};
});