0

can you help me?

I'm new in javascript. I have 2 arrays, x and y and my page fill this arrays with two options, the first one is with random numbers and the second is with inputs.

let numberX = [10, 22, 33];
let numberY = [34, 44, 9];

But i need an object like this:

let allData =
[{
    Rating:10,//x
    Count:20,//y
    Duration:0,//this number isn't needed
  }];

How can I transform 2 simple arrays in a structure like the object?

My HTML Code is:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Linear Regression</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css"/>
</head>

<body>
    <form action="" method="post">
        <input type="text" name="x1"  placeholder="Type x1">
        <input type="text" name="y1" placeholder="Type y1">
        <br>
        <input type="text" name="x2"  placeholder="Type x2">
        <input type="text" name="y2" placeholder="Type y2">
        <br>
        <input type="text" name="x3"  placeholder="Type x3">
        <input type="text" name="y3"  placeholder="Type y3">
        <br>
        <input type="text" name="x4"  placeholder="Type x4">
        <input type="text" name="y4"  placeholder="Type y4">
        <br>
        <input type="text" name="x5"  placeholder="Type x5">
        <input type="text" name="y5"  placeholder="Type y5">
        <br>
        <input type="text" name="x6"  placeholder="Type x6">
        <input type="text" name="y6"  placeholder="Type y6">
        <br>
        <input type="text" name="x7"  placeholder="Type x7">
        <input type="text" name="y7"  placeholder="Type y7">
        <br>
        <input type="text" name="x8"  placeholder="Type x8">
        <input type="text" name="y8"  placeholder="Type y8">
        <br>
        <input type="text" name="x9"  placeholder="Type x9">
        <input type="text" name="y9"  placeholder="Type y9">
        <br>
        <input type="text" name="x10"  placeholder="Type x10">
        <input type="text" name="y10"  placeholder="Type y10">
        <br>
        <button type="button" onclick="generateNumbers()">Plot Numbers</button>
        <button type="button" onclick="generateRandomNumbers()">Plot Random Numbers</button>
        </br></br></br></br>
        <div id="divTable"></div>
        <div id="divSVG"></div>
        <div id="title"></div>
            <text id="equation"></text>
            <div id="graph-wrapper">

              <div id="graph-wrapper-y">
                <text>Eje Y</text>
                <select id="graph-picklist-y" class="graph-picklist">
                  <option value="Rating" selected>Average Rating</option>
                  <option value="Count">Attendee Count</option>
                </select>
              </div>

              <div id="graph-wrapper-x">
                <text>Eje X</text>
                <select id="graph-picklist-x" class="graph-picklist">
                  <option value="Rating">Average Rating</option>
                  <option value="Count" selected>Attendee Count</option>
                </select>
              </div>
        </div>
      </body>

      <!--<script type="text/javascript" src="data.js"></script>-->
      <!--<script type="text/javascript" src="regression.js"></script>-->
     </form>

    <script type="text/javascript">
        function deleteDiv()
        {
            arrayTable = document.getElementById("divTable");
            contenedorSVG = document.getElementById("divSVG");

            father = arrayTable.parentNode;
            father.removeChild(arrayTable);

            mother = contenedorSVG.parentNode;
            mother.removeChild(contenedorSVG);

            createDiv();
        }

        function createDiv()
        {
            var divTable1 = document.createElement("div");
            var divDiagram = document.createElement("div");
            divTable1.setAttribute("id","divTable");
            divDiagram.setAttribute("id","divSVG");
            //midiv.innerHTML = "<p>Este es el contenido de mi div</p>";
            document.body.appendChild(divTable1);
            document.body.appendChild(divDiagram);
            //document.getElementById('donde lo quiero poner').appendChild(midiv);
        }
        function generateNumbers()
        {
            let dataset = [];
            var numbersX = [];
            var numbersY = [];
            for (let i = 1; i < 11; i++)
            {
                dataset.push([document.getElementsByName("x"+i)[0].value, document.getElementsByName("y"+i)[0].value]);
                numbersX.push(document.getElementsByName("x"+i)[0].value);
                numbersY.push(document.getElementsByName("y"+i)[0].value);
            }
            deleteDiv();
            generateTable(numbersX, numbersY);
            plotDispersionDiagram(dataset);
        }

        function generateRandomNumbers()
        {
            let dataset = [];
            var numbersX = [];
            var numbersY = [];
            let numDataPoints = 30;             //Number of dummy data points to create
            let xRange = Math.random() * 1000;  //Max range of new x values
            let yRange = Math.random() * 1000;  //Max range of new y values

            for (let c = 0; c < numDataPoints; c++) //Loop numDataPoints times
            {
                let newNumber1 = Math.round(Math.random() * xRange);    //New random integer
                let newNumber2 = Math.round(Math.random() * yRange);    //New random integer
                numbersX.push(newNumber1);
                numbersY.push(newNumber2);
                dataset.push([newNumber1, newNumber2]);         //Add new number to array
            }
            deleteDiv();
            generateTable(numbersX, numbersY);
            plotDispersionDiagram(dataset);
            combineArrayIntoObject(numbersX, numbersY);
        }

        function generateTable(numbersX, numbersY)
        {
            let table = document.createElement('table'); // Create table.
            table.setAttribute('class', 'article');// Apply CSS for table

            let renglon0 = table.insertRow(0);// Insert New Column for Row1 at index '0'.
            let ren0col1 = renglon0.insertCell(0);
            ren0col1.innerHTML = 'POINT NUMBER';
            let ren0col2 = renglon0.insertCell(1);
            ren0col2.innerHTML = 'X';
            let ren0col3 = renglon0.insertCell(2);
            ren0col3.innerHTML = 'Y';
            let div = document.getElementById('divTable');// Append Table into div.
            div.appendChild(table);

            for (let x = 0; x < numbersX.length; x++)
            {
                let renglonX = table.insertRow(x+1);// Agrega nuevo renglon en x+1
                let rencolX1 = renglonX.insertCell(0);
                rencolX1.innerHTML = x+1; // Agrega Nueva Columna a renglox en el indice 0.

                let rencolX2 = renglonX.insertCell(1);
                rencolX2.innerHTML = numbersX[x];// Agrega Nueva Columna a renglox en el indice 1.

                let rencolX3 = renglonX.insertCell(2);
                rencolX3.innerHTML = numbersY[x];// Agrega Nueva Columna a renglox en el indice 2.
                div.appendChild(table);
            }
        }

        function plotDispersionDiagram(dataset)
        {
            let w = 700;
            let h = 500;
            let padding = 60;
            //Create scale functions
            var xScale = d3.scale.linear()
                                 .domain([0, d3.max(dataset, function(d) { return d[0]; })])
                                 .range([padding, w - padding * 2]);

            var yScale = d3.scale.linear()
                                 .domain([0, d3.max(dataset, function(d) { return d[1]; })])
                                 .range([h - padding, padding]);

            var rScale = d3.scale.linear()
                                 .domain([0, d3.max(dataset, function(d) { return d[1]; })])
                                 .range([2, 5]);

            var formatAsPercentage = d3.format("0.1%");

            //Define X axis
            var xAxis = d3.svg.axis()
                              .scale(xScale)
                              .orient("bottom")
                              .ticks(5)
                              .tickFormat(formatAsPercentage);

            //Define Y axis
            var yAxis = d3.svg.axis()
                              .scale(yScale)
                              .orient("left")
                              .ticks(5)
                              .tickFormat(formatAsPercentage);

            //Create SVG element
            var svg = d3.select("#divSVG")
                        .append("svg")
                        .attr("width", w)
                        .attr("height", h);

            //Create circles

            svg.selectAll("circle")
               .data(dataset)
               .enter()
               .append("circle")
               .attr("cx", function(d) {
                    return xScale(d[0]);
               })
               .attr("cy", function(d) {
                    return yScale(d[1]);
               })
               .attr("r", function(d) {
                    return rScale(d[1]);
               });

            //Create labels
            svg.selectAll("text")
               .data(dataset)
               .enter()
               .append("text")
               /*.text(function(d) {
                    return d[2];
               })*/
               .text(function () {
                  arguments.callee.myStaticVar = arguments.callee.myStaticVar || 0;
                  arguments.callee.myStaticVar++;
                  return(arguments.callee.myStaticVar);
                })

               .attr("x", function(d) {
                    return xScale(d[0]);
               })
               .attr("y", function(d) {
                    return yScale(d[1]);
               })
               .attr("font-family", "sans-serif")
               .attr("font-size", "11px")
               .attr("fill", "red");

            svg.append("g") //Create X axis
                .attr("class", "axis")
                .attr("transform", "translate(0," + (h - padding) + ")")
                .call(xAxis);

            svg.append("g") //Create Y axis
                .attr("class", "axis")
                .attr("transform", "translate(" + padding + ",0)")
                .call(yAxis);
        }

        function combineArrayIntoObject(numbersX, numbersY, allData) {
           //let    allData = [];
           let maxLen = numbersX.length > numbersY.length ? numbersX.length : numbersY.length;
           let i = 0;
           while(i < maxLen) {
              let x = numbersX[i] ? numbersX[i]: 0;
              let y = numbersY[i] ? numbersY[i]: 0;
              allData.push({
                  Rating: x,
                  Count: y
            });
            i++;
         }

            return allData;
        }


        var parentId = "#graph-wrapper";
        var animDuration = 1000;
        var margin = {top: 20, right: 50, bottom: 50, left: 100};

        var width = $(parentId).width() - margin.left - margin.right,
            height = $(parentId).height()  - margin.top - margin.bottom;

        var xScale = d3.scale.linear()
            .range([0,width]);

        var yScale = d3.scale.linear()
            .range([height, 0]);

        var line = d3.svg.line();

        var xAxis = d3.svg.axis()
            .scale(xScale)
            .tickSize(-height)
            .tickPadding(8)
            .tickFormat(d3.round)
            .orient("bottom");

        var yAxis = d3.svg.axis()
            .scale(yScale)
            .tickSize(-width)
            .tickPadding(8)
            .orient("left");

        var svg = d3.select(parentId).append("svg")
              .attr("width", width + margin.left + margin.right)
              .attr("height", height + margin.top + margin.bottom)
              .attr("id","svg-parent")
            .append("g")
              .attr("id","graph-plane")
              .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + (height) + ")")
            .call(xAxis);

        svg.append("g")
            .attr("class", "y axis")
            .attr("transform", "translate("  +0+ ",0)")
            .call(yAxis);

        svg.append("path")
            .attr("class","trendline")
            .attr("stroke-width", 1)
            .style("stroke","steelblue")
            .style("fill","none");

        d3.selectAll(".graph-picklist").on("change",function(){
          updateChart(d3.select("#graph-picklist-x")[0][0].value,
                      d3.select("#graph-picklist-y")[0][0].value);
        });


        function getDimensions(x,y, allData){
          var returnX=[];
          var returnY=[];
          var returnPairs = [];
          allData.forEach(function(d){
            var pair = {x: d[x],y: d[y]};
            returnPairs.push(pair);
            returnX.push(d[x]);
            returnY.push(d[y]);
          });
          console.log(typeof(allData));
          return {x:returnX,y:returnY,pairs:returnPairs};
        }

        function updateTitle(x,y){
          //var title = d3.select("#title").text("Linear Regression: "+x+" vs "+y);
          var title = d3.select("#title").text("Regresión Lineal: x vs y");
        }

        // returns slope, intercept and r-square of the line
        //Pulled from http://bl.ocks.org/benvandyke/8459843
        function leastSquares(xSeries, ySeries) {
          var reduceSumFunc = function(prev, cur) { return prev + cur; };

          var xBar = xSeries.reduce(reduceSumFunc) * 1.0 / xSeries.length;
          var yBar = ySeries.reduce(reduceSumFunc) * 1.0 / ySeries.length;

          var ssXX = xSeries.map(function(d) { return Math.pow(d - xBar, 2); })
            .reduce(reduceSumFunc);

          var ssYY = ySeries.map(function(d) { return Math.pow(d - yBar, 2); })
            .reduce(reduceSumFunc);

          var ssXY = xSeries.map(function(d, i) { return (d - xBar) * (ySeries[i] - yBar); })
            .reduce(reduceSumFunc);

          var slope = ssXY / ssXX;
          var intercept = yBar - (xBar * slope);
          var rSquare = Math.pow(ssXY, 2) / (ssXX * ssYY);

          return [slope, intercept, rSquare];
        }
        //http://snipplr.com/view/37687/random-number-float-generator/
        function randomFloatBetween(minValue,maxValue,precision){
            if(typeof(precision) == 'undefined'){
                precision = 2;
            }
            return parseFloat(Math.min(minValue + (Math.random() * (maxValue - minValue)),maxValue).toFixed(precision));
        }

        //"draw" the line with many points respecting the calculated equation
        function calculateLineData(leastSquares,xRange,iterations){
          var returnData = [];
          for(var i=0; i<iterations; i++){
            var randomX = randomFloatBetween(xRange[0],xRange[1]);
            returnData.push({
              xVal:randomX,
              yVal: (randomX*leastSquares[0])+leastSquares[1]
            });
          }
          return returnData;
        }

        function updateChart(x,y){

          updateTitle(x,y);
          //Fetch data
          var records = getDimensions(x,y);

          //Reset scale
          yScale.domain(d3.extent(records.y));
          xScale.domain(d3.extent(records.x));

          //re-assign data (or assign new data)
          var selectedCircles = d3.select("#graph-plane")
                                  .selectAll(".circles")
                                  .data(records.pairs)

          //give a transition on the existing elements
          selectedCircles
            .transition().duration(animDuration)
            .attr("transform",function(d){return "translate("+xScale(d.x)+","+yScale(d.y)+")";})
            .style("fill","steelblue");

          //Append any new elements and transition them as well
          selectedCircles.enter()
                        .append("circle")
                        .attr("class","circles")
                        .attr("r",5)
                        .style("fill","steelblue")
                        .transition().duration(animDuration)
                        .attr("transform",function(d){return "translate("+xScale(d.x)+","+yScale(d.y)+")";});

          //Remove any dom elements which are no longer data bound
          selectedCircles.exit().remove();

          //Update Axes
          d3.select(parentId).select(".x.axis").transition().duration(animDuration).call(xAxis);
          d3.select(parentId).select(".y.axis").transition().duration(animDuration).call(yAxis);

          //Update Regression
          line.x(function(d) { return xScale(d.xVal); })
              .y(function(d) { return yScale(d.yVal); });

          var leastSquaresCoeff = leastSquares(records.x, records.y);
          var lineData = calculateLineData(leastSquaresCoeff,d3.extent(records.x),200);

          var trendline = d3.selectAll(".trendline")
                                .transition().delay(1000).duration(500)
                                .attr("d",line(lineData));

          d3.select("#equation").text(function(){
            return (leastSquaresCoeff[1]<0)?
              "y="+leastSquaresCoeff[0].toFixed(2)+"x"+
                  leastSquaresCoeff[1].toFixed(2)+" rSquared: "+
                  leastSquaresCoeff[2].toFixed(2)
                  :
              "y="+leastSquaresCoeff[0].toFixed(2)+"x"+"+"+
                  leastSquaresCoeff[1].toFixed(2)+" rSquared: "+
                  leastSquaresCoeff[2].toFixed(2);
          });
        }
        $( document ).ready(function() {
          updateChart("Count","Rating");
        });

    </script>
