0

I'm trying to create a multi line chart with dual y axes , I've tried running the code in powerbi d3.js visual , but is not yielding any visual. I'm not understanding where I've made the mistake

I want to create a multi line chart , where x axes has the time , one y axes is force , another y axes is temperature.Time should be in the format HH:MM:SS on the x axes

This is the base chart I've created using html enter image description here

So for each metal , I need to plot the line for force and a line for temperature for each time interval ,the result line chart format should be somewhat like in the image enter image description here

Dummy Data:

Metal Force Temperature Time
Silver 55 22 15:30:01
Copper 43 67 15:30:01
gold 61 99 15:30:01
diamond 31 47 15:30:01
indium 88 19 15:30:01
Silver 51 61 15:30:02
Copper 37 26 15:30:02
gold 49 81 15:30:02
diamond 26 41 15:30:02
indium 15 15:30:02
Silver 34 77 15:30:03
Copper 93 58 15:30:03
gold 29 36 15:30:03
diamond 64 57 15:30:03
indium 72 15:30:03

Below is the code. When I run the code I'm getting a blank space as in the image enter image description here

var margin = { top: 20, right: 20, bottom: 30, left: 40 },
    width = pbi.width - margin.left - margin.right,
    height = pbi.height - margin.top - margin.bottom;

var parseTime = d3.time.format("%H:%M:%S").parse;

// Scales
var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);

// Axis
var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(d3.time.seconds, 1).tickFormat(d3.time.format("%H:%M:%S"));
var yAxis = d3.svg.axis().scale(y).orient("left");

// Line generators
var lineForce = d3.svg.line()
    .x(function(d) { return x(d.Time); })
    .y(function(d) { return y(d.Force); });

var lineTemp = d3.svg.line()
    .x(function(d) { return x(d.Time); })
    .y(function(d) { return y(d.Temperature); });

var svg = d3.select("#chart")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

pbi.dsv(function(data) {
    // Convert Time to Date object and parse Force and Temperature as numbers
    data.forEach(function(d) {
        d.Time = parseTime(d.Time);
        d.Force = +d.Force;
        d.Temperature = d.Temperature ? +d.Temperature : null;  // Handle null values
    });

    var metals = Array.from(new Set(data.map(function(d) { return d.Metal; })));

    var colorScale = d3.scale.category10()
        .domain(metals);

    x.domain(d3.extent(data, function(d) { return d.Time; }));  // Use extent for min and max
    y.domain([0, d3.max(data, function(d) { return Math.max(d.Force, d.Temperature || 0); })]);  // Combined domain, handling nulls

    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis)
        .append("text")
        .attr("x", width / 2)
        .attr("y", margin.bottom - 10)
        .attr("fill", "#000")
        .attr("text-anchor", "middle")
        .text("Time");

    svg.append("g")
        .attr("class", "y axis")
        .call(yAxis)
        .append("text")
        .attr("transform", "rotate(-90)")
        .attr("y", -margin.left + 10)
        .attr("x", -height / 2)
        .attr("dy", "0.71em")
        .attr("text-anchor", "middle")
        .text("Force/Temperature");  // Combined axis label

    metals.forEach(function(metal) {
        var metalData = data.filter(function(d) { return d.Metal === metal; });

        svg.append("path")
            .datum(metalData.filter(function(d) { return d.Force !== null; }))
            .attr("fill", "none")
            .attr("stroke", colorScale(metal))
            .attr("class", "line-force " + metal)
            .attr("stroke-width", 1.5)
            .attr("d", lineForce);

        svg.append("path")
            .datum(metalData.filter(function(d) { return d.Temperature !== null; }))
            .attr("fill", "none")
            .attr("stroke", colorScale(metal + "-temp"))
            .attr("class", "line-temp " + metal)
            .attr("stroke-width", 1.5)
            .attr("d", lineTemp);
    });
});

2
  • Looks like you are mixing d3 versions: d3.scale.linear is v3 or earlier, d3.scaleTime is v4 or later for example. Commented Jul 7 at 12:07
  • I've changed scaletime to version3, as d3.time.scale() , still it's blank
    – Elysian
    Commented Jul 9 at 9:03

0

Browse other questions tagged or ask your own question.