path element shows as individual points in the dom instead of one string of elements in SVG. The code looks like this
//------ BEGIN NEW CODE HERE ------
let univMenu = d3.select("#univDropdown");
univMenu
.append("select")
.selectAll("option")
.data(nest)
.enter()
.append("option")
.attr("value", function(d){return d.key;})
.text(function(d){return d.key;})
// Function to create the initial graph
let initialGraph = function(univ){
let selectUniv = nest.filter(function(d){return d.key == univ;})
let selectUnivGroups = svg.selectAll(".univGroups")
.data(selectUniv, function(d){return d ? d.key : this.key;})
.enter()
.append("g")
.attr("class", "univGroups")
let initialPath = selectUnivGroups.selectAll(".line")
.data(function(d) { return d.values; })
.enter()
.append("path")
initialPath
.attr("d", function(d){return valueLine(d.values)})
.attr("class", "line")}
// Create initial graph
initialGraph("USHE Average")
// Update the data
let updateGraph = function(univ){
// Filter the data to include only fruit of interest
let selectUniv = nest.filter(function(d){return d.key == univ;})
// Select all of the grouped elements and update the data
let selectUnivGroups = svg.selectAll(".univGroups")
.data(selectUniv)
// Select all the lines and transition to new positions
selectUnivGroups.selectAll("path.line")
.data(function(d){return (d.values);})
.transition()
.duration(1000)
.attr("d", function(d){return valueLine(d.values)})}
// Run update function when dropdown selection changes
univMenu.on('change', function(){
let selectedUniv = d3.select(this)
.select("select")
.property("value")
updateGraph(selectedUniv)
});
The idea is I would have a selector to toggle between different universities to show their cost through the 'univMenu'.
Any help to get the path to show individually would be very greatly appreciated. I have the style in the CSS.
EDIT: the valueLine variable is defined as:
var valueLine = d3.line()
.x(function(d) { return x(d.Year); })
.y(function(d) { return y(+d.Currentdollars); });
A sample of the CSV is
University,USHE average,Constant dollars,Currentdollars,Year,% change from
previous year
University of Utah,NA,"$49,711 ",56990.00,2008,NA
I'm having a mental block about using the result of:
.rollup(function(leaves) { return leaves.length;})
as the radius of a circle in a scatter plot. My complete code (and sample data) is in a plunk here https://plnkr.co/edit/Cwuce6inLV5jouCWTFfN
The scatter works with a static value of 5 but I'd like to use value based on the .rollup from the d3.nest as explained in this other SO question I had: Capturing leaves.length value from d3.nest
I think I'm missing a key concept about in this section of code:
d3.tsv("etds_small.tsv", function(error, dataset) {
dataset.forEach(function(d) {
if(deptlist.indexOf(d.dept) == -1) deptlist.push(d.dept);
if(years.indexOf(d.year) == -1) years.push(d.year);
})
var deptYearCount = d3.nest()
//.key(function(d) { return d.college;} )
.key(function(d) { return d.dept})
.key(function(d) { return d.year })
.rollup(function(leaves) { return leaves.length;})
.map(dataset);
console.log(dataset); // retains the college, dept, and year labels
console.log(deptYearCount); // replaces labels with "key"
x.domain(years.sort(d3.ascending));
y.domain(deptlist.sort(d3.ascending));
//console.log(y.domain());
//console.log(x.domain());
svg.selectAll(".dot")
.data(dataset) //should this be deptYearCount from the d3.nest above?
.enter().append("circle")
.attr("class", "dot")
.attr("r", 5) // Would like to use length (from d3.nest) as radius
//.attr("r", function(d) {return d.values.length*1.5;}) works with .data(debtYearCount)
.style("opacity", 0.3)
.style("fill", "#e31a1c" )
.attr("cx", function(d) {
return x(d.year);
})
.attr("cy", function(d) {
return y(d.dept);
});
Give this a try for your radius:
.attr("r", function(d) {return Object.keys(deptYearCount[d.dept]).length*1.5;})
Because you are using .map(dataset) instead of .entries(dataset), d3.next() is returning one-big-object instead of an array of objects. That one-big-object does not contain a property called values.
Updated explanation:
First, look at the structure of the object deptYearCount. It has property names like Earth Sciences., Education., etc.
Our d3 data is iterating over an array of objects. Each object has property dept that looks like Earth Sciences., Education., etc.
So, deptYearCount[d.dept] is getting us to the correct property within deptYearCount.
For example, at one round of our iteration we are looking at deptYearCount["Education."]. That turns out to be another object with properties like 2007,2008, etc. Therefore, the number of properties in deptYearCount["Education."] is the value we want for the radius.
How do we find the number of properties of deptYearCount["Education."]? One way is the Object.keys(someObject) function. It returns an array of strings corresonding to the property names, and we just need its .length.
I'm new to this d3 and nvd3.I'm trying to build a multi line chart using nvd3 and i have got 2 issues
1) the x axis doesn't seem to show the right values for hour and minutes as in json data which has date in standard utc format.
2) when i put the the first value as non-zero for both memory and cpu it scales down to negative y axis and looks weird.
Ty for the help. here is the plunk
nv.addGraph(function() {
var chart = nv.models.cumulativeLineChart()
.x(function(d) {
console.log(d.time)
return d.time
})
.y(function(d) {
console.log(d.value)
return d.value
})
.color(["#FF0000", "#000000"])
.height(210)
.width(420)
.useInteractiveGuideline(false)
.showControls(false)
.forceY(0)
;
chart.xAxis
.tickFormat(function(d) {
return d3.time.format('%H:%M')(new Date(d))
});
chart.yAxis.tickFormat(d3.format(',.1'));
d3.select('nv-indexLine').fill("black");
d3.select('#chart svg')
.datum(formattedData)
.call(chart);
nv.utils.windowResize(chart.update);
chart.lines.interactive(false);
return chart;
});
One change make your function like this for return x values it should return a Date object.
So instead of doing this
.x(function(d) {
console.log(d.time)
return d.time
})
Do like this to return Date object
.x(function(d) {
console.log(d.time)
return new Date(d.time)
})
working code here
I'm having trouble understanding when and how to use nested data.
In this example I have a CSV with names ('Name') and locations ('starting point'). By assigning keys to the locations I am able to make a dropdown containing them all, and I would like to use this to filter the names associated with each location.
However I am unable to find the data's values, in this case 'd.Name'
Here inside the update function I have tried to access the 'values' on the data join.
var adventurer = canvas
.selectAll(".adventurer")
.data(function(d) {
return d.values;
})
Ive also tried creating an extra data variable but thats not working for me either.
Sorry I can't make a jsfiddle but here is a plunk
DATA
,,Name,First names,s,r,Nat,born,starting point,starting date,arrival date,days,km,Assist,Support,Style,note,arrival date 2
1,1,KAGGE,Erling,,,Nor,1/15/1963,Berkner Island,11/18/1992,1/7/1993,50,appr. 1300,n,n,solo,first solo unassisted,
2,2,ARNESEN,Liv,f,,Nor,6/1/1953,Hercules Inlet,11/4/1994,12/24/1994,50,1130,n,n,solo,first woman unassisted,
3,3,HAUGE,Odd Harald,,,Nor,1956,Berkner Island,11/4/1994,12/27/1994,54,appr. 1300,n,n,,,
HTML
<div id="menu"></div>
<div id="chart"></div>
SCRIPT
d3.csv("data.csv", function(csv_data) {
var data = d3.nest()
.key(function(d) {
return d['starting point'];})
.sortKeys(d3.ascending)
.entries(csv_data)
console.log(data);
//create dropdown select
var list = d3.select("#menu").append("select")
list.selectAll("option")
.data(data)
.enter().append("option")
.attr("value", function(d) {
return d.key;
})
.text(function(d) {
return d.key;
});
//chart config
var w = 375,
h = 1000;
var canvas = d3.select('#chart')
.append('svg')
.attr('width', w)
.attr('height', h)
.append('g')
.attr('transform', 'translate (0,50)');
//function (bind, add, remove, update)
function updateLegend(data) {
var adventurer = canvas
.selectAll(".adventurer")
.data(function(d) {
return d.values;
})
var adventurerEnter = adventurer
.enter().append("g")
.attr('class', 'adventurer');
adventurerEnter
.append("text")
.attr('class', 'name')
.attr('x', 0);
adventurer.select('.name')
.text(function(d, i) {
return d.Name;
})
.attr('y', function(d, i) {
return i * 30;
});
// remove old elements
adventurer.exit().remove();
};
// generate initial legend
updateLegend(data);
});
// handle on click event
d3.select('#menu')
.on('change', function() {
var data = eval(d3.select(this).property('value'));
console.log(data)
updateLegend(data);
});
You need to display both the locations and the names. You have a nest (in the plunk but not in your question) of location/name, but you also need a distinct list of names, or possibly a list of name/location:
var locations = d3.nest()
.key(function(d) {return d['starting point'];})
.sortKeys(function(a,b){ return a > b && 1 || b > a && -1 || 0})
.key(function(d) {return d.Name;})
.entries(csv_data)
var names = d3.nest()
.key(function(d) {return d.Name;})
.sortKeys(function(a,b){ return a > b && 1 || b > a && -1 || 0})
.key(function(d) {return d['starting point'];})
.entries(csv_data)
Then you have to display your names however you want. Then you need an .on('change', function()...) handler (or on click or whatever fits your needs) that actually filters the names wherever those are displayed.
I also fixed your sorting. d3.ascending is for numbers, not strings.
I've started from the multiline example http://bl.ocks.org/mbostock/3884955
I extended it to show the dots along the line, but I'm not able to give to the circle the same color of the line...
I'm really new in d3.js and I really need an advice.
here the example page: http://www.danielepennati.com/d3/linea.html
I've change some variable name to make the script more general so there is some difference with the original example code. the main one is the name of the variable that contain the mapped data: it is "column" and not "cities"
d3.tsv(surce_data, function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "id"; }));
var column = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {id: d.id, value: +replace(d[name])};
})
};
});
the second main difference is the x axsis: in my code it is ordinal and not linear.
so to draw the line the code is:
var tracciato = svg.selectAll(".line-group")
.data(column)
.enter().append("g")
.attr("class", "line-group");
tracciato.append("path")
.attr("class", "line")
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { return color(d.name); });
to make the points along the line I've wrote this code:
var point = tracciato.append("g")
.attr("class", "line-point");
point.selectAll('circle')
.data(function(d,i){ return d.values})
.enter().append('circle')
.attr("cx", function(d, i) {
return x(i) + x.rangeBand() / 2;
})
.attr("cy", function(d, i) { return y(d.value) })
.attr("r", 5);
I'd link the points color be the same of the line, but the problem is the colors are assigned to the "column" object. I don't know how to give to each new circle within the same column the same column color...
I don't know if my problem is clear, please ask me if you need any more specification.
Thanks