</body>

Uncaught TypeError: Cannot read property 'forEach' of undefined
    at getDimensions (main.html:340)
    at updateChart (main.html:403)
    at HTMLDocument.<anonymous> (main.html:459)
    at i (jquery.min.js:2)
    at Object.fireWith [as resolveWith] (jquery.min.js:2)
    at Function.ready (jquery.min.js:2)
    at HTMLDocument.K (jquery.min.js:2)
getDimensions @ main.html:340
updateChart @ main.html:403
(anonymous) @ main.html:459
i @ jquery.min.js:2
fireWith @ jquery.min.js:2
ready @ jquery.min.js:2
K @ jquery.min.js:2
main.html:267 Uncaught TypeError: Cannot read property 'push' of undefined
    at combineArrayIntoObject (main.html:267)
    at generateRandomNumbers (main.html:136)
    at HTMLButtonElement.onclick (main.html:44)

This code generate a dispersion diagram with d3, but when I tried to generate the linear regression diagram, the code fails with the function getDimensions because the function combineArrayIntoObject doesn't return the result well.

2
  • Your example is not clear enough. Can you write a complete example? Commented Aug 28, 2017 at 16:54
  • ^^^ is the first array ratings and the second counts? Commented Aug 28, 2017 at 16:55

6 Answers 6

