score:1
Call the initialgraph
with the nest
result as an argument. You only have a valid value in the nest variable when the callback is executing.
var initialgraph = function (stockName, nest) {
// Filter the data to include only stock of interest
var selectStock = nest.filter(function(d) { return d.key == stockName; });
//....
};
d3.json("api_all.php", function(data) {
data.forEach(e => {
e.date = parseDate(e.date);
e.value = +e.close;
e.stockName = e.stock_name;
});
var nest = d3.nest()
.key(function (d) { return d.stockName; })
.entries(data);
var xExtent = d3.extent(data, function(d) { return d.date; });
x.domain(xExtent);
zoom.translateExtent([[x(xExtent[0]), -Infinity], [x(xExtent[1]), Infinity]])
y.domain([0, d3.max(data, function(d) { return d.value; })]);
yGroup.call(yAxis).select(".domain").remove();
areaPath.datum(data);
zoomRect.call(zoom.transform, d3.zoomIdentity);
/*Build Dropdown Menu*/
var stockDropDown = d3.select("#dropdown")
stockDropDown
.append("select")
.selectAll("option")
.data(nest)
.enter()
.append("option")
.attr("value", function(d){
return d.key;
})
.text(function(d){
return d.key;
});
initialgraph("KYOKUYO CO.,LTD.", nest);
});
If initialgraph
is defined inside the callback you have no problem because it is a closure.
Edit
Like answered today about async functions, when d3.json()
returns does not mean the call back is called/finished. Remove the initialgraph()
call from line 134. And call it at the end of the callback.
Edit 2
Needed to look up an example for d3v4 and json to see what the interface is of the d3.json()
. According to the docs it is using fetch and promises but apparently not. The real interface is
d3.json(url, function (error, data) {
// process the data
});
Here is the complete code that shows at least the initial graph based on the json. I have not verified if it draws the correct graph.
Calling y.domain()
in an each()
call does not make sense. The max value is already determined based on the json data
. Maybe it is an idea to use the extend of the d.value
: d3.extend(data, d=>d.value);
The updategraph()
now gets a valid nest
value.
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 60},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
/*Define the rect*/
/*Parse dates*/
var parseDate = d3.timeParse("%Y-%m-%d"),
formatDate = d3.timeFormat("%Y");
/*Set the ranges*/
var x = d3.scaleTime()
.domain([new Date(2002, 0, 1), new Date(2003, 0, 1)])
.range([0, width]);
var y = d3.scaleLinear()
.range([height, 0]);
/*Create axes*/
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y);
var area = d3.area()
.curve(d3.curveStepAfter)
.y0(y(0))
.y1(function(d) { return y(d.value); });
var areaPath = g.append("path")
.attr("clip-path", "url(#clip)")
.attr("fill", "steelblue");
var yGroup = g.append("g");
var xGroup = g.append("g")
.attr("transform", "translate(0," + height + ")");
var zoom = d3.zoom()
.scaleExtent([1 / 4, 8])
.translateExtent([[-width, -Infinity], [2 * width, Infinity]])
.on("zoom", zoomed);
var zoomRect = svg.append("rect")
.attr("width", width)
.attr("height", height)
.attr("fill", "none")
.attr("pointer-events", "all")
.call(zoom);
g.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
/*Import Data from API*/
d3.json("api_all.php", function(error, data) {
data.forEach(e => {
e.date = parseDate(e.date);
e.value = +e.close;
e.stockName = e.stock_name;
});
var nest = d3.nest()
.key(function(d){
return d.stockName;
})
.entries(data);
/*Scale range of the data*/
var xExtent = d3.extent(data, function(d) { return d.date; });
x.domain(xExtent);
zoom.translateExtent([[x(xExtent[0]), -Infinity], [x(xExtent[1]), Infinity]])
y.domain([0, d3.max(data, function(d) { return d.value; })]);
yGroup.call(yAxis).select(".domain").remove();
areaPath.datum(data);
zoomRect.call(zoom.transform, d3.zoomIdentity);
/*Build Dropdown Menu*/
var stockDropDown = d3.select("#dropdown");
stockDropDown
.append("select")
.selectAll("option")
.data(nest)
.enter()
.append("option")
.attr("value", function(d){
return d.key;
})
.text(function(d){
return d.key;
});
stockDropDown.on("change", function() {
var selectedStock = d3.select(this)
.select("select")
.property("value");
updateGraph(selectedStock, nest);
});
initialgraph("KYOKUYO CO.,LTD.", nest);
});
/*Function to create initial graph*/
var initialgraph = function(stockName, nest) {
/*Filter the data to include only stock of interest*/
var selectStock = nest.filter(function(d) {
return d.key == stockName;
})
var selectStockGroups = svg.selectAll(".stockGroups")
.data(selectStock, function(d) {
return d ? d.key : this.key;
})
.enter()
.append("g")
.attr("class", "stockGroups")
// .each(function(d) {
// y.domain([0, d3.max(data, function(d) { return d.value; })]);
// })
;
var initialPath = selectStockGroups.selectAll(".rect")
.data(function(d) {return d.value.year})
.enter()
.append("path")
initialPath
.attr("d", function(d) {
return valueLine(d.values)
})
.attr("class", "rect")
/*Add Y Axis*/
var yaxis = svg.append("g")
.attr("class", "y axis")
.call(d3.axisLeft(y))
};
/*Create initial graph*/
//initialgraph("KYOKUYO CO.,LTD.");
/*Update the data*/
var updateGraph = function(stockName, nest) {
var selectStock = nest.filter(function(d) {
return d.key == stockName;
})
var selectStockGroups = svg.selectAll(".stockGroups")
.data(selectStock)
.each(function(d) {
y.domain([0, d3.max(data, function(d) { return d.value; })])
});
selectStockGroups.selectAll("path.rect")
.data(function(d) {return d.value.year;}, function(d) {return d.key})
.transition()
.duration(1000)
.attr("d", function(d) {
return valueLine(d.values)
})
}
/*Zoom function*/
function zoomed() {
var xz = d3.event.transform.rescaleX(x);
xGroup.call(xAxis.scale(xz));
areaPath.attr("d", area.x(function(d) { return xz(d.date); }));
}
Source: stackoverflow.com
Related Query
- javascript/D3 basics: If asynchronous call, why is code outside of json request?
- d3.json asynchronous solution
- How do I keep data after calling JSON in D3 through asynchronous call?
- Neat solution to convert flat data to nested JSON
- Convert a directory structure in the filesystem to JSON with Node.js
- d3 js - loading json without a http get
- Importing local json file using d3.json does not work
- Loading D3.js data from a simple JSON string
- D3 - how to deal with JSON data structures?
- Updating links on a force directed graph from dynamic json data
- How to convert to D3's JSON format?
- d3.js & json - simple sample code?
- Generate (multilevel) flare.json data format from flat json
- d3 - reading JSON data instead of CSV file
- Render D3 graph from a string of JSON instead of a JSON file
- how to load a json object instead of json file
- how to encode this data to parent / children structure in JSON
- D3.js - JSON data array is binding the same array element to everything
- How do I create a tree layout using JSON data in d3.v4 - without stratify()
- Dynamically update D3 Sunburst if the source json is updated (item added or deleted)
- Retrieving Keys from JSON Array key-value pair dynamically - Javascript
- How can I efficiently move from a Pandas dataframe to JSON
- d3 piechart from local json variable
- scipy dendrogram to json for d3.js tree visualisation
- Convert flat JSON file to hierarchical json data like flare.json [d3 example file]
- How do I load JSON data synchronously with d3.js?
- Convert csv to JSON tree structure?
- D3 JSON data conversion
- Recursively build hierarchical JSON tree?
- How to load data from an internal JSON array rather than from an external resource / file for a collapsible tree in d3.js?
More Query from same tag
- Pie chart keeps adjusting itself when updating - D3
- D3 - How to alter examples
- How to render a d3.js map on canvas free of blurriness
- SimpleHTTPServer code 404, message File not found
- D3 inserting a chart within the tooltip
- d3.js change array data mapping from normalized to regular stacked chart
- angularjs url together with django framework
- Binding data to existing number of elements based on object property
- getting error for d3 Js
- Data sorting in table in D3
- D3js - Creating and easily updating a multi-line chart
- D3 animate donut chart while updating it with different data length
- D3 tree link arrows are weird, not in the right place. How to fix them?
- How to calculate (SVG) X/Y coordinates out of translation and rotation (in JS/D3.js)?
- D3.js d3.line giving unexpected results when taking values from an input
- append a circle in middle of all my path (sunburst)
- Append foreignObject containing some HTML inside an SVG element
- How to make d3-diagram visualization from json-array working?
- d3 grouped bar chart inconsistent items alignment
- How to update d3.js pie chart with updated dataset
- How to turn dataset into multiple different color lines in D3.JS
- Adding Multiple shaped nodes to a force directed network diagram in d3v4
- Display Bar Chart for Last week, Last Month, and Last Year Data from JSON using D3.js
- How to refer to a D3 parent element's class?
- Indented tree in nvd3.js : searching for a specific node and opening all parents
- Make axis ticks strings in d3
- Unable to reset the focus ordinal bar chart
- D3: Issue while Displaying a Line chart inside tooltip
- d3js v4: Scale circles with zoom
- How to specify height and width of a d3 tree dynamically to allow it to take up all the space it needs