我正在尝试运行数据可视化应用程序,我使用D3.js,我的代码可以工作,但是当我更改所选选项时,图表会发生变化但会下降并且每次更改都会下降。 我不知道问题出在哪里。
那是我的代码:
<!DOCTYPE html>
<html>
<head>
<title> Graphique </title>
<script src="http://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script>
</head>
<body>
<FORM>
<SELECT id="Nb" size="1" onchange="Changement()">
<option>Selection</option>
<option>NbCopie</option>
<option>NbTache</option>
<option>NbCopieBW</option>
<option>NbCopieCouleur</option>
<option>MtTotal</option>
</SELECT>
</FORM>
<div id="chart"></div>
<svg width="960" height="500"></svg>
<script>
function Changement() {
d3.selectAll("svg > *").remove();
d3.json("Data.json", function(error, data) {
var Nb = data.map(function(d) {
var x = document.getElementById('Nb');
var i = x.selectedIndex;
var text = x.options[i].text;
if (text == "NbCopie")
return d.NbCopie;
else if (text == "NbTache")
return d.NbTache;
else if (text == "NbCopieBW")
return d.NbCopieBW;
else if (text == " NbCopieCouleur")
return d.NbCopieCouleur;
else if (text == "MtTotal")
return d.MtTotal;
});
var maxNb = d3.max(Nb);
var svg = d3.select("svg"),
margin = {
top: 30,
right: 30,
bottom: 40,
left: 50
},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var animateDuration = 700;
var animateDelay = 30;
var tooltip = d3.select('body').append('div')
.style('position', 'absolute')
.style('background', '#f4f4f4')
.style('padding', '5 15px')
.style('border', '1px #333 solid')
.style('border-raduis', '5px')
.style('opacity', '0')
var yScale = d3.scaleLinear()
.domain([0, maxNb])
.range([0, height])
var xScale = d3.scaleBand()
.domain(d3.range(0, Nb.length))
.range([0, width])
var colors = d3.scaleLinear()
.domain([0, Nb.length])
.range(['#0080FF', '#FF3333'])
var myChart = d3.select('#chart').append('svg')
.attr('width', width + margin.right + margin.left)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
.style('background', '#f4f4f4')
.selectAll('rect')
.data(Nb)
.enter().append('rect')
.style('fill', function(d, i) {
return colors(i);
})
.attr('width', xScale.bandwidth())
.attr('x', function(d, i) {
return xScale(i)
})
.attr('height', 0)
.attr('y', height)
.on('mouseover', function(d) {
tooltip.transition()
.style('opacity', 1)
tooltip.html(d)
.style('left', (d3.event.pageX) + 'px')
.style('top', (d3.event.pageY + 'px'))
d3.select(this).style('opacity', 0.5)
})
.on('mouseout', function(d) {
tooltip.transition()
.style('opacity', 0)
d3.select(this).style('opacity', 1)
})
myChart.transition()
.attr('height', function(d) {
return yScale(d);
})
.attr('y', function(d) {
return height - yScale(d);
})
.duration(animateDuration)
.delay(function(d, i) {
return i * animateDelay
})
.duration(1000)
.ease(d3.easeElastic)
var vScale = d3.scaleLinear()
.domain([0, maxNb])
.range([height, 0])
var vAxis = d3.axisLeft()
.scale(vScale)
.ticks(5)
.tickPadding(5)
var vGuide = d3.select('svg')
.append('g')
vAxis(vGuide)
vGuide.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
vGuide.selectAll('path')
.style('fill', 'none')
.style('stroke', '#000')
vGuide.selectAll('line')
.style('stroke', '#000')
var hScale = d3.scaleTime()
.domain(d3.extent(data, function(d) {
var parseDate = d3.timeParse("%Y%m%d");
Date_Id = parseDate(d.Date_Id);
return Date_Id;
}))
.range([0, width - 150])
var hAxis = d3.axisBottom()
.scale(hScale)
.ticks(d3.timeMonth)
var hGuide = d3.select('svg')
.append('g')
.attr("class", "axis axis--x")
.attr("transform", "translate(" + margin.left + "," + (height + margin.top) + ")")
.call(hAxis);
});
};
</script>
这是我的问题的截图:
第一次尝试 enter image description here 第二次尝试 enter image description here这是我的JSON文件的摘录
[{
"ConsoPhot_Id": "10148",
"idLotImport": 390,
"Date_Id": 20170201,
"Orga_Id": "203938",
"NbTache": 153,
"NbCopie": 798,
"NbCopieBW": 488,
"NbCopieCouleur": 310,
"MtTotal": 13.69
},
{
"ConsoPhot_Id": "10602",
"idLotImport": 391,
"Date_Id": 20161201,
"Orga_Id": "203938",
"NbTache": 153,
"NbCopie": 909,
"NbCopieBW": 779,
"NbCopieCouleur": 130,
"MtTotal": 7.93
},
{
"ConsoPhot_Id": "10905",
"idLotImport": 392,
"Date_Id": 20161101,
"Orga_Id": "203938",
"NbTache": 115,
"NbCopie": 515,
"NbCopieBW": 409,
"NbCopieCouleur": 106,
"MtTotal": 5.6
},
答案 0 :(得分:1)
每次选择选项时都不要附加新的SVG。
因此,而不是:
var myChart = d3.select('#chart').append('svg')
.attr('width', width + margin.right + margin.left)
.attr('height', height + margin.top + margin.bottom)
.append('g')
//etc...
简单地说:
var myChart = svg.append('g')
//etc...
以下是使用您提供的小型JSON示例进行更改的plunker:https://plnkr.co/edit/PMnNI4hoBz3Q2k5fQTp5?p=preview
PS:就像我在my comment中所说的那样,这个代码现在有很多问题,主要的一个事实是你要擦除SVG里面的所有东西只是为了再次绘制它,第二个每次选择选项时都要加载相同 JSON。话虽如此,您应该重新考虑此代码中的主要重构。请记住,我只是回答你问题中陈述的问题。