1

The key assumption this implementation makes is that numberX and numberY are of equal length. You can adjust it to your needs. Creates an empty array, does a loop to push the data in the object format you laid out.

let numberX = [10, 22, 33];
let numberY = [34, 44, 9];

let allData = [];

for (let i=0; i < numberX.length; i++) {
  allData.push({
    Rating: numberX[i],
    Count: numberY[i],
    Duration: 0
  })
}

console.log(allData)
Sign up to request clarification or add additional context in comments.

Comments

1

A better functional approach to solve your problem you don't need same length array if no value found it will assign 0 and will take only the maxlength of both array

function combineArrayIntoObject(arr1, arr2) {
   let result = [];
   let maxLen = arr1.length > arr2.length ? arr1.length : arr2.length;
   let i = 0;
   while(i < maxLen) {
      let x = arr1[i] ? arr1[i]: 0;
      let y = arr2[i] ? arr2[i]: 0;
      result.push({
          Rating: x,
          Count: y
    });
    i++;
 }

 return result;
}

let x = [10, 22, 33];
let y = [34, 44, 9];

console.log(combineArrayIntoObject(x,y));

Comments

0

Maybe something like this:

let xObject = {};
xObject.Rating = numberX[0];
xObject.Count = numberX[1];
xObject.Duration= numberX[2];
allData.push(xObject);

Comments

0

For geting an array with objects, you could map the values in a new object.

var numberX = [10, 22, 33],
    numberY = [34, 44, 9],
    allData = numberX.map((Rating, i) =>({ Rating, Count: numberY[i], Duration: 0 }));

console.log(allData);

Comments

0
let allData = [];
for (let i = 0; i < numberX.length; i++){
    allData.push({
       Rating: numberX[i], 
       Count: numberY[i]
    })
}

Or, here is another variant:

let allData = numberX.map((item, index) => {
    return {
        Rating: item,
        Count: numberY[index]
    }
})

Comments

0

let numberX = [10, 22, 33];
var numberY = [34, 44, 9];
const result = numberX.reduce((acc, val, i) => {
  acc.push({
    Rating: val,
    Count: numberY[i],
    Duration: 0
  })
  return acc;
}, []);
console.log(result)

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.