Reputation: 75
I'm struggling with plotting a sigle line in Power BI custom visual. Reports in Power BI are written using TypeScript and d3.js v.3.0. I'm able to plot chart with axes, but the line doesn't appear. Using pure d3.js in HTML file is really easy, but it is hard to integrate it with TypeScript due to typings preservation.
While developing this code I have had several problems with typings. Code below almost works. Take a look at this snippet. Issue with typings arises, when at the bottom I delete 'any'.
Here is link to sandbox at CodePen: https://codepen.io/SuszonyDzik/pen/aBaJJQ
module powerbi.extensibility.visual {
export class Visual implements IVisual {
private target: HTMLElement;
private updateCount: number;
private svg: d3.Selection<SVGAElement>;
private host: IVisualHost;
private selectionManager: ISelectionManager;
//private xAxis: d3.Selection<SVGAElement>;
//private yAxis: d3.Selection<SVGAElement>;
private data = [
{date: "2011-10-01", close: 582.13},
{date: "2011-10-10", close: 303.00},
{date: "2011-10-20", close: 103.00},
{date: "2011-10-25", close: 143.00},
]
static Config = {
xScalePadding: 0.1,
solidOpacity: 1,
transparentOpacity: 0.5,
xAxisFontMultiplier: 0.04,
};
private margin = {top: 20, right: 30, bottom: 30, left: 80};
constructor(options: VisualConstructorOptions) {
this.host = options.host;
let svg = this.svg = d3.select(options.element)
.append('svg')
.classed('worksheet', true);
}
public update(options: VisualUpdateOptions) {
let width = options.viewport.width - this.margin.left - this.margin.right;
let height = options.viewport.height - this.margin.top - this.margin.bottom;
this.svg.attr({
width: width + this.margin.left + this.margin.right,
height: height + this.margin.top + this.margin.bottom
});
let parseDate = d3.time.format("%Y-%m-%d").parse;
let xScale = d3.time.scale()
.domain(this.data.map(function(d) { return parseDate(d.date); }))
.range([0, width])
let yScale = d3.scale.linear()
.domain([0, d3.max(this.data, function(d) { return d.close; })])
.range([height, 0]);
let xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(10)
let yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(10)
.innerTickSize(-width)
.outerTickSize(10)
.tickPadding(10)
let worksheet = d3.select(".worksheet")
.attr("width", width + this.margin.left + this.margin.right)
.attr("height", height + this.margin.top + this.margin.bottom);
// remove exsisting axis and bar
this.svg.selectAll('.axis').remove();
this.svg.selectAll('.bar').remove();
this.svg.selectAll('.chart').remove();
let chart = d3.select(".worksheet")
.append("g")
.attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")")
.attr("class", "chart")
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
chart.append("g")
.attr("class", "y axis")
.call(yAxis)
let line = d3.svg.line()
.x(function(d) { console.log(parseDate(this.data.date)); return xScale(parseDate(this.data.date)); })
.y(function(d) { return yScale(this.data.close); })
.interpolate("linear")
chart.append("path")
.datum(this.data)
.attr("class", "line")
.attr("d", <any> line)
}
public destroy(): void {
//TODO: Perform any cleanup tasks here
}
}
}
Power BI chart with axes but without line
Upvotes: 3
Views: 1918
Reputation: 46
Please change the code from
chart.append("path")
.datum(this.data)
.attr("class", "line")
.attr("d", <any> line)
To
chart.append("path")
.datum(this.data)
.attr("class", "line")
.attr("d", "M" + this.data.map((d)=> {
return xScale( parseDate(d.date)) + ',' + yScale(d.close);
}).join('L'))
And also from the below
let xScale = d3.time.scale()
.domain(this.data.map(function(d) { return parseDate(d.date); }))
.range([0, width])
to
let xScale = d3.time.scale()
.domain(d3.extent(this.data,function(d) { return parseDate(d.date); }))
.range([0, width])
I have modified the code and worked. Please find the output. Output
Upvotes: 1