Skip to content Skip to sidebar Skip to footer

Group Line Plotting In D3 With D3.group

I am working with a tidy-long data structure with three columns: date, ID, num_orders. date ID num_orders '2018-08-22' 1 3 '2018-08-23' 7 1

Solution 1:

d3.line() is accepting arrays only, while d.values() is an iterator. By converting it into an array the problem is solved.

Notice that, on the snippet I removed the parseDate because I am generating data as Dates. You most likely will need to keep the parseDate

const margin = { top: 10, right: 30, bottom: 30, left: 60 };
const width = 1000 - margin.left - margin.right;
const height = 600 - margin.top - margin.bottom;

var x = d3.timeDays(newDate(2020, 06, 01), newDate(2020, 10, 30));
var y = Array.from({length: x.length}, Math.random).map(n =>Math.floor(n * 10) + 5);
var data = x.map((v, i) => {
  return {
    "date": v,
    "id": Math.floor(Math.random() * (10 + 1)),
    "num_orders": y[i]
  };
});

const svg = d3.select('#my_dataviz')
    .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})`);


const grouped_data = d3.group(data, d => d.id);

parseDate = d3.timeParse('%Y-%m-%d');

const xScale = d3.scaleTime()
                .domain(d3.extent(data, d => d.date))
                .range([0, width]);
svg.append('g')
    .attr('transform', `translate(0, ${height})`)
    .call(d3.axisBottom(xScale));

const yScale = d3.scaleLinear()
                .domain([0, d3.max(data, d => d.num_orders)])
                .range([height, 0]);
svg.append('g')
    .call(d3.axisLeft(yScale));

const myColor = d3.scaleOrdinal()
                    .domain(grouped_data.keys())
                    .range(d3.schemeSet3);

const line = d3.line()
              .x(d => { returnxScale(d.date); })
              .y(d =>yScale(d.num_orders));

svg.selectAll('.line')
    .data(grouped_data)
    .enter()
    .append('path')
        .attr('fill', 'none')
        .attr('stroke', d =>myColor(d[0]))
        .attr('stroke-width', 1.5)
        .attr('d', (d) =>line(Array.from(d.values())[1]));
   
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/d3/6.5.0/d3.min.js"></script><divid="my_dataviz"></div>

Solution 2:

Try to parse the data on the line generator

const margin = { top: 10, right: 30, bottom: 30, left: 60 };
const width = 1000 - margin.left - margin.right;
const height = 600 - margin.top - margin.bottom;

const svg = d3.select('#my_dataviz')
    .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})`);
                
d3.json("./data.json")
    .then( function(data) {        
        const grouped_data = d3.group(data, d => d.ID);

        parseDate = d3.timeParse('%Y-%m-%d')
        const xScale = d3.scaleTime()
                        .domain(d3.extent(data, d =>parseDate(d.date)))
                        .range([0, width]);
        svg.append('g')
            .attr('transform', `translate(0, ${height})`)
            .call(d3.axisBottom(xScale));
        
        const yScale = d3.scaleLinear()
                        .domain([0, d3.max(data, d => d.num_orders)])
                        .range([height, 0]);
        svg.append('g')
            .call(d3.axisLeft(yScale));

        const myColor = d3.scaleOrdinal()
                            .domain(grouped_data.keys())
                            .range(d3.schemeSet3);
        
        svg.selectAll('.line')
            .data(grouped_data)
            .enter()
            .append('path')
                .attr('fill', 'none')
                .attr('stroke', d =>myColor(d.keys))
                .attr('stroke-width', 1.5)
                .attr('d', function(d){
                                return d3.line()
                                    .x(d =>xScale(parseData(d.date)))
                                    .y(d =>yScale(d.num_orders))
                                    (d.values);
                });
    } )

Post a Comment for "Group Line Plotting In D3 With D3.group"