D3 - Updating Choropleth csv to change mapping of colours - json

Hi I'm new to D3 and am having trouble updating my map through buttons that trigger a function to load a new csv. I looked at similar posts which mentioned that I would only need to update the section which fills the map with colours, and have tried to adapt this but clicking on my button doesn't affect the map.
Here is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3: Setting path fills dynamically to generate a choropleth</title>
<h1>Relation between Managers and Tertiary Education </h1>
<div id="option1">
<input type="button"value="Education"onclick="viewEducation()" />
</div>
<div id="option2">
<input type="button"value="Managers"onclick="viewManagers()" />
</div>
<script type="text/javascript" src="d3.js"></script>
<style type="text/css">
/* No style rules here yet */
</style>
</head>
<body>
<script type="text/javascript">
//Width and height
var w = 1000;
var h = 600;
var path = d3.geoPath()
.projection(d3.geoMercator()
.center([151,-33.5])
.scale(17000)
.translate([w/2,h/2]));
//Define quantize scale to sort data values into buckets of color
var color = d3.scaleQuantize()
.range(["rgb(237,248,233)","rgb(200,235,198)", "rgb(186,228,179)","rgb(146,208,140)", "rgb(116,196,118)", "rgb(88,178,100)", "rgb(49,163,84)", "rgb(20,130,60)", "rgb(0,109,44)"])
.domain([6274, 39796]);
//Colors derived from ColorBrewer, by Cynthia Brewer, and included in
//https://github.com/d3/d3-scale-chromatic
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
//Load in agriculture data
d3.csv("ManagerPercentage.csv", function(d) { d.value = parseFloat(d.value); parseFloat(d.value1); return d; }, function(data) {
//Set input domain for color scale
color.domain([
d3.min(data, function(d) { return d.value; }),
d3.max(data, function(d) { return d.value; })
]);
//Load in GeoJSON data
d3.json("australia_adm2.json", function(json) {
//Merge the ag. data and GeoJSON
//Loop through once for each ag. data value
for (var i = 0; i < data.length; i++) {
//Grab state name
var dataState = data[i].state;
//Grab data value, and convert from string to float
var dataValue = parseFloat(data[i].value);
//Find the corresponding state inside the GeoJSON
for (var j = 0; j < json.features.length; j++) {
var jsonState = json.features[j].properties.sa4_name11;
if (dataState == jsonState) {
//Copy the data value into the JSON
json.features[j].properties.value = dataValue;
//Stop looking through the JSON
break;
}
}
}
//Bind data and create one path per GeoJSON feature
svg.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d", path)
.style("fill", function(d) {
//Get data value
var value = d.properties.value;
if (value) {
//If value exists…
return color(value);
} else {
//If value is undefined…
return "#ccc";
}
});
});
});
function viewEducation () {
d3.select("option1")
d3.csv("EducationPercentage.csv", function(data) {
svg.selectAll("path")
.style("fill", function(d) {
var value = d.properties.value;
if (value) {
return color(value);
} else {
return "#ccc";
}
});
});
}
function viewManagers () {
d3.select("option2")
d3.csv("ManagerPercentage.csv", function(data) {
svg.selectAll("path")
.style("fill", function(d) {
var value = d.properties.value;
if (value) {
return color(value);
} else {
return "#ccc";
}
});
});
});
}
</script>
</body>
</html>

Related

d3 line and points on map from csv data

