0 votes
1 view
in BI by (14.1k points)

I'm struggling with plotting a single 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. The code below almost works. Take a look at this snippet. The 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 

1 Answer

0 votes
by (39.1k points)
  • 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 change this code 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])

  • Output

image

Welcome to Intellipaat Community. Get your technical queries answered by top developers !


Categories

...