d3js中的画线导致d3.v5.min.js:2错误: 属性d:预期数量

问题描述 投票:0回答:1

我有一个双y轴图表,我想在其中显示总得分的条形和一条平均得分的线。玩完之后,除了没有显示的那行,我已经完成了所有配置。

我收到控制台错误d3.v5.min.js:2 Error: <path> attribute d: Expected number, "MNaN,189.02173913…".因此,我认为lineFunction出了点问题,但我看不到,它应该返回x和y值来绘制线条。我用this page作为灵感

我已经检查了相似答案herehere的解决方案,但我的Average变量已经是一个数字,因此对于我来说似乎没问题。

我想念什么?

我的代码:

//// VERTICAL BAR CHART WITH SVG AND NAMES SINGLE X AND DUAL Y AXES
		// Create data array of values to visualize
		var dataArray = [{ "Player": "John Doe", "Points": 23, "Average": 4.5 }, { "Player": "Jane Doe", "Points": 13, "Average": 2.3 }, { "Player": "Mary Jane", "Points": 21, "Average": 1.5 }, { "Player": "Debasis Das", "Points": 14, "Average": 5.7 }, { "Player": "Nishant", "Points": 37, "Average": 5.9 }, { "Player": "Mark", "Points": 15, "Average": 6.2 }, { "Player": "Andrew", "Points": 18, "Average": 1.2 }, { "Player": "Simon", "Points": 34, "Average": 3.1 }, { "Player": "Lisa", "Points": 30, "Average": 9.2 }, { "Player": "Marga", "Points": 20, "Average": 7.8 }];

		// Create variable for the SVG
		var canvas = d3.select(".v5chart").append("g").attr("transform", "translate(20,30)");

		var canvasWidth = 500;


		var maxValue = d3.max(dataArray, function (d) { return d.Points; });
		var maxValue2 = d3.max(dataArray, function (d) { return d.Average; });
		//console.error("maxValue2:" + maxValue2);
		var canvasHeight = maxValue * 10;
		var canvasHeight2 = maxValue2 * 10;

		//make sure y-axes are equal in height
		if (canvasHeight > canvasHeight2) {canvasHeight2 = canvasHeight;}
		else if (canvasHeight < canvasHeight2) {canvasHeight = canvasHeight2;}

		var heightScale = d3.scaleLinear()
			.domain([0, d3.max(dataArray, function (d) { return d.Points; })])
			.range([canvasHeight, 0]); //use max value (37) * 10
		var y_axis = d3.axisLeft()
			.scale(heightScale);

		var heightScale2 = d3.scaleLinear()
			.domain([0, d3.max(dataArray, function (d) { return d.Average; })])
			.range([canvasHeight2, 0]); 
		var y_axis2 = d3.axisRight()
			.scale(heightScale2);



		//band settings x axis
		var xScale = d3.scaleBand()
			.domain(dataArray.map(function (d) { return d.Player; }))
			.range([0, canvasWidth]).padding([0.1]);
		var x_Axis = d3.axisBottom(xScale);

		// create bars
		canvas.selectAll("rect")
			.data(dataArray)
			.enter().append("rect")
			.attr("class", "bar")
			.attr("height", function (d, i) { return (d.Points * 10) })
			.attr("width", xScale.bandwidth())
			.attr("x", function (d, i) { return xScale(d.Player); })
			.attr("y", function (d, i) { return canvasHeight - (d.Points * 10) });

		// text for in vertical bars
		canvas.selectAll("text")
			.data(dataArray)
			.enter().append("text")
			.text(function (d) { return d.Points })
			.attr("text-anchor", "middle")
			.attr("class", "text")
			.attr("x", function (d, i) { return (xScale(d.Player) + xScale.bandwidth() / 2); })
			.attr("y", function (d, i) { return canvasHeight + 20 - (d.Points * 10) });




		var yScale = d3.scaleLinear()
			.domain([0, maxValue2]) // input 
			.range([canvasHeight2, 0]); // output

		var lineFunction = d3.line()
			.x(function (d, i) { return xScale(i); }) // set the x values for the line generator
			.y(function (d, i) { return yScale(d.Average); }) // set the y values for the line generator 
			.curve(d3.curveMonotoneX); // apply smoothing to the line
		
		// 4. Call the y axis in a group tag
		canvas.append("g")
			.attr("class", "y axis")
			.call(d3.axisRight(yScale)) // Create an axis component with d3.axisLeft
			.attr("transform", "translate(" + canvasWidth + ",0)")
			.append("text")
			.attr("fill", "#000")
			.attr("transform", "rotate(-90)")
			.attr("y", 6)
			.attr("dy", "-1em")
			.attr("text-anchor", "end")
			.text("Average");


		canvas.append("path")
			.attr("class", "line")
			.attr("d", lineFunction(dataArray));

