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 ******
答案 0 :(得分:1)
微小变化:
主要问题的解决方案,即轴未更新=>您正在调用select('.x')
,但是在创建 x 和 y 轴时错过了添加类的操作。
svg.append("g").attr('class', 'x')....
svg.append("g").attr('class', 'y')...
代码的一些补充(也许您可以将其作为我的建议):
通常,折线图只是一条简单的线,没有显示填充区域。为此,请进行以下更改(添加到path
后),或者您可以添加CSS:
.style('fill', 'none')
.style('stroke', '#000')
.header
不需要任何填充。调整大小时看起来混乱了。删除了.header { /* padding: 20px 0px 20px 0px; */ }
也许您错过了这一点,但是y
列输入并没有在更改时调用updateData()
。
d3.select('#input-cadenceLengthData')
...
.append('input')
.on('input', updataData)
将以上所有内容放在一起,这是一个小提琴:https://jsfiddle.net/nq1rfy7c/
摘要:
//****** 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(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")
.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) {
d.x = +d.x;
d.y = +d.y;
});
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 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 ******
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>
希望这会有所帮助。