admin管理员组文章数量:1290452
I'm trying to make a basic line chart using a 1 dimensional array containing numeric elements.
chart.html
<svg id="svg"></svg>
graph.js
lineData = [10,15,20,25,30,35,40,35,30,25,20,15,10];
let svg = D3.select("#svg").attr('width', width).attr('height', height);
let chart = svg.append('g').classed('display', true).attr('transform', 'translate(' + this.padding.l + ', ' + this.padding.t + ')');
let x = D3.scaleLinear().domain([0, lineData.length]).range([0,width]);
let y = D3.scaleLinear().domain([0, D3.max(lineData)]).range([height, 0]);
let line = D3.line().x((d,i) => {return x(i);}).y((d) => {return y(d);}).curve();
chart.selectAll('.line').data([lineData]).enter().append('path').classed('line', true).attr('stroke', 'red').attr('d', (d) => {return line(d);});
and I keep getting this error: Error: <path> attribute d: Expected moveto path mand ('M' or 'm'), "[object Object]".
----------UPDATE (Un-simplified Angular Component)----------
bar-curve-chartponent.ts
import {Component, Input, OnInit, ViewChild} from '@angular/core';
import * as D3 from "d3";
import * as D3Tooltip from "d3-tip"
@Component({
selector: 'app-bar-curve-chart',
templateUrl: './bar-curve-chartponent.html',
styleUrls: ['./bar-curve-chartponent.css']
})
export class BarCurveChartComponent implements OnInit {
@ViewChild('svg') svg:any;
private chart:any;
private padding = {t:50, r:75, b:25, l:20};
private x:any;
private y:any;
// Change Any to Data Type
@Input('data') data:number[] = [5,10,15,20,25,30,35,30,25,20,15,10,5];
@Input('lineData') lineData:any = [10,15,20,25,30,35,40,35,30,25,20,15,10];
@Input('height') height:number = 700;
@Input('width') width:number = 700;
constructor() { }
ngOnInit() {
this.prep();
this._plot();
}
private prep():void {
let svg = D3.select(this.svg.nativeElement)
.attr('width', this.width)
.attr('height', this.height);
this.chart = svg.append('g')
.classed('display', true)
.attr('transform', 'translate(' + this.padding.l + ', ' + this.padding.t + ')');
this.x = D3.scaleLinear().domain([0, this.data.length]).range([0, this.width]);
this.y = D3.scaleLinear().domain([0, D3.max(this.data)]).range([this.height, 0]);
}
private _plot():void {
let line = D3.line()
.x((d,i) => {return this.x(i);})
.y((d) => {return this.y(d);}).curve();
console.log(line(this.lineData));
this.chart.selectAll('.line')
.data([this.lineData])
.enter()
.append('path')
.classed('line', true)
.attr('stroke', 'red')
.attr('d', (d) => {return line(d);});
}
}
bar-curve-chartponent.html
<svg #svg ></svg>
I'm trying to make a basic line chart using a 1 dimensional array containing numeric elements.
chart.html
<svg id="svg"></svg>
graph.js
lineData = [10,15,20,25,30,35,40,35,30,25,20,15,10];
let svg = D3.select("#svg").attr('width', width).attr('height', height);
let chart = svg.append('g').classed('display', true).attr('transform', 'translate(' + this.padding.l + ', ' + this.padding.t + ')');
let x = D3.scaleLinear().domain([0, lineData.length]).range([0,width]);
let y = D3.scaleLinear().domain([0, D3.max(lineData)]).range([height, 0]);
let line = D3.line().x((d,i) => {return x(i);}).y((d) => {return y(d);}).curve();
chart.selectAll('.line').data([lineData]).enter().append('path').classed('line', true).attr('stroke', 'red').attr('d', (d) => {return line(d);});
and I keep getting this error: Error: <path> attribute d: Expected moveto path mand ('M' or 'm'), "[object Object]".
----------UPDATE (Un-simplified Angular Component)----------
bar-curve-chart.ponent.ts
import {Component, Input, OnInit, ViewChild} from '@angular/core';
import * as D3 from "d3";
import * as D3Tooltip from "d3-tip"
@Component({
selector: 'app-bar-curve-chart',
templateUrl: './bar-curve-chart.ponent.html',
styleUrls: ['./bar-curve-chart.ponent.css']
})
export class BarCurveChartComponent implements OnInit {
@ViewChild('svg') svg:any;
private chart:any;
private padding = {t:50, r:75, b:25, l:20};
private x:any;
private y:any;
// Change Any to Data Type
@Input('data') data:number[] = [5,10,15,20,25,30,35,30,25,20,15,10,5];
@Input('lineData') lineData:any = [10,15,20,25,30,35,40,35,30,25,20,15,10];
@Input('height') height:number = 700;
@Input('width') width:number = 700;
constructor() { }
ngOnInit() {
this.prep();
this._plot();
}
private prep():void {
let svg = D3.select(this.svg.nativeElement)
.attr('width', this.width)
.attr('height', this.height);
this.chart = svg.append('g')
.classed('display', true)
.attr('transform', 'translate(' + this.padding.l + ', ' + this.padding.t + ')');
this.x = D3.scaleLinear().domain([0, this.data.length]).range([0, this.width]);
this.y = D3.scaleLinear().domain([0, D3.max(this.data)]).range([this.height, 0]);
}
private _plot():void {
let line = D3.line()
.x((d,i) => {return this.x(i);})
.y((d) => {return this.y(d);}).curve();
console.log(line(this.lineData));
this.chart.selectAll('.line')
.data([this.lineData])
.enter()
.append('path')
.classed('line', true)
.attr('stroke', 'red')
.attr('d', (d) => {return line(d);});
}
}
bar-curve-chart.ponent.html
<svg #svg ></svg>
Share
Improve this question
edited Sep 28, 2017 at 9:22
altocumulus
21.6k13 gold badges64 silver badges86 bronze badges
asked Sep 27, 2017 at 17:02
Zander RootmanZander Rootman
2,2082 gold badges19 silver badges29 bronze badges
4
- 1 Your code doesn't throw any error: jsfiddle/w6y91wek It's possible that, trying to simplify it, you eliminated the problem. Is that your real code? Please, share the code that actually causes an error. – Gerardo Furtado Commented Sep 27, 2017 at 23:01
- @GerardoFurtado sorry for the late response. It was like 2am when I asked this question. I've updated the answer, the real thing is an angular ponent using D3. – Zander Rootman Commented Sep 28, 2017 at 6:44
- 1 In that case I suggest you add the Angular tag to your question, because the D3 code has no problem. – Gerardo Furtado Commented Sep 28, 2017 at 6:47
- @GerardoFurtado I know I'm probably missing something exceptionally retarded. And I've added the TS Tag also, just in case, but I do see this error popup on google for D3 Related questions. – Zander Rootman Commented Sep 28, 2017 at 6:49
2 Answers
Reset to default 6You have an error in your definition of the line generator:
let line = D3.line()
.x((d,i) => {return this.x(i);})
.y((d) => {return this.y(d);}).curve();
If you use .curve()
without an argument, it acts as a getter:
If curve is not specified, returns the current curve factory, which defaults to curveLinear.
Therefore, line
is going to hold a reference to the curve factory instead of the line generator. If you want a curve factory other than the default d3.curveLinear, you need to pass it as a parameter, or you need to omit the call to .curve()
to get the line generator instead.
As an aside: the above statement can be simplified/beautified to:
let line = D3.line()
.x((d, i) => this.x(i))
.y(this.y);
In my case, I did not have same problem as OP, but I had same error message as OP. The OP was not passing an argument to curve(...)
, but I was not calling d3.line
as I should!
I was only calling d3.curveCatmullRom.alpha(0.5)
:
path.attr('d', d3.curveCatmullRomClosed.alpha(0.5))
Once I called d3.line().curve(...), as described in the documentation, it worked:
path.attr('d', d3.line().curve(d3.curveCatmullRom.alpha(0.5));
本文标签:
版权声明:本文标题:javascript - D3 Simple Line Chart: Error: <path> attribute d: Expected moveto path command ('M' or 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741500512a2382032.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论