1

我是 Javascript 的新手,一直坚持为这个项目构建雷达/网络图。

雷达图

如图所示,该图是测量基础攻击、防御和耐力的三点雷达图。我希望在这些点之上覆盖一个三角形(或另一个多边形)以显示“雷达”的清晰形状:

.

此数据通过 API 调用并通过 SQLite 部署。API 需要键入特定的 ID 号才能生成相关的基本统计信息。

下面的代码形成了图表:

function getBaseStats(pokecharID) {
  var queryUrl = "/api/v1/base_stats";
  var int_pokeCharID = parseInt(pokecharID);

  let filteredStats = [];
  let statsList = [];
  statsList.length = 0;



 d3.json(queryUrl).then((data) => {
    filteredStats.push(
      data.filter((stat) => stat[0] === int_pokeCharID && stat[1] === "Normal")
    );

var base_attack = filteredStats[0][0][2];
var base_defense = filteredStats[0][0][3];
var base_stamina = filteredStats[0][0][4];

var w = 500,
  h = 500;

var colorscale = d3.scaleOrdinal(d3.schemeCategory10);

var d = [
  [
    { axis: "Base Attack", value: base_attack },
    { axis: "Base Defense", value: base_defense },
    { axis: "Base Stamina", value: base_stamina },
  ],
];

感谢所有和任何帮助!

编辑:添加了尝试创建多边形的代码。

    var area = d3.svg.area.radial()
.interpolate("cardinal-closed")
.angle(function(d) { return angle(d.time); })
.innerRadius(function(d) { return radius(d.y0); })
.outerRadius(function(d) { return radius(d.y0 + d.y); });
4

1 回答 1

0

有一个根据您的要求进行一些修改的示例:

const data = [
  {color: 'orange', values: [500, 400, 900]},
  {color: 'blue', values: [800, 200, 400]},
  {color: 'green', values: [300, 1000, 600]},
];

const svg = d3.select('svg');

const maxValue = 1000;
const radius = 150;
const center = {x: 250, y: 200};

const radialScale = d3.scaleLinear()
  .domain([0, maxValue]) 
  .range([radius, 0]) 
  
const axis = d3.axisRight()
  .scale(radialScale)
  .ticks(5)

svg.append('g')
  .attr('transform', `translate(${center.x},${center.y  - radius})`)
  .call(axis);

let val, angle;
for (val = 0; val <= maxValue; val += maxValue / 5) {
  const r = radialScale(val);
  svg.append('circle')
    .attr('cx', center.x)
    .attr('cy', center.y)
    .attr('r', r)
    .style('stroke', '#aaa')
    .style('fill', 'none');
}

const labels = ['Base Attack', 'Base Stamina', 'Base Defence'];
const anchors = ['middle', 'start', 'end'];
const shifts = [{x: 0, y: -15}, {x: 10, y: 15}, {x: -10, y: 15}];

for (let index = 0; index < labels.length; index++) {
  const angle = index * Math.PI * 2 / labels.length;
  const x = center.x + radius * Math.sin(angle);
  const y = center.y + radius * -Math.cos(angle);
  if (angle > 0) {
    svg.append('line')
        .attr('x1', center.x)
        .attr('y1', center.y)
        .attr('x2', x)
        .attr('y2', y)
        .style('stroke', '#000');
  }
  svg.append('text')
    .text(labels[index])
    .attr('text-anchor', anchors[index])
    .attr('dx', shifts[index].x)
    .attr('dy', shifts[index].y)
    .attr('x', x)
    .attr('y', y)
}

data.forEach(({color, values}, index) => {
    let path = '';
  for (let i = 0; i < values.length; i++) {
    const r = radius - radialScale(values[i]);
    console.log('V: ', values[i]);
    console.log('R: ', r);
    const angle = i * Math.PI * 2 / values.length;
    const x = center.x + r * Math.sin(angle);
    const y = center.y + r * -Math.cos(angle);
    path += `${i > 0 ? 'L' : 'M'} ${x},${y} `;
  }
  path += 'Z';
  svg.append('path')
    .attr('d', path)
    .style('stroke', color)
    .style('stroke-width', 3)
    .style('stroke-opacity', 0.6)
    .style('fill', color)
    .style('fill-opacity', 0.3)
  
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js"></script>
<svg width="500" height="400">
  
</svg>

于 2021-05-10T10:25:13.853 回答