Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.7k views
in Technique[技术] by (71.8m points)

javascript - d3.max() not returning the max value in an array?

I've been teaching myself d3 overnight and can't seem to figure out this one issue I am having. I am dynamically feeding the d3.max() method an array of numbers (I have tried parsing them with parseInt()/parseFloat() as well as not parsing them) through an HTML <select> element. I am using the console to check the values as my visualizations are becoming skewed. However, sometimes it does return the max value, and sometimes it just doesn't.

var localityElectricityConsumption = localities[localityName].totalElectricityConsumption;
            maxConsumption = d3.max(localityElectricityConsumption);
            r = d3.scale.linear().domain([0, maxConsumption]).range([120, 0]);

            console.log("array being fed to d3.max: " + localityElectricityConsumption);
            console.log("what d3.max() is returning: " + d3.max(localityElectricityConsumption));
            console.log("what parseInt(d3.max()) is returning: " + d3.max(localityElectricityConsumption));

You can see the live visualization and check the console here. Try using the top-most graph to switch from the North American locality to the Mexico locality. d3.max() returns the max value for North America, but not Mexico, and therefore doesn't graph the data correctly for Mexico. I am officially stumped. Any help would be appreciated.

EDIT:

Here is the code that is used to create localities[localityName].totalElectricityConsumption:

 d3.csv("data/" + dataset, function (data) {

            for (var i = 0; i < data.length; i++) {

                var record = data[i];

                if (dataset === "total_electricity_consumption.csv") {
                    currentDataset = listOfDatasets[0].name;
                    record.totalElectricityConsumption = [];

                    // loop through all years, from 1980 to 2012
                    for (var year = 1980; year <= 2012; year++) {
                        var value = record[year];

                        // deal with missing data points
                        if (value === '--') {
                            value = 0;
                        }
                        else if (value === 'NA') {
                            value = 0;
                        }
                        else if (value === '(s)') {
                            value = 0;
                        }
                        else if (value === 'W') {
                            value = 0;
                        }

                        // add record of current total electricity consumption
                        record.totalElectricityConsumption.push(value);
                    }
                }

// create a list of country names
                localities[record.Locality] = record;
                listOfLocalities.push(record.Locality);
                }
}

Sorry, formatting is not perfect as I had to take some stuff out to make the code more readable for Stack Overflow.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

As expected, d3.max() is indeed returning the maximum value... however, it is returning the maximum value among strings, not among numbers.

The explanation is that, by default, d3.csv() will load all the values as strings, even if they are numbers. Therefore, when you do:

var value = record[year];

value is a string, not a number. And in JavaScript the maximum for an array of strings is different from the maximum for an array of numbers. For instance, using numbers:

var myArray = [1, 65, 9, 32, 42];
console.log(d3.max(myArray));
<script src="https://d3js.org/d3.v4.min.js"></script>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...