Ошибка: атрибут d: ожидаемое число, «M-6, NaNH0.5V20.5H-6»

#javascript #reactjs #svg #d3.js

#javascript #reactjs #svg #d3.js

Вопрос:

Я пытаюсь создать две линейные диаграммы с помощью d3 в react, но я продолжаю получать эту ошибку и не знаю, как ее решить. Предполагается, что линейные диаграммы должны быть составлены с указанием времени эпохи на оси X и значений работоспособности на оси yAxis(Disk_Free, Memory_Free).Я изменил значения набора данных на значения с плавающей запятой, но я думаю, что что-то не так со значениями времени. Я очень новичок в d3, поэтому любой совет был бы полезен.

Это мой набор данных

 [

 {
   Health_id: 1,
   Epoch_Time: 1603959168.903983,
   Disk_Free: '86.2',
   Memory_Free: '1555480576',
   
 },
 {
   Health_id: 2,
   Epoch_Time: 1603959183.331211,
   Disk_Free: '86.2',
   Memory_Free: '1552396288',
   
  },
  {
   Health_id: 3,
   Epoch_Time: 1603959197.5066514,
   Disk_Free: '86.2',
   Memory_Free: '1565560832',
   
},
{
   Health_id: 4,
   Epoch_Time: 1603959211.6641965,
   Disk_Free: '86.2',
   Memory_Free: '1602510848',
  
  },
{
   Health_id: 5,
   Epoch_Time: 1603959225.8478744,
   Disk_Free: '86.2',
   Memory_Free: '1594617856',
   
},
]
  

Мой код d3 для генерации строки выглядит следующим образом

  static getDerivedStateFromProps(nextProps, prevState){
    const { data } = nextProps; //This is where I accept the above dataset and I try creating the line charts with it

    if(!data){
        return {};
    }
    const xScale = d3.scaleTime().range([margin.left,width-margin.right]);
    const yScale = d3.scaleLinear().range([height-margin.botton,margin.top])
    
    //Set Domains on Scales

    const timeDomain = d3.extent(data, d=>(d.Epoch_Time*1000))
    const healthID = d3.extent(data, d=>(d.Health_id))
    xScale.domain(timeDomain)
    yScale.domain(healthID)
    
    //Create and use line generator to plot the line charts

    const lineGenerator = d3.line().x(d=>xScale((d.Epoch_Time*1000)))
    const lines = [

        {
            path:lineGenerator.y((d)=>yScale((d.Disk_Free)))(data)
        },
        {
            path:lineGenerator.y((d)=>yScale((d.Memory_Free)))(data)
        },
       
    ];
    return {lines, xScale, yScale};
}

render(){
    return(
        <div className="main-body">
            <h4 center>Line Chart Test</h4>
            <svg>
                <g>
                    {this.state.lines.map((d,i)=>{
                        if(i===0){
                            return <path d={d.path} fill="none" stroke="red" />
                        }
                        else{
                            return <path d={d.path} fill="none" stroke="blue" />
                        } 
           })}
                </g>
               
            </svg>
        </div>
    )
}}export default Chart;
  

Я не получаю никаких линейных диаграмм при запуске веб-сайта, и ошибка, которую он показывает, такова:

       Error: <path> attribute d: Expected number, 
      "….00000665251144,NaNL35.097628459…".
  

мой путь svg выглядит следующим образом:

  <path d="M35.00203802950035,NaNL102.09192541055444,NaNL168.70615737356852,NaNL235.2960961666892,NaNL301.9796416583058,NaNL368.6469772068924,NaNL435.1701408263458,NaNL01.790251499806,NaNL568.4943668788065,NaNL635.0026281969162,NaN" fill="none"stroke="red">
</path>
  

Комментарии:

1. У вашего yScale есть проблема — регистрация его домена и диапазона выявляет проблему. Диапазон [NaN,someNumber] — скорее всего, ваш объект margin не имеет свойства с именем botton : range([height-margin.botton,margin.top]) . Хотя, учитывая размер значений Memory_Free по сравнению с доменом, вы можете не получить искомую строку, как только диапазон масштаба будет фиксированным.

2. не могли бы вы предложить какие-либо советы о том, как правильно сгенерировать строку? Как я уже сказал, я очень новичок в этом, поэтому я не могу придумать никакой альтернативы.

3. Ну, если вы исправите опечатку в диапазоне (и преобразуете строки в числа, как показано ниже), вы хотя бы получите правильную строку без NaN s? Если это так, то это просто вопрос установки правильного домена, который является чем-то отдельным от ошибки, которую вы получаете.

4. Да, у меня есть допустимая строка, но домен не виден.

5. Хорошо — теперь мы можем посмотреть на домен. Домен равен [1,5] — значение 1 будет масштабироваться, чтобы быть равным первому значению в диапазоне, значение 5 будет масштабироваться, чтобы быть равным второму значению в диапазоне. Поскольку ваши данные находятся за пределами [1,5] для памяти и диска, ваша строка будет выведена за пределы вашего диапазона. Значительно, поскольку размер диска в ~ 16 раз превышает верхний предел диапазона шкалы, а объем памяти на порядки больше. Вероятно, вы захотите установить домен для каждой строки в своей настройке, используя разные масштабы, с доменом, равным d3.extent(data, function(d) { return d.PropertyBeingScaled })

Ответ №1:

Ваши значения Y Disk_Free и Memory_Free являются строками. Сначала вам нужно преобразовать их в числа с помощью, например parseFloat :

 lineGenerator.y((d) => yScale(parseFloat(d.Disk_Free)))(data)

// ...

lineGenerator.y((d) => yScale(parseFloat(d.Memory_Free)))(data)