I am trying to plot individual data points and also a line path that runs between these points like this example D3 stop and restart transition along path to allow click through to geo data coordinates that I have been helped with before.
Now I want to use my actual data rather than a test set of coordinates but am running into trouble. I have tried both a geoJson file and also csv for my data. I am using a csv file with lon and lat for the points and was hoping to make the line from that same set of data, ie use one set of data for the points and line.
I can’t get my line to show up in the correct place - it is in top right corner but should be on / through points. I think this is something to do with projection but I am having trouble parsing the data correctly to get a line string as required. I have tried to use the sample here https://bl.ocks.org/alandunning/cfb7dcd7951826b9eacd54f0647f48d3 - but get empty objects??
My question is how to use the csv lon lat with a d3 svg line generator.
This is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Working version 3</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-array.v1.min.js"></script>
<script src="https://d3js.org/d3-geo.v1.min.js"></script>
<script src="https://d3js.org/d3-queue.v3.min.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<style type="text/css">
circle {
fill: steelblue;
stroke: pink;
stroke-width: 3px;
}
.line{
fill: none;
stroke: red;
stroke-width: 6;
}
</style>
</head>
<body>
<script>
var w = 960,
h = 500;
var projection = d3.geoMercator()
.translate([w/2, h/2])
.scale([w * 0.16]);
var path = d3.geoPath()
.projection(projection);
var duration = 10000;
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h);
/*
var line = d3.line()
.x(function (d) {return projection([d.lon]);})
.y(function (d) {return projection([d.lat]);})
.curve(d3.curveBasis);
var line = d3.line()
.x(function(d){return projection(d[0].lon);})
.y(function(d){return projection(d[0].lat);})
.curve(d3.curveBasis);
/*ok line shows up but in wrong place
var line = d3.line()
.x(function(d) { return (d.lon); })
.y(function(d) { return (d.lat); })
.curve(d3.curveBasis);
*/
var line = d3.line()
.x(function(d) { return (d.lon); })
.y(function(d) { return (d.lat); })
.curve(d3.curveBasis);
//original
/*
var line = d3.line()
.x(function(d){return projection(d)[0];})
.y(function(d){return projection(d)[1];})
.curve(d3.curveBasis);
*/
//
//bring in data
d3.queue()
.defer(d3.json, "data/oceans.json")
.defer(d3.csv, "data/speckCities.csv")
.await(ready);
function ready (error, oceans, data){
if (error) throw error;
//console.log(data[0]);
//console.log(data[0].lon);
//map
svg.selectAll("path")
.data(oceans.features)
.enter()
.append("path")
.attr("d", path)
.style("fill", "#A8B2C3");
var linepath = svg.append("path")
.datum(data)
.attr("d", line)
.attr('class', 'line');
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([d.lon, d.lat])[0];
})
.attr("cy", function(d) {
return projection([d.lon, d.lat])[1];
})
.attr("r", 5)
.style("fill", "yellow")
.style("stroke", "gray")
.style("stroke-width", 0.25)
.style("opacity", 0.75)
.append("title") //Simple tooltip
.text(function(d) {
return d.name ;
});
//
//
/*svg.selectAll(".point")
.data(coordinates)
.enter()
.append("circle")
.attr("r", 7)
.attr("transform", function(d) { return "translate(" + projection(d) + ")"; });
var circle = svg.append("circle")
.attr("r", 19)
.attr("transform", "translate(" + projection(d) + ")");
/*
var pauseValues = {
lastT: 0,
currentT: 0
};
function transition() {
circle.transition()
.duration(duration - (duration * pauseValues.lastT))
.attrTween("transform", translateAlong(linepath.node()))
.on("end", function(){
pauseValues = {
lastT: 0,
currentT: 0
};
transition()
});
}
function translateAlong(path) {
var l = path.getTotalLength();
return function(d, i, a) {
return function(t) {
t += pauseValues.lastT;
var p = path.getPointAtLength(t * l);
pauseValues.currentT = t;
return "translate(" + p.x + "," + p.y + ")";
};
};
}
d3.select('button').on('click',function(d,i){
var self = d3.select(this);
if (self.text() == "Pause"){
self.text('Play');
circle.transition()
.duration(0);
setTimeout(function(){
pauseValues.lastT = pauseValues.currentT;
}, 100);
}else{
self.text('Pause');
transition();
}
});
*/
}
</script>
</body>
</html>
You are not projecting your line:
var linepath = svg.append("path")
.datum(data)
.attr("d", line)
.attr('class', 'line');
In this case your longitude/latitude pairs in your geojson are converted to straight pixel coordinates:
var line = d3.line()
.x(function(d) { return (d.lon); })
.y(function(d) { return (d.lat); })
.curve(d3.curveBasis);
As svg coordinates start at [0,0] in the top left, and your points appear to be around 10 degrees east or so (positive longitude), and 50 degrees north or so (positive latitude), your first point in the line appears 10 pixels from the left and 50 pixels from the top. Also, because svg y values increase as one moves down, but latitude values increase as one moves north (typcally up on a map), your line also appears inverted on the y axis compared to your points.
You could set your line function to use a projection to set the x and y points:
var line = d3.line()
.x(function(d) { return projection([d.lon,d.lat])[0] ; })
.y(function(d) { return projection([d.lon,d.lat])[1]; })
.curve(d3.curveBasis);
You need both latitude and longitude to project a point, so the projection function takes both, and returns both x and y, hence the [0] and [1], this is why your commented out sections don't work
But this is unnecessary, you can pass geojson straight to the path (the same as you do for the world background), that is if your data is available in geojson (though it is not hard to make a geojson on the fly):
var linepath = svg.append("path")
.datum(data) // in geojson form
.attr("d", path) // use your path
.attr('class', 'line');
This is more accurate than a line - the segments between lines in a d3.line are straight or follow a predefined curve, in Cartesian coordinate space. A d3.geoPath follows great circle distance, so the segments between points follow the shortest path on the planet, a more accurate representation, thought at times perhaps, less stylistic.
To create the geojson on the fly, assuming your data looks like: [{lon:number,lat:number},{lon:number,lat:number}] you could use something like:
var points = data.map(function(d) { return [d.lon,d.lat] })
var geojson = { "type": "LineString", "coordinates": points }

