I'm currently making a simple line chart that updates its values based on a series of input forms.
I can create and render the chart correctly, and can update the line upon user input, however my axis labels aren't updating in turn. I've tried following a few other examples here but to no avail, can someone please help me in fixing my updateData() function to update the axis labels in my code?
jsfiddle - https://jsfiddle.net/quirkules/0xktoLj7/1/
//****** CREATE CHART ******
//collect data from input fields
var data = [];
for (var i = 0; i < 10; i++) {
data.push({
x: d3.select('#cadenceThroughputData' + i).select('input').property('value'),
y: d3.select('#cadenceLengthData' + i).select('input').property('value'),
});
}
// set the dimensions and margins of the graph
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = d3.select('#output-chart').node().getBoundingClientRect().width - margin.left - margin.right,
height = d3.select('#output-chart').node().getBoundingClientRect().height - margin.top - margin.bottom;
// set the ranges
var x = d3.scaleLinear().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
var x_axis = d3.axisBottom().scale(x);
var y_axis = d3.axisLeft().scale(y);
// define the line
var valueline = d3.line()
.x(d => { return x(d.x); })
.y(d => { return y(d.y); });
// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("#output-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 + ")");
// format the data
data.forEach(function(d) {
d.x = +d.x;
d.y = +d.y;
});
// Scale the range of the data
x.domain([0, d3.max(data, d => { return d.x; })]);
y.domain([0, d3.max(data, d => { return d.y; })]);
// Add the valueline path.
svg.append("path")
.data([data])
.attr("class", "line")
.attr("d", valueline);
// Add the X Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(x_axis);
// Add the Y Axis
svg.append("g")
.call(y_axis);
function updataData(){
//collect data from input fields again
var data = [];
for (var i = 0; i < 10; i++) {
data.push({
x: d3.select('#cadenceThroughputData' + i).select('input').property('value'),
y: d3.select('#cadenceLengthData' + i).select('input').property('value'),
});
}
// format the data
data.forEach(function(d) {
d.x = +d.x;
d.y = +d.y;
});
// Scale the range of the data again
x.domain([0, d3.max(data, d => { return d.x; })]);
y.domain([0, d3.max(data, d => { return d.y; })]);
// Select the section we want to apply our changes to
var svg = d3.select("#output-chart").transition();
// Make the changes
// change the line
svg.select(".line")
.duration(750)
.attr("d", valueline(data));
// change the x axis
svg.select(".x")
.duration(750)
.call(x_axis);
// change the y axis
svg.select(".y")
.duration(750)
.call(y_axis);
}
//****** END CREATE CHART ******
Minor changes:
Solution for the main issue ie axes not updating => You're calling select('.x')
but you missed adding the classes while creating x and y axis.
svg.append("g").attr('class', 'x')....
svg.append("g").attr('class', 'y')...
Some additions to the code (maybe you can term them as my suggestions):
Usually a line chart is just a simple line with no filled area shown. To do that, here's the change (to the path
append) or you can add CSS:
.style('fill', 'none') .style('stroke', '#000')
The .header
doesn't need any padding. It looks messed up when resized. Removed .header { /* padding: 20px 0px 20px 0px; */ }
.header { /* padding: 20px 0px 20px 0px; */ }
Maybe you missed this but the y
column input doesn't call updateData()
on change.
d3.select('#input-cadenceLengthData') ... .append('input') .on('input', updataData)
Putting together all of the above, here's a fiddle: https://jsfiddle.net/nq1rfy7c/
Snippet:
//****** SETUP DIVS ****** // Add the divs to the DOM $(document.body) .append('<div id="global-header"></div>') .append('<div id="input-cadenceSelect"></div>') .append('<div id="input-cadenceThroughputHeader"></div>') .append('<div id="input-cadenceLengthHeader"></div>') .append('<div id="input-cadenceType"></div>') .append('<div id="input-cadenceThroughputData"></div>') .append('<div id="input-cadenceLengthData"></div>') .append('<div id="output-chart"></div>') .append('<div id="output-summary"></div>') .append('<div id="global-footer"></div>'); //add text to #input-cadenceThroughputHeader d3.select('#input-cadenceThroughputHeader') .append('label') .text('X Value'); d3.select('#input-cadenceLengthHeader') .append('label') .text('Y Value'); for (var i = 0; i < 10; i++) { //add 10 #cadenceType divs to #input-cadenceType d3.select('#input-cadenceType') .append('div') .attr('class', 'header') .attr('id', 'cadenceType' + i) .style('position', 'absolute') .style('top', (i * 10) + '%') .style('width', '100%') .style('height', '10%') .style('display', 'table') .style('background', bandColour(i)) .append('label') .text((i + 1)); //add 10 #cadenceData divs to #input-cadenceData d3.select('#input-cadenceThroughputData') .append('div') .attr('id', 'cadenceThroughputData' + i) .style('position', 'absolute') .style('top', (i * 10) + '%') .style('width', '100%') .style('height', '10%') .style('background', bandColour(i)) .append('input') .on('input', updataData) .attr('size', '6') .attr('maxlength', '4') .style('height', '20px') .style('background', bandColour(i)) .attr('value', parseInt(Math.random() * 100)); //add 10 #cadenceLength divs to #input-cadenceLength d3.select('#input-cadenceLengthData') .append('div') .attr('id', 'cadenceLengthData' + i) .style('position', 'absolute') .style('top', (i * 10) + '%') .style('width', '100%') .style('height', '10%') .style('background', bandColour(i)) .append('input') .attr('size', '6') .attr('maxlength', '4') .style('height', '20px') .style('background', bandColour(i)) .on('input', updataData) .attr('value', parseInt(Math.random() * 10)); } function bandColour(i) { if (i % 2 > 0) { return '#333'; } else { return '#171213'; } } //****** END SETUP DIVS ****** //****** CREATE CHART ****** //collect data from input fields var data = []; for (var i = 0; i < 10; i++) { data.push({ x: d3.select('#cadenceThroughputData' + i).select('input').property('value'), y: d3.select('#cadenceLengthData' + i).select('input').property('value'), }); } // set the dimensions and margins of the graph var margin = { top: 20, right: 20, bottom: 30, left: 50 }, width = d3.select('#output-chart').node().getBoundingClientRect().width - margin.left - margin.right, height = d3.select('#output-chart').node().getBoundingClientRect().height - margin.top - margin.bottom; // set the ranges var x = d3.scaleLinear().range([0, width]); var y = d3.scaleLinear().range([height, 0]); var x_axis = d3.axisBottom().scale(x); var y_axis = d3.axisLeft().scale(y); // define the line var valueline = d3.line() .x(d => { return x(dx); }) .y(d => { return y(dy); }); // append the svg obgect to the body of the page // appends a 'group' element to 'svg' // moves the 'group' element to the top left margin var svg = d3.select("#output-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 + ")"); // format the data data.forEach(function(d) { dx = +dx; dy = +dy; }); // Scale the range of the data x.domain([0, d3.max(data, d => { return dx; })]); y.domain([0, d3.max(data, d => { return dy; })]); // Add the valueline path. svg.append("path") .data([data]) .attr("class", "line") .style('fill', 'none') .style('stroke', '#000') .attr("d", valueline); // Add the X Axis svg.append("g").attr('class', 'x') .attr("transform", "translate(0," + height + ")") .call(x_axis); // Add the Y Axis svg.append("g").attr('class', 'y') .call(y_axis); function updataData() { //collect data from input fields again var data = []; for (var i = 0; i < 10; i++) { data.push({ x: d3.select('#cadenceThroughputData' + i).select('input').property('value'), y: d3.select('#cadenceLengthData' + i).select('input').property('value'), }); } // format the data data.forEach(function(d) { dx = +dx; dy = +dy; }); x_axis = d3.axisBottom().scale(x); y_axis = d3.axisLeft().scale(y); // Scale the range of the data again x.domain([0, d3.max(data, d => { return dx; })]); y.domain([0, d3.max(data, d => { return dy; })]); // Select the section we want to apply our changes to var svg = d3.select("#output-chart").transition(); // Make the changes // change the line svg.select(".line") .duration(750) .attr("d", valueline(data)); // change the x axis svg.select(".x") .duration(750) .call(x_axis); // change the y axis svg.select(".y") .duration(750) .call(y_axis); } //****** END CREATE CHART ******
body { font-family: sans-serif; color: white; background: #171213; } label { display: block; } input, textarea { color: white; font-size: 18px; font-weight: bold; text-align: center; border: 2px solid transparent; } #global-header { position: fixed; left: 0px; top: 0px; height: 5%; width: 100%; padding: 10px; box-sizing: border-box; text-align: center; font-size: 1.5em; font-family: Helvetica; color: white; } .header { color: #009DE0; font-size: 18px; font-weight: bold; text-align: center; display: table-cell; vertical-align: middle; /* padding: 20px 0px 20px 0px; */ } #input-cadenceType { position: fixed; box-sizing: border-box; border-left: 2px solid #009DE0; border-top: 2px solid #009DE0; border-bottom: 2px solid #009DE0; margin-left: 0%; top: 25%; width: 10%; height: 73%; } #input-cadenceThroughputHeader { position: fixed; color: #009DE0; font-size: 12px; font-weight: bold; text-align: center; box-sizing: border-box; border-left: 2px solid #009DE0; border-top: 2px solid #009DE0; margin-left: 10%; top: 20%; width: 10%; height: 5%; text-align: center; } #input-cadenceLengthHeader { position: fixed; color: #009DE0; font-size: 12px; font-weight: bold; text-align: center; box-sizing: border-box; border-left: 2px solid #009DE0; border-top: 2px solid #009DE0; margin-left: 20%; top: 20%; width: 10%; height: 5%; text-align: center; } #input-cadenceThroughputData { position: fixed; box-sizing: border-box; border-top: 2px solid #009DE0; border-left: 2px solid #009DE0; border-bottom: 2px solid #009DE0; margin-left: 10%; top: 25%; width: 10%; height: 73%; } #input-cadenceLengthData { position: fixed; box-sizing: border-box; border-top: 2px solid #009DE0; border-left: 2px solid #009DE0; border-bottom: 2px solid #009DE0; margin-left: 20%; top: 25%; width: 10%; height: 73%; } #input-simConstraint { position: fixed; margin-left: 30%; top: 5%; width: 35%; height: 20%; background: aqua; text-align: right; } #input-simDataHeader { position: fixed; margin-left: 65%; top: 5%; width: 35%; height: 5%; background: orange; text-align: center; } #input-simDataNoStoriesHeader { position: fixed; margin-left: 65%; top: 10%; width: 11.67%; height: 5%; background: green; text-align: center; } #input-simDataFocusHeader { position: fixed; margin-left: 76.67%; top: 10%; width: 11.67%; height: 5%; background: silver; text-align: center; } #input-simDataLengthHeader { position: fixed; margin-left: 88.34%; top: 10%; width: 11.67%; height: 5%; background: goldenrod; text-align: center; } #input-simDataNoStoriesValue { position: fixed; margin-left: 65%; top: 15%; width: 11.67%; height: 5%; background: pink; text-align: center; } #input-simDataFocusValue { position: fixed; margin-left: 76.67%; top: 15%; width: 11.67%; height: 5%; background: navy; text-align: center; } #output-chart { position: fixed; margin-left: 30%; top: 20%; width: 70%; height: 58%; background: red; text-align: right; } #global-footer { position: fixed; background: #171213; left: 0px; bottom: 0px; height: 2%; width: 100%; vertical-align: middle; text-align: right; font-size: 0.75em; font-family: Helvetica; color: white; }
<script src="https://d3js.org/d3.v4.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
Hope this helps.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.