skip to Main Content

Im trying to create a multiline graphic whith D3, in body I have this Line:

<svg id="lineChart1" width="600" height="400"></svg>

this is the js code:

  function getRandomColor() {
      const r = Math.floor(Math.random() * 256);
      const g = Math.floor(Math.random() * 256);
      const b = Math.floor(Math.random() * 256);
      return `rgb(${r},${g},${b})`;
  }

 

  function createChartD3(selector, labels, datasets) {
      const svg = d3.select(selector);
      const margin = { top: 20, right: 30, bottom: 30, left: 40 };
      const width = +svg.attr('width') - margin.left - margin.right;
      const height = +svg.attr('height') - margin.top - margin.bottom;

      const x = d3.scaleTime()
          .domain(d3.extent(labels))
          .range([0, width]);
     

      const y = d3.scaleLinear()
          .domain([0, d3.max(datasets, d => d3.max(d.values))])
          .nice()
          .range([height, 0]);

      const line = d3.line()
          .x((d, i) => x(labels[i]))
          .y(d => y(d));

      const g = svg.append('g')
          .attr('transform', `translate(${margin.left},${margin.top})`);

      
      g.append('g')
          .attr('transform', `translate(0,${height})`)
          .call(d3.axisBottom(x));

      
      g.append('g')
          .call(d3.axisLeft(y));

      
      datasets.forEach(dataset => {
          g.append('path')
              .datum(dataset.values)
              .attr('class', 'line')
              .attr('d', line)
              .attr('stroke', getRandomColor())
              .attr('fill', 'none');
      });
  }

this is what I’m passing to function:
selector:’lineChart1′

label is an array of dates
[‘2024-10-13T09:40:06’,
‘2024-10-13T09:40:21’,
‘2024-10-13T09:40:36]

datasest is an array of object whith this props {label:’string’, value:’Array’}

es:
[{label:’CH_01′, values:[7287.385, 7510.846, 7590.083, 7544.071, 7681.146, 7467.861, 7432.631, 7392.977]},
[{label:’CH_02′, values: [3871.76, 4000.862, 4106.523, 4124.878, 4145, 3944.293, 4054.519, 4048.956, 3970.813, 4017.163, 4116.421]}] I have a lot of data two minutes contains approx 5600 record so 5600 dates as label and 5600 values in each array(values) in dataset multiplied 14 times (there are 14 objetcts in datasets)

I tryied to change some values but I don’t understand what is wrong

2

Answers


  1. Your x-scale is a time scale but you are giving it an array of strings not dates. You need to convert those strings to JavaScript date objects. Use timeParse if the date/times are local or utcParse if in UTC.

    const tp = d3.timeParse("%Y-%m-%dT%H:%M:%S")
    labels = labels.map(label => tp(label));
    
    Login or Signup to reply.
  2.  // Sample label and dataset
            const labels = ['2024-10-13T09:40:06', '2024-10-13T09:40:21', '2024-10-13T09:40:36'];
            const datasets = [
                {
                    label: 'CH_01',
                    values: [7287.385, 7510.846, 7590.083]
                },
                {
                    label: 'CH_02',
                    values: [3871.76, 4000.862, 4106.523]
                }
            ];
    
            // Function to generate a random color
            function getRandomColor() {
                const r = Math.floor(Math.random() * 256);
                const g = Math.floor(Math.random() * 256);
                const b = Math.floor(Math.random() * 256);
                return `rgb(${r},${g},${b})`;
            }
    
            // Function to create a multiline chart with D3
            function createChartD3(selector, labels, datasets) {
                const svg = d3.select(selector);
                const margin = { top: 20, right: 30, bottom: 30, left: 40 };
                const width = +svg.attr('width') - margin.left - margin.right;
                const height = +svg.attr('height') - margin.top - margin.bottom;
    
    
                // X scale: time scale
                const x = d3.scaleTime()
                    .domain(d3.extent(labels, d=> new Date(d)))
                    .range([0, width]);
                
                // Y scale: linear scale for datasets' values
                const y = d3.scaleLinear()
                    .domain([0, d3.max(datasets, d => d3.max(d.values))])
                    .nice()
                    .range([height, 0]);
    
                // Line generator function
                const line = d3.line()
                    .x((d, i) => x(new Date(labels[i])))
                    .y(d => y(d));
    
                // Group for chart content
                const g = svg.append('g')
                    .attr('transform', `translate(${margin.left},${margin.top})`);
    
                // X-axis
                g.append('g')
                    .attr('transform', `translate(0,${height})`)
                    .call(d3.axisBottom(x));
    
                // Y-axis
                g.append('g')
                    .call(d3.axisLeft(y));
    
                // Plot each dataset's line
                datasets.forEach(dataset => {
                    g.append('path')
                        .datum(dataset.values)
                        .attr('class', 'line')
                        .attr('d', line)
                        .attr('stroke', getRandomColor())
                        .attr('fill', 'none');
                });
            }
    
            // Call the function to create the chart
            createChartD3('#lineChart1', labels, datasets);
      .line {
                fill: none;
                stroke-width: 2px;
            }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js"></script>
    <svg id="lineChart1" width="600" height="400"></svg>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search