Piechart not being rendered when values supplied through d3.json

I am trying to read the values as specified in a JSON and based on those values creating a Piechart in d3.json. But on supplying values manually, the piechart is fully functional! The JSON file is present in the same directory as the .html file. Moreover, the var dataset is being populated with the desired values, which is verified by logging the dataset in the console. And I am not getting any error in the Chrome Browser.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sentiments Score</title>
<script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<div id="chart"></div>
<script type="text/javascript">
var dataset = [
{ "label": 'Neutral'},
{ "label": 'Positive'},
{ "label": 'Negative' }
];
d3.json("senti_analysis.json", function(data){
for (var i =0; i<dataset.length;i++)
{
if (dataset[i].label == 'Neutral')
{
dataset[i].count = +data.key.senti.neu;
}
else if (dataset[i].label == 'Positive') {
dataset[i].count = +data.key.senti.pos;
}
else
{
dataset[i].count = +data.key.senti.neg;
}
}
});
/*
var dataset = [{ label: 'Neutral', count: 0.45 },
{ label: 'Positive', count: 0.45 },
{ label: 'Negative', count: 0.10 }
];*/
console.log(dataset);
var w = 360;
var h = 360;
var r = Math.min(w, h) / 2;
var color = d3.scaleOrdinal(d3.schemeCategory20b);
var svg = d3.select('#chart')
.append('svg')
.attr('width', w)
.attr('height', h)
.append('g')
.attr('transform', 'translate(' + (w / 2) + ',' + (h / 2) + ')');
var arc = d3.arc()
.innerRadius(0)
.outerRadius(r);
var pie = d3.pie()
.value(function(d) { return d.count; })
.sort(null);
var path = svg.selectAll('path')
.data(pie(dataset))
.enter()
.append('path')
.attr('d', arc)
.attr('fill', function(d, i) {
return color(d.data.label);
});
</script>
</body>
The json file I am trying to read is as below:
{
"key": {
"senti": {
"neg": 0.10,
"neu": 0.45,
"pos": 0.45,
"compound": 0.784
},
"post": "I am excited to do Sentiment Analysis. I live in Tempe
and I love learning!"
}
}

Using dynamic input(CSV) in d3js

