D3.js行返回一个随机数

时间:2018-10-26 12:50:55

标签: javascript d3.js linechart

以我刚接触D3的事实开头,这可能是我所缺少的一个简单错误-我知道一定是这样。我正在尝试访问数据的方式。

试图弄清楚这个家伙一段时间。 (也许我看了太久了)

我一直玩到它,直到我的台词 finally 完全出现为止,但是现在它并没有显示完整的台词,只有两点-这是我不确定的数字。

谢谢!

编辑:目标是使用lineData [0]沿lineData 1(月)的x轴绘制一条线。最终,lineData 2将用于第二行,但此刻只是试图使第一行工作。

编辑:更新的代码(根据Shashank的建议)可以在这里找到: https://codepen.io/anon/pen/RevxYG?editors=0010

我更新的图形看起来更好,但仍然看到NaN值: enter image description here

这是我的代码:

 let lineData = [
    [4, 2, 0, 3, 3, 4, 52, 3, 0, 3, 3, 1], 
    [0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], 
    ["Oct", "Nov", "Dec", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep"]
  ]
            console.log("lineData", lineData)

        // set dimensions of the line chart
        let width = 393,
            height = 285;


        // set the scales
        let yScale = d3.scaleLinear()    
            .domain([0, 52])
            .range([height - 40 , 0]);

        let xScale = d3.scaleOrdinal()
            .range([0, width - 40]);

        // create the line
        let line = d3.line()
            .x(function(d, i) { return xScale(i); })
            .y(function(d) { return yScale(d[0]); });

        // create svg container
        let lineChart = d3.select(element)
            .append("svg")
            .attr("viewbox", "0 60 960 600")
            .attr("preserveAspectRatio", "xMinYMin meet")
            .attr("width", width)
            .attr("height", height)
            .attr("class", "line-chart")

        lineChart.append("path")
            .datum(lineData)
            .attr("d", line)
            .attr("fill", "none")
            .attr("stroke", "rebeccapurple")
            .attr("stroke-width", 2)

        lineChart.selectAll("dot")
            .data(lineData)
            .attr("d", line)
            .enter()
            .append("circle")
            .attr("r", 3.5)
            .attr("cx", function(d, i) { return xScale(i)})
            .attr("cy", function(d) { return yScale(d[0])})
            .attr("fill", "rebeccapurple")

        lineChart.append("g")
            .attr("transform", "translate(20, 245)")
            .call(d3.axisBottom(xScale))

        lineChart.append("g")
            .attr("transform", "translate(20, 0)")
            .call(d3.axisLeft(yScale))

数据正在通过函数传递。

数据为: enter image description here

,我的图表如下所示: enter image description here

,生成的路径/点如下所示: enter image description here

1 个答案:

答案 0 :(得分:1)

遗漏点:

  1. 重要提示:理想情况下,当您要根据月份绘制线条时,最好使用d3 time scale。但是序数刻度也可以。我猜您在这里寻找d3.scaleBand
  

除了输出范围是连续的和数字的,带刻度类似于序数刻度。

为什么不使用d3.scaleOrdinal?这是一个示例:

let lineData = [
    [4, 2, 0, 3, 3, 4, 52, 3, 0, 3, 3, 1], 
    [0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], 
    ["Oct", "Nov", "Dec", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep"]
  ]

        let xScale = d3.scaleOrdinal().range(lineData[2])
            .domain(lineData[0]);
            
    console.log('domain is: ' + xScale.domain());
    console.log('range is: ' + xScale.range());
<script src="https://d3js.org/d3.v4.min.js"></script>

您会看到重复的值如何映射到对您的情况无济于事的月份,因此d3.scaleBand()(您也可以使用d3.scalePointRead more about it in this answer. < / p>

  1. 使用上述频段比例,您将通过以下方式将域设置为lineData[2]

    xScale = d3.scaleBand().domain(lineData[2])
    
  2. 未将转换应用于linecircles。因此,我附加了<g>容器以分别包含直线和圆并转换了这些组元素。例如:

    var dots = lineChart.append('g')
        .attr("transform", "translate(20, 0)");
    

下面的解决方案仅在将第一行添加到图表时回答此特定问题。正如您在评论中提到的那样,您最终将第二个元素添加为另一行时,path的选择将会更改

let lineData = [
    [4, 2, 0, 3, 3, 4, 52, 3, 0, 3, 3, 1], 
    [0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], 
    ["Oct", "Nov", "Dec", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep"]
  ]
        // set dimensions of the line chart
        let width = 393,
            height = 285;


        // set the scales
        let yScale = d3.scaleLinear()    
            .domain([0, 52])
            .range([height - 40 , 0]);

        let xScale = d3.scaleBand().domain(lineData[2])
            .rangeRound([0, width - 40]);

        // create the line
        let line = d3.line()
            .x(function(d, i) { 
            	return xScale(lineData[2][i]) + xScale.bandwidth()/2; 
            })
            .y(function(d) { return yScale(d); });

        // create svg container
        let lineChart = d3.select('body')
            .append("svg")
            .attr("viewbox", "0 60 960 600")
            .attr("preserveAspectRatio", "xMinYMin meet")
            .attr("width", width)
            .attr("height", height)
            .attr("class", "line-chart")

				var lineG = lineChart.append('g')
        	.attr("transform", "translate(20, 0)");
          
        lineG.append("path")
            .data(lineData)
            .attr("d", line)
            .attr("fill", "none")
            .attr("stroke", "rebeccapurple")
            .attr("stroke-width", 2)

			var dots = lineChart.append('g')
        	.attr("transform", "translate(20, 0)");
        dots.selectAll("dot")
            .data(lineData[0])
            .enter()
            .append("circle").classed('dot', true)
            .attr("r", 3.5)
            .attr("cx", function(d, i) { return xScale(lineData[2][i]) + xScale.bandwidth()/2})
            .attr("cy", function(d) { return yScale(d)})
            .attr("fill", "rebeccapurple")

        lineChart.append("g")
            .attr("transform", "translate(20, 245)")
            .call(d3.axisBottom(xScale))

        lineChart.append("g")
            .attr("transform", "translate(20, 0)")
            .call(d3.axisLeft(yScale))
<script src="https://d3js.org/d3.v4.min.js"></script>

建议:像对yScale [0,52]一样,将域设置为静态值不是一个好习惯。尝试使用d3.extentd3.min方法。

希望这会有所帮助。

编辑:当您尝试使用d3.scalePoint时,在line函数和圆圈中选择xScale值时犯了一个小错误。您需要在fn行中选择categories[i],如下所示:

.x(function(d, i) { 
     return xScale(categories[i]); 
 })

使用d3.scalePoint更新的代码段

let data = {
    'New': [4, 2, 0, 3, 3, 4, 52, 3, 0, 3, 3, 1], 
    'Terminated': [0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0]
  };
  let categories = ["Oct", "Nov", "Dec", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep"];
  
            let lineData = [data.New, data.Terminated, categories];

        
            // set dimensions of the line chart
            let width = 393,
                height = 285;

            // set the scales
            let yScale = d3.scaleLinear()    
                .domain([0, 60]).nice()
                .range([height - 40 , 0]);
        
            let xScale = d3.scalePoint()
                .domain(lineData[2].map(function(d, i) { return d; }))
                .range([0, width - 40]);
        
            // create the line
            let line = d3.line()
                .x(function(d, i) { 
                	return xScale(categories[i]); 
                })
                .y(function(d) { return yScale(d); });
        
            // create svg container
            let lineChart = d3.select('body')
                .append("svg")
                .attr("viewbox", "0 60 960 600")
                .attr("preserveAspectRatio", "xMinYMin meet")
                .attr("width", width)
                .attr("height", height)
                .attr("class", "line-chart")

				var lineG = lineChart.append('g')
        	.attr("transform", "translate(20, 0)");
            lineG.append("path")
                .datum(lineData)
                .attr("d", function(d) { return line(d[0]); })
                .attr("fill", "none")
                .attr("stroke", "rebeccapurple")
                .attr("stroke-width", 2)
          
            lineChart.selectAll("dot")
                .data(lineData[0])
                .enter()
                .append("circle")
                .attr("transform", "translate(20, 0)")
                .attr("r", 3.5)
                .attr("cx", function(d, i) { return xScale(categories[i])})
                .attr("cy", function(d) { return yScale(d)})
                .attr("fill", "rebeccapurple")
        
            lineChart.append("g")
                .attr("transform", "translate(20, 245)")
                .call(d3.axisBottom(xScale))

        
            lineChart.append("g")
                .attr("transform", "translate(20, 0)")
                .call(d3.axisLeft(yScale))
<script src="https://d3js.org/d3.v4.min.js"></script>

希望这也有帮助。