将数组缩减为 return 分组数据,从学校到地方当局

Reducing an array to return grouped data from schools to local authorities

我有一些用于在页面上绘制 svg 圆圈的 JS 代码。圆圈基于学校数据,圆圈的大小取决于 SchoolCapacity 字段。问题是我的数组 schooldata 包含 100 多个元素,圆圈非常拥挤并且彼此重叠。我的问题是如何重写 process schools data 代码以显示地方当局 (LA (Name)) 和他们的学校能力圆圈代替。

学校数据数组:

const schooldata = [{
    "URN": 135691,
    "LA (code)": 938,
    "LA (name)": "West Sussex",
    "EstablishmentNumber": 6228,
    "EstablishmentName": "Seadown School",
    "SchoolCapacity": 30,
    "Postcode": "BN11 2BE"
  }, {
    "URN": 112080,
    "LA (code)": 908,
    "LA (name)": "Cornwall",
    "EstablishmentNumber": 6084,
    "EstablishmentName": "St Ia School",
    "SchoolCapacity": 45,
    "Postcode": "TR26 2SF"
  },
    {
    "URN": 130842,
    "LA (code)": 938,
    "LA (name)": "West Sussex",
    "EstablishmentNumber": 8003,
    "EstablishmentName": "Greater Brighton Metropolitan College",
    "SchoolCapacity": "",
    "Postcode": "BN12 6NU"
  },

JS 业务逻辑

  function getcoordinates(postcode) {
    let url = "https://api.getthedata.com/postcode/" + postcode.replace(" ", "+");
    try {
      return fetch(url).then(function(response) {
        return response.json(); // Process it inside the `then`
      });
    } catch (error) {
      console.log(error);
    }
  }
  //svg setup
  var svgns = "http://www.w3.org/2000/svg",
    container = document.getElementById('cont');
  
  function drawcircle(easting, northing, size, label, identifier) {
    var xScale = (container.width.baseVal.value - 20) / (700000);
    var x = 10 + (xScale * easting);
    var yScale = (container.height.baseVal.value - 20) / (700000);
    var y = 10 + (yScale * (700000 - northing));
    var sizeScale = 100;
    var radius = size / sizeScale;
  
    //draw or update the svg circle
    var circle = document.getElementById("Circle_" + identifier);
    if (circle == null) {
      circle = document.createElementNS(svgns, 'circle');
    }
    circle.setAttributeNS(null, 'id', "Circle_" + identifier);
    circle.setAttributeNS(null, 'cx', x);
    circle.setAttributeNS(null, 'cy', y);
    circle.setAttributeNS(null, 'r', radius);
    circle.setAttributeNS(null, 'style', 'fill: #c6605e; stroke: none; stroke-width: 1px;');
    container.appendChild(circle);
  
    //draw or update the circle label
    var newText = document.getElementById("Circle_Label_" + identifier);
    if (newText == null) {
      newText = document.createElementNS(svgns, "text");
      var textNode = document.createTextNode(label);
      newText.appendChild(textNode);
    }
    newText.setAttributeNS(null, 'id', "Circle_Label_" + identifier);
    newText.setAttributeNS(null, "x", x);
    newText.setAttributeNS(null, "y", y);
    newText.setAttributeNS(null, "font-size", "10");
    var textNode = document.createTextNode(label);
    newText.replaceChild(textNode, newText.childNodes[0]);
    container.appendChild(newText);
  }
  
  **//process schools data** -- TODO: change to LA instead of schools
  let schools = schooldata.reduce(function(allSchools, school) {
    allSchools[school.EstablishmentName] = {
      SchoolCapacity: school.SchoolCapacity || 0,
      coordinates: []
    };
    getcoordinates(school.Postcode).then(function(data) {
      allSchools[school.EstablishmentName].coordinates.push([data.data.easting, data.data.northing]);
      drawcircle(data.data.easting, data.data.northing, school.SchoolCapacity, school.EstablishmentName, school.URN);
    });
    return allSchools
  }, {});

HTML

<!DOCTYPE html>
<meta charset="utf-8">
          
<!-- Create an element where the map will take place -->
<svg id="cont" width="900" height="900"></svg>

我想我需要做一些数组缩减?

首先,使用 Array.reduce():

将您的学校缩减为地方当局
const locAuthorities = schooldata.reduce(function (prev, curr) {
  const laCode = curr["LA (code)"]
  const laName = curr["LA (name)"]
  if (prev[laCode]) {
    prev[laCode].SchoolCapacity += curr.SchoolCapacity || 0
  } else {
    prev[laCode] = {
      "LA (code)": laCode,
      "LA (name)": laName,
      "SchoolCapacity": curr.SchoolCapacity,
      "Postcode": curr.Postcode,
      "URN": curr.URN
    }
  }
  return prev
}, {})

const locAuthoritiesArray = Object.values(locAuthorities)

现在用localAuthoritiesArray画圆圈:

locAuthoritiesArray.forEach(function (la) {
  getcoordinates(la.Postcode).then(function (data) {
    drawcircle(
      data.data.easting,
      data.data.northing,
      la.SchoolCapacity,
      la["LA (name)"],
      la.URN
    );
  });
})