I am trying to use dynamic input to a draw function in d3js. So when the user changes the csv it would remove the current selection and draw the visualization for the new input. So my question is would I be using a onChange function with the select and then within this function parse the csv and call for the draw function.The current working code is here in plunker:
https://plnkr.co/edit/AjVBK3rTOF5aI4eDDbV5?p=preview
<svg width="1250" height="1080"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width");
var format = d3.format(",d");
var color = d3.scaleOrdinal(d3.schemeCategory10);
var pack = d3.pack()
.size([width, width])
.padding(1.5);
var inputs = {};
function selectCity(){
//storing the drop-dsown selection in the ddSelection var
var ddSelection = document.getElementById("city").value;
//feeding that to create the csv filename you want
var str1 = ddSelection;
var str2 = ".csv";
var csvFile = str1.concat(str2);
str1.concat(str2);
console.log(csvFile);
d3.csv(csvFile, function(d) {
d.sno = +d.sno;
return d;
}, function(error, data) {
if (error) throw error;
d3.selectAll("input").on("change", function(){
inputs[this.id] = +this.value;
console.log(inputs.myValue + "-" + inputs.myRating)
if(inputs.myValue && inputs.myRating){
var classes = data.filter(d => d.value < inputs.myValue && d.rating >= inputs.myRating);
draw(classes);
}
})
function draw(classes) {
console.log(classes.length);
var root = d3.hierarchy({
children: classes
})
.sum(function(d) {
return d.value;
})
.each(function(d) {
if (id = d.data.id) {
var id, i = id.lastIndexOf(".");
d.id = id;
d.package = id.slice(0, i);
d.class = id.slice(i + 1);
}
});
var node = svg.selectAll(".node")
.data(pack(root).leaves())
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
node.append("circle")
.attr("id", function(d) {
return d.id;
})
.attr("r", function(d) {
return d.r;
})
.style("fill", function(d) {
return color(d.package);
});
node.append("clipPath")
.attr("id", function(d) {
return "clip-" + d.id;
})
.append("use")
.attr("xlink:href", function(d) {
return "#" + d.id;
});
node.append("text")
.attr("clip-path", function(d) {
return "url(#clip-" + d.id + ")";
})
.selectAll("tspan")
.data(function(d) {
return d.class.split(/(?=[A-Z][^A-Z])/g);
})
.enter().append("tspan")
.attr("x", 0)
.attr("y", function(d, i, nodes) {
return 13 + (i - nodes.length / 2 - 0.5) * 10;
})
.text(function(d) {
return d;
});
node.append("title")
.text(function(d) {
return d.data.id + "\n" + format(d.value);
});
}
});
}
</script>
</div>
Here is one example how to do it: http://www.d3noob.org/2014/04/using-html-inputs-with-d3js.html
You don't have to redraw everything but update certain elements.
I don't understand your part about changing the CSV. The user does not change the CSV but your visual output is depending on some user data. So yes, within the callback function of d3.csv(), you write your code that calls some kind of a draw function. But the draw function does not have to be defined there. You can write the function outside and just call it there. This increased the readable of your code dramatically. ;)

how to replace comma with dot

I am having comma values inside my json and i want when i get those values i get them in dot so basically I want to convert my comma values into dot values..my json looks like and its always fixed that i will get comma values at val003.
I know something to do like var new = new.replace(/,/g, '.') . but how can i specify my val003 here for the conversion. Thank you in advance
My html
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta content="utf-8" http-equiv="encoding">
<div id="below">
<div id="chart"></div>
</div>
<script>
var jsonURL = 'avb.json';
var myData = [];
var fliterdata = [];
var tempdata = [];
var selectop = "";
var selectDate = false;
var chartType = chartType || 'bar';
function filterJSON(json, key, value) {
var result = [];
for (var foo in json) {
var extractstr = json[foo][key] ;
extractstr=String(extractstr);
if (extractstr.slice(3)== value) {
result.push(json[foo]);
}
}
return result;
}
function selectValue(d) {
switch (selectop) { //d object select particular value for Y axis
case "01":
return d.val001;
break;
case "02":
return d.val002;
break;
case "03":
return d.val003;
break;
case "04":
return d.val004;
break;
default:
//console.log("default");
return d.val001;
}
}
var line = d3.svg.line()
.x(function(d) {
return xScale(d.date);
})
.y(function(d) {
return yScale(selectValue(d));
})
.interpolate("monotone")
.tension(0.9);
yScale.domain([0, d3.max(tempData, function(d) {
return +selectValue(d);
})]);
var svg = d3.select('#chart').append('svg')
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
if (chartType == 'bar') {
svg
.selectAll(".bar") //makes bar
.data(tempData)
.enter().append("rect")
.attr("class", "bar")
.style("fill", "teal")
.attr("x", function(d) {
return xScale(d.date);
}).attr("width", xScale.rangeBand())
.attr("y", function(d) {
return yScale(selectValue(d));
}).attr("height", function(d) {
console.log("as", d.value);
return height - yScale(selectValue(d));
})
}
if (chartType == 'line') {
svg.append("path") // Add the line path.
.data(tempData)
.attr("class", "line")
.attr("d", line(tempData));
}
}
d3.json(jsonURL, function(data) {
myData = data; //data from json in mydata
d.val003.replace(",",".")
myData.forEach(function(d) {
d.date = new Date(d.date);
d.date = new Date(d.date + " UTC");
});
$("#listbox").on("click", function() {
var key = $(this).val();
console.log("key:", key);
var value = $('#listbox option:selected').text();
console.log("vaue:", value);
selectop = String(key);
selectop = selectop.slice(-2);
console.log("mydata: ", myData);
console.log("selectops:", selectop);
fliterdata = filterJSON(myData, key, value); //selected value from user and picks the whole element that contains that attribute
console.log("fliterdata: ", fliterdata);
tempData = fliterdata; //graph made by temp data
if (selectDate)
render(true);
});
});
function selectChartType(type) {
chartType = type;
render(true);
}
</script>
</body>
</div>
</body>
</html>
Try this,
return d.val003.toString().replace(",",".");
Yo can simply request a value in a JSon object -- it pretty much serves as an object in JavaScript.
So if you have your JSon object, lets call it json you can simply do:
var url = *your url*, json;
// retrieve the json object from a URL
$.getJSON(url, function (response) {$
json = response;
});
// reassing val003 with the corrected string
json.val003 = json.val003.replace(",", ".")
That should work, I believe.
If it is always the comma in a decimal number you want to replace, than you can do a search replace in the whole json string for the sequence "number" "comma" "number" like:
([0-9]),([0-9])
and replace it with:
$1.$2
$1 and $2 are the placeholders for the found numbers before and after the comma.
You can use this site for online testing:
http://www.regexe.com/

