Javascript 使用D3.Group在D3中进行组线绘制

Javascript 使用D3.Group在D3中进行组线绘制,javascript,d3.js,grouping,Javascript,D3.js,Grouping,我正在使用一个整洁的长数据结构,它有三列:date、ID、num_orders date ID num_orders "2018-08-22" 1 3 "2018-08-23" 7 1 "2018-08-23" 10 1 "2018-08-23" 17 1 "2018-08-23"

我正在使用一个整洁的长数据结构,它有三列:date、ID、num_orders

date          ID          num_orders
"2018-08-22"  1           3
"2018-08-23"  7           1
"2018-08-23"  10          1
"2018-08-23"  17          1
"2018-08-23"  19          1
.
.
.
我想使用D3.js为每个ID绘制一条线,其中日期和num_顺序分别作为x轴和y轴。我用它作为我正在做的事情的模型,但是在代码中,作者使用了嵌套函数,它不再在D3的v6中使用;现在使用的方法是分组。所以我现在的代码是:

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(d.date))
                                    .y(d => yScale(d.num_orders))
                                    (d.values);
                });
    } )

到目前为止,我可以让带有记号的轴显示出来,但是没有一行显示出来,这让我认为问题出在最终的svg中。我是D3的新手,所以对这个问题的任何指导都是非常感谢的。如果您对我的代码有任何全面的建议,我也欢迎您的建议。

尝试在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);
                });
    } )

d3.line只接受数组,而d.values是迭代器。 通过将其转换为数组,问题得以解决

注意,在代码段中,我删除了parseDate,因为我将数据生成为日期。 您很可能需要保留日期

常量边距={顶部:10,右侧:30,底部:30,左侧:60}; 常量宽度=1000-margin.left-margin.right; 常数高度=600-margin.top-margin.bottom; var x=d3.timedays新日期2020,06,01,新日期2020,10,30; vary=Array.from{length:x.length},Math.random.mapn=>Math.floorn*10+5; var data=x.mapv,i=>{ 返回{ 日期:五,, id:Math.floorMath.random*10+1, 订单数量:y[i] }; }; const svg=d3。选择“我的数据维” .append'svg' .attr'width',width+margin.left+margin.right .attr'height',height+margin.top+margin.bottom .附加“g” .attr'transform', `翻译${margin.left},${margin.top}`; const grouped_data=d3.groupdata,d=>d.id; parseDate=d3.timeParse“%Y-%m-%d”; 常量xScale=d3.scaleTime .domaind3.extentdata,d=>d.date .范围[0,宽度]; svg.append'g' .attr'transform','translate0,${height}` .calld3.axisBottomxScale; 常数yScale=d3.scaleLinear .domain[0,d3.maxdata,d=>d.num\u顺序] .范围[高度,0]; svg.append'g' .calld3.axisLeftyScale; 常量myColor=d3.scaleOrdinal .domain\u data.keys .范围3.schemeSet3; 常数线=d3.0线 .xd=>{return xScaled.date;} .yd=>yScaled.num_订单; svg.selectAll'.line' .datau数据 进来 .append'path' .attr'fill','none' .attr'stroke',d=>myclord[0] .attr“笔划宽度”,1.5 .attr'd',d=>lineArray.fromd.values[1];
您的建议绝对是一个好建议,我已经将其纳入了我的代码中。但它似乎并没有解决问题。太好了,这正是我想要的。一个简单的问题是,颜色的表现并不像预期的那样;他们的头发都变白了。我尝试使用类似的方法,即.attr'stroke',d=>mycolorary.fromd.keys,但它似乎不起作用…检查更新的代码段:.attr'stroke',d=>myclord[0]非常感谢,我不得不在分组的\u数据对象上使用forEach循环。这是一个更好的解决方案!整天都在寻找这个答案,直到现在!非常感谢你!!!