Добавьте цвет к нескольким путям из массива точно таких же данных в D3. js - PullRequest
0 голосов
/ 11 февраля 2020

Вопрос, вероятно, вводит в заблуждение, но я не знал, как сказать это более точно. В основном мои данные выглядят следующим образом:

    {
        "pitcher": 547943,
        "pitch_type": "CH",
        "velo": 80.15329032258065,
        "hmov": 0,
        "vmov": 0,
        "name": "hyun-jin-ryu"
      },
    {
      "pitcher": 547943,
      "pitch_type": "CH",
      "velo": 80.15329032258065,
      "hmov": 12.729861677419354,
      "vmov": 5.4084,
      "name": "hyun-jin-ryu"
    },
    {
        "pitcher": 547943,
        "pitch_type": "CU",
        "velo": 72.77105263157895,
        "hmov": 0,
        "vmov": 0,
        "name": "hyun-jin-ryu"
      },
    {
      "pitcher": 547943,
      "pitch_type": "CU",
      "velo": 72.77105263157895,
      "hmov": -13.357961403508773,
      "vmov": -13.062238596491229,
      "name": "hyun-jin-ryu"
    }

Я хочу получить путь для каждого типа pitch_type, начиная с (hmov [0], vmov [0]) или 0,0 и заканчивая (hmov [ 1], вмов [1]). Я также создал цветовую шкалу, связанную с «вело», но не могу найти способ назначить ее для моей траектории. Я подозреваю, что это связано с наличием 2 значений вело, но я не могу точно сказать, в этом ли проблема.

    //Loop through each pitch    
    dataNest.forEach(function(d) { 
        svg.append("path")
            .data([data])
            .attr("d", pitchLine(d.values))
            .attr("stroke", function(d) { return veloScale(d); }) //Problematic part
            .attr("stroke-witdh", 2);
    });

Полный код:

const margin = {top: 25, bottom: 25, right: 25, left: 25};
const height = 300 - margin.top - margin.bottom;
const width = 300 - margin.left - margin.right;

//Set Ranges
let x = d3.scaleLinear().range([0, width]);
let y = d3.scaleLinear().range([height, 0]);
let veloScale = d3.scaleSequential(d3.interpolateViridis);


//Set line generator
let pitchLine = d3.line()
            .x(function(d) { return x(d.hmov); })
            .y(function(d) { return y(d.vmov); });

//Add SVG canvas
let svg = d3.select("body")
    .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
    .append("g")
        .attr("transform", 
              "translate(" + margin.left + "," + margin.top + ")");

///////////////////////////////

//Get the Data
d3.json("ryu.json").then(function(data) {
    data.forEach(function(d) {
        d.hmov = +d.hmov;
        d.vmov = +d.vmov;
        d.velo = +d.velo;
    });

    //Scales
    x.domain(d3.extent(data, function(d) { return d.hmov; }));
    y.domain(d3.extent(data, function(d) { return d.vmov; }));
    veloScale.domain(d3.extent(data, function(d) { return d.velo; }))

    //Nesting data
    let dataNest = d3.nest()
        .key(function(d) { return d.pitch_type; })
        .entries(data);

    //Loop through each pitch    
    dataNest.forEach(function(d) { 
        svg.append("path")
            .data([data])
            .attr("d", pitchLine(d.values))
            .attr("stroke", function(d) { return veloScale(d); })
            .attr("stroke-witdh", 2);
    });

1 Ответ

0 голосов
/ 12 февраля 2020

Раздел вашего кода, в котором вы * l oop просматриваете массив dataNest, должен быть обновлен так, чтобы

a) данные объединялись на правильном уровне, ie массив dataNest для создания каждого пути и d.values ​​для базовой точки пути.

b) функция цвета обводки передает значение из массива, который вы хотите отобразить, в цвет. Поскольку у вас могут быть разные значения вело для каждого элемента в массиве d.values, вам нужно будет решить, какой из них вы будете использовать. В приведенном ниже примере используется значение velo из первого элемента массива.

//Create a separate g element to contain the path, based on the nested array    
let pitch = svg.selectAll(".pitch-type")
            .data(dataNest)
            .enter()
            .append("g")
     //for each g element, add a path and assign the d.values for that path
        pitch.append("path")
          .datum(d => d.values)
          .attr("d", d => pitchLine(d))
//pass in the velo value to get a colour
          .attr("stroke", d => veloScale(d[0].velo))
          .attr("stroke-witdh", 2);

let data = [{
        "pitcher": 547943,
        "pitch_type": "CH",
        "velo": 80.15329032258065,
        "hmov": 0,
        "vmov": 0,
        "name": "hyun-jin-ryu"
      },
    {
      "pitcher": 547943,
      "pitch_type": "CH",
      "velo": 80.15329032258065,
      "hmov": 12.729861677419354,
      "vmov": 5.4084,
      "name": "hyun-jin-ryu"
    },
    {
        "pitcher": 547943,
        "pitch_type": "CU",
        "velo": 72.77105263157895,
        "hmov": 0,
        "vmov": 0,
        "name": "hyun-jin-ryu"
      },
    {
      "pitcher": 547943,
      "pitch_type": "CU",
      "velo": 72.77105263157895,
      "hmov": -13.357961403508773,
      "vmov": -13.062238596491229,
      "name": "hyun-jin-ryu"
    }]
    
    const margin = {top: 25, bottom: 25, right: 25, left: 25};
    const height = 300 - margin.top - margin.bottom;
    const width = 300 - margin.left - margin.right;

//Set Ranges
    let x = d3.scaleLinear().range([0, width]);
    let y = d3.scaleLinear().range([height, 0]);
    let veloScale = d3.scaleSequential(d3.interpolateViridis);


//Set line generator
let pitchLine = d3.line()
            .x(function(d) { return x(d.hmov); })
            .y(function(d) { return y(d.vmov); });

//Add SVG canvas
let svg = d3.select("body")
    .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
    .append("g")
        .attr("transform", 
              "translate(" + margin.left + "," + margin.top + ")");


    data.forEach(function(d) {
        d.hmov = +d.hmov;
        d.vmov = +d.vmov;
        d.velo = +d.velo;
    });

    //Scales
    x.domain(d3.extent(data, function(d) { return d.hmov; }));
    y.domain(d3.extent(data, function(d) { return d.vmov; }));
    veloScale.domain(d3.extent(data, function(d) { return d.velo; }))

    //Nesting data
    let dataNest = d3.nest()
        .key(function(d) { return d.pitch_type; })
        .entries(data);
    
   
    let pitch = svg.selectAll(".pitch-type")
    	.data(dataNest)
    	.enter()
    	.append("g")
 
    pitch.append("path")
      .datum(d => d.values)
      .attr("d", d => pitchLine(d))
      .attr("stroke", d => veloScale(d[0].velo))
      .attr("stroke-witdh", 2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...