Search functionality for D3 bundle layout

I'm a noob and trying to implement a search method for a diagram.
The diagram is a chord diagram and was mostly adapted from here:
http://bl.ocks.org/mbostock/1044242
And the search function was taken from here:
http://mbostock.github.io/protovis/ex/treemap.html
My problem is that when it reads my file it interprets the text as: [object SVGTextElement] and so the only hit I have for my search is if I search [object SVGTextElement].
This is my entire code:
<html>
<head>
<title>I'm Cool</title>
<link rel="stylesheet" type="text/css" href="ex.css?3.2"/>
<script type="text/javascript" src="../protovis-r3.2.js"></script>
<script type="text/javascript" src="bla3.json"></script>
<style type="text/css">
.node {
font: 300 11px "Helvetica Neue", Helvetica, Arial, sans-serif;
fill: #bbb;
}
.node:hover {
fill: #000;
}
.link {
stroke: steelblue;
stroke-opacity: 0.4;
fill: none;
pointer-events: none;
}
.node:hover,
.node--source,
.node--target {
font-weight: 700;
}
.node--source {
fill: #2ca02c;
}
.node--target {
fill: #d62728;
}
.link--source,
.link--target {
stroke-opacity: 1;
stroke-width: 2px;
}
.link--source {
stroke: #d62728;
}
.link--target {
stroke: #2ca02c;
}
#fig {
width: 860px;
}
#footer {
font: 24pt helvetica neue;
color: #666;
}
input {
font: 24pt helvetica neue;
background: none;
border: none;
outline: 0;
}
#title {
float: right;
text-align: right;
}
</style>
<body><div id="center"><div id="fig">
<div id="title"></div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var diameter = 800,
radius = diameter / 2,
innerRadius = radius - 160;
var cluster = d3.layout.cluster()
.size([360, innerRadius])
.sort(null)
.value(function(d) { return d.size; });
var bundle = d3.layout.bundle();
var line = d3.svg.line.radial()
.interpolate("bundle")
.tension(.85)
.radius(function(d) { return d.y; })
.angle(function(d) { return d.x / 180 * Math.PI; });
var svg = d3.select("body").append("svg")
.attr("width", diameter)
.attr("height", diameter)
.append("g")
.attr("transform", "translate(" + radius + "," + radius + ")");
var link = svg.append("g").selectAll(".link"),
node = svg.append("g").selectAll(".node");
d3.json("bla3.json", function(error, classes) {
var nodes = cluster.nodes(packageHierarchy(classes)),
links = packageImports(nodes);
link = link
.data(bundle(links))
.enter().append("path")
.each(function(d) { d.source = d[0], d.target = d[d.length - 1]; })
.attr("class", "link")
.attr("d", line);
node = node
.data(nodes.filter(function(n) { return !n.children; }))
.enter().append("text")
.attr("class", "node")
.attr("dx", function(d) { return d.x < 180 ? 12 : -12; })
.attr("dy", ".31em")
.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")" + (d.x < 180 ? "" : "rotate(180)"); })
.style("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
.text(function(d) { return d.key; })
.on("mouseover", mouseovered)
.on("mouseout", mouseouted);
});
function mouseovered(d) {
node
.each(function(n) { n.target = n.source = false; });
link
.classed("link--target", function(l) { if (l.target === d) return l.source.source = true; })
.classed("link--source", function(l) { if (l.source === d) return l.target.target = true; })
.filter(function(l) { return l.target === d || l.source === d; })
.each(function() { this.parentNode.appendChild(this); });
node
.classed("node--target", function(n) { return n.target; })
.classed("node--source", function(n) { return n.source; });
}
function mouseouted(d) {
link
.classed("link--target", false)
.classed("link--source", false);
node
.classed("node--target", false)
.classed("node--source", false);
}
d3.select(self.frameElement).style("height", diameter + "px");
// Lazily construct the package hierarchy from class names.
function packageHierarchy(classes) {
var map = {};
function find(name, data) {
var node = map[name], i;
if (!node) {
node = map[name] = data || {name: name, children: []};
if (name.length) {
node.parent = find(name.substring(0, i = name.lastIndexOf(".")));
node.parent.children.push(node);
node.key = name.substring(i + 1);
}
}
return node;
}
classes.forEach(function(d) {
find(d.name, d);
});
return map[""];
}
// Return a list of imports for the given array of nodes.
function packageImports(node) {
var map = {},
imports = [];
// Compute a map from name to node.
node.forEach(function(d) {
map[d.name] = d;
});
// For each import, construct a link from the source to target node.
node.forEach(function(d) {
if (d.imports) d.imports.forEach(function(i) {
imports.push({source: map[d.name], target: map[i]});
});
});
return imports;
}
function title(d) {
return d.parentNode ? (title(d.parentNode) + "." + d.nodeName) : d.nodeName;
}
var re = "",
color = pv.Colors.category19().by(function(d) d.parentNode.nodeName)
node = pv.dom(bla3).root("bla3.json").node();
var vis = new pv.Panel()
.width(860)
.height(568);
cluster.bundle.add(pv.Panel)
.fillStyle(function(d) color(d).alpha(title(d).match(re) ? 1 : .2))
.strokeStyle("#fff")
.lineWidth(1)
.antialias(false);
cluster.bundle.add(pv.Label)
.textStyle(function(d) pv.rgb(0, 0, 0, title(d).match(re) ? 1 : .2));
vis.render();
/** Counts the number of matching classes, updating the title element. */
function count() {
var classes = 0, bytes = 0, total = 0;
for (var i = 0; i < node.length; i++) {
var n = node[i];
if(n.firstChild) continue;
total += n.nodeValue;
if (title(n).match(re)) {
classes++;
bytes += n.nodeValue;
}
}
var percent = bytes / total * 100;
document.getElementById("title").innerHTML
= classes + " classes found "+n;
}
/** Updates the visualization and count when a new query is entered. */
function update(query) {
if (query != re) {
re = new RegExp(query, "i");
count();
vis.render();
}
}
count();
</script>
<div id="footer">
<label for="search">search: </label>
<input type="text" id="search" onkeyup="update(this.value)">
</div>
</div></div></body>
</html>
The input is bla3.json and looks like this:
[{"name":"A.Patient Intake","imports":["E.Name","C.injury","E.DOB","E.Email","Progress","B.Obtain Brief Medical History","Perform Physical Exam","Perform Subjective Patient Evaluation"]},
{"name":"C.injury","imports":[]},
{"name":"E.Name","imports":[]},
{"name":"E.Email","imports":[]},
...
I didn't put the whole thing but it shouldn't matter...
My purpose is of course to have a search function that I could type, for example, "Patient Intake" and it will highlight that chord (or just the name):
Any ideas of how to go about this?
I would approach this in a completely different way to what you're currently doing. I would filter the data based on the query (not the DOM elements) and then use D3's data matching to determine what to highlight. In code, this would look something like this.
function update(query) {
if (query != re) {
re = new RegExp(query, "i");
var matching = classes.filter(function(d) { return d.name.match(re); });
d3.selectAll("text.node").data(matching, function(d) { return d.name; })
// do something with the nodes
// can be source or target in links, so we use a different method here
links.filter(function(d) {
var ret = false;
matching.forEach(function(e) {
ret = ret || e.name == d.source.name || e.name == d.target.name;
});
return ret;
})
// do something with the links
}
}