canvas.selectAll(".dot")
    .data(dataArray)
    .enter().append("circle") // Uses the enter().append() method
    .attr("class", "dot") // Assign a class for styling
    .attr("cx", function (d, i) { return xScale(d.Player) })
    .attr("cy", function (d) { return yScale(d.Average) })
    .attr("r", 5)
    .on("mouseover", function (a, b, c) {
        console.log(a)
        //this.attr('class', 'focus')
    })
    .on("mouseout", function () { })
    .append("text")
    .attr("text-anchor", "middle")
    .text(function (d) {
        return d.Average;
    });
	 
		//y axis 1 settings
		canvas.append("g")
			.attr("transform", "translate(0,0)")
			.call(y_axis)
			.append("text")
			.attr("fill", "#000")
			.attr("transform", "rotate(-90)")
			.attr("y", 6)
			.attr("dy", "0.71em")
			.attr("text-anchor", "end")
			.text("Points");

		//x axis
		canvas.append("g")
			.attr("transform", "translate(0," + canvasHeight + ")")
			.call(x_Axis)
			.selectAll("text")
			.attr("x", 30)
			.attr("transform", function (d) {
				return "rotate(65)"
			});
/*Rectangle bar class styling*/
	.bar {
	  fill: #0080FF
	}
	.bar:hover {
	  fill: #003366
	}

	/*Text class styling*/
	.text {
	  fill: white;
	  font-family: sans-serif
	}


	/* Style the lines by removing the fill and applying a stroke */
	.line {
		fill: none;
		stroke: #ffab00;
		stroke-width: 3;
	}
	  
	.overlay {
	  fill: none;
	  pointer-events: all;
	}

	/* Style the dots by assigning a fill and stroke */
	.dot {
		fill: #ffab00;
		stroke: #fff;
	}
	  
	  .focus circle {
	  fill: none;
	  stroke: steelblue;
	}
<script src="https://d3js.org/d3.v5.min.js"></script>
	<svg class="v5chart" width="960" height="500"></svg>
javascript d3.js linechart
1个回答
0
投票

在d3的文档中;

domain中的第一个元素将被映射到第一个波段,第二个域的值到第二个带,依此类推。域值是从字符串值到索引内部存储在映射中;的然后,将所得的索引用于确定频段。因此,一个乐队标度的值必须可转换为字符串,并且已字符串化域值的版本唯一地标识对应的带。如果未指定domain,则此方法返回当前域。

但是在xScale函数中,您正在使用带Player键的dataArray映射值。我的意思是,如果您想从xScale函数中获取任何正确的数字,则必须将其与Player键(例如“ John Doe”,“ Jane Doe”等)一起使用。

总之,如果将line功能更改为这一功能,您将看到结果:

var lineFunction = d3.line()
        .x(function (d, i) { return xScale(d.Player); /*return xScale(i)*/ })
        .y(function (d, i) { return yScale(d.Average); })
        .curve(d3.curveMonotoneX);

我想,您想在此之后解决对齐问题。由您决定。

© www.soinside.com 2019 - 2024. All rights reserved.