D3.js图形显示错误

时间:2017-05-04 08:33:48

标签: javascript d3.js

我正在尝试运行数据可视化应用程序,我使用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
},

1 个答案:

答案 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。话虽如此,您应该重新考虑此代码中的主要重构。请记住,我只是回答你问题中陈述的问题。