Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/408.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript D3.js条形图-轴和标签不工作/转换_Javascript_D3.js - Fatal编程技术网

Javascript D3.js条形图-轴和标签不工作/转换

Javascript D3.js条形图-轴和标签不工作/转换,javascript,d3.js,Javascript,D3.js,第一次使用D3.js。我一直在让条形图在条形图上显示值标签,并在数据刷新时转换x/y轴。我没有收到任何错误,代码来自于将几个示例放在一起。下面是代码,作为工作示例。在实际代码中,我使用d3.json提取数据,在jsfiddle中,我使用静态变量,仅供参考。感谢您的帮助 代码如下: var data; var margin = { top: 20, right: 0, bottom: 30, left: 30 }, width = 838 - margin.lef

第一次使用D3.js。我一直在让条形图在条形图上显示值标签,并在数据刷新时转换x/y轴。我没有收到任何错误,代码来自于将几个示例放在一起。下面是代码,作为工作示例。在实际代码中,我使用d3.json提取数据,在jsfiddle中,我使用静态变量,仅供参考。感谢您的帮助

代码如下:

var data;

var margin = {
    top: 20,
    right: 0,
    bottom: 30,
    left: 30
},
width = 838 - margin.left - margin.right,
    height = 300 - margin.top - margin.bottom;

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], 0.05);

var y = d3.scale.linear()
    .range([height, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .ticks(10);

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


d3.json("http://10.0.0.13/sma/sma-php/inverterdata.php?var=CDAY&id=C1200031", function (error, data) {
data.forEach(function (d) {
    d.max_energy = +d.max_energy;
});

x.domain(data.map(function (d) {
    return d.xaxis;
}));
y.domain([0, d3.max(data, function (d) {
    return d.max_energy;
})]);

svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis)
    .append("text")
    .attr("transform", "rotate(0)")
    .attr("y", 23)
    .attr("x", 340)
    .attr("dy", ".71em")
    .style("text-anchor", "bottom")
    .text("Timeline");

svg.append("g")
    .attr("class", "y axis")
    .call(yAxis)
    .append("text")
    .attr("transform", "rotate(0)")
    .attr("y", -15)
    .attr("x", -25)
    .attr("dy", ".71em")
    .style("text-anchor", "top")
    .text("Energy - KWh");

svg.selectAll(".bar")
    .data(data)
    .enter().append("rect")
    .attr("class", "bar")
    .attr("x", function (d) {
    return x(d.xaxis);
})
    .attr("width", x.rangeBand())
    .attr("y", function (d) {
    return y(d.max_energy);
})
    .transition().delay(function (d, i) {
    return i * 10;
}).duration(10)
    .attr("height", function (d) {
    return height - y(d.max_energy);
});

//Create labels
svg.selectAll("text")
    .data(data)
    .enter()
    .append("text")
    .text(function (d) {
    return parseFloat(Math.round(d.max_energy * 100) / 100).toFixed(1);
})
    .attr("x", function (d) {
    return x(d.xaxis) + x.rangeBand() / 2;
})
    .attr("y", function (d) {
    return height - y(d.max_energy) + 14;
})
    .attr("text-anchor", "middle")
    .attr("font-family", "sans-serif")
    .attr("font-size", "11px")
    .attr("fill", "black");

//});

//On click, update with new data            
d3.select("p").on("click", function () {

    // Get the data again
        d3.json("http://10.0.0.13/sma/sma-php/inverterdata.php?var=PDAY&id=P100023", function (error, data) {
    data.forEach(function (d) {
        d.max_energy = +d.max_energy;
    });

    // Scale the range of the data again 
    x.domain(data.map(function (d) {
        return d.xaxis;
    }));
    y.domain([0, d3.max(data, function (d) {
        return d.max_energy;
    })]);

    // Make the changes
    svg.selectAll(".bar") // change the bar
    .data(data) // Update the data within.
    .transition().delay(function (d, i) {
        return i / data.length * 1000;
    })
        .duration(500)
        .attr("x", function (d) {
        return x(d.xaxis);
    })
        .attr("y", function (d) {
        return y(d.max_energy);
    })
        .attr("width", x.rangeBand())
        .attr("height", function (d) {
        return height - y(d.max_energy);
    });

    //Update all labels
    svg.selectAll("text")
        .data(data).transition()
        .delay(function (d, i) {
        return i / data.length * 1000;
    })
        .duration(500)
        .text(function (d) {
        return parseFloat(Math.round(d.max_energy * 100) / 100).toFixed(1);
    })
        .attr("x", function (d, i) {
        return x(i) + x.rangeBand() / 2;
    })
        .attr("y", function (d) {
        return height - y(d.max_energy) + 24;
    });

    });

});
HTML:


这其实比你想象的要容易。您只需再次调用axis函数:

svg.select("g.x").call(xAxis);
svg.select("g.y").call(yAxis);
改变了JSFIDLE

要使标签正常工作,可以为这些文本元素指定一个特定的类,并相应地进行选择。默认情况下,D3根据索引匹配元素。也就是说,通过调用轴添加轴标签后,将选择这些标签并与数据匹配。因此,.enter选择将为空,不添加新标签


js也可以忽略这一点。

这实际上比你想象的要容易。您只需再次调用axis函数:

svg.select("g.x").call(xAxis);
svg.select("g.y").call(yAxis);
改变了JSFIDLE

要使标签正常工作,可以为这些文本元素指定一个特定的类,并相应地进行选择。默认情况下,D3根据索引匹配元素。也就是说,通过调用轴添加轴标签后,将选择这些标签并与数据匹配。因此,.enter选择将为空,不添加新标签


js这一点也可以忽略。

关于问题的第二部分:

标签没有正确显示,因为您只是使用selectAlltext来抓取标签。问题是轴上的记号标签也是文本元素,因此它们被选中并分配了数据,但没有包含在输入中。这也是更新数据时轴标签移出屏幕的原因,因为在这种情况下,您在所有元素上设置属性,而不仅仅是新元素

要修复:向条形标签添加一个类,并使用它专门选择它们:

svg.selectAll("text.barLabels") //use this selector in your update as well
    .data(data)
    .enter()
    .append("text")
    .classed("barLabels", true) //remember to actually add the class!
现在应该都能用了……差不多了

你也许可以自己解决这个问题,但是你的标签y定位功能没有考虑到你使用的是倒比例,所以标签最终都处于奇怪的位置。你也需要改变

.attr("y", function (d) {
    return height - y(d.max_energy) + 24;
});

因此,0.0标签的位置不会超出轴线;甚至

.attr("y", function (d,i) { 
    return Math.min(y(d.max_energy) + 24*(1+i%2), height);
})
这样,如果相邻标签对于条来说太宽,它们就不会重叠。i%2对于偶数只返回0,对于奇数只返回1;模运算符%返回整数除法的余数


最后一个版本是我在这里实现的:

关于问题的第二部分:

标签没有正确显示,因为您只是使用selectAlltext来抓取标签。问题是轴上的记号标签也是文本元素,因此它们被选中并分配了数据,但没有包含在输入中。这也是更新数据时轴标签移出屏幕的原因,因为在这种情况下,您在所有元素上设置属性,而不仅仅是新元素

要修复:向条形标签添加一个类,并使用它专门选择它们:

svg.selectAll("text.barLabels") //use this selector in your update as well
    .data(data)
    .enter()
    .append("text")
    .classed("barLabels", true) //remember to actually add the class!
现在应该都能用了……差不多了

你也许可以自己解决这个问题,但是你的标签y定位功能没有考虑到你使用的是倒比例,所以标签最终都处于奇怪的位置。你也需要改变

.attr("y", function (d) {
    return height - y(d.max_energy) + 24;
});

因此,0.0标签的位置不会超出轴线;甚至

.attr("y", function (d,i) { 
    return Math.min(y(d.max_energy) + 24*(1+i%2), height);
})
这样,如果相邻标签对于条来说太宽,它们就不会重叠。i%2对于偶数只返回0,对于奇数只返回1;模运算符%返回整数除法的余数


最后一个版本是我在这里实现的:

嗨,拉尔斯,谢谢!!!但你的jFIDLE链接不起作用。另外,为什么我的条形图标签没有出现?谢谢哎呀,对不起。不确定哪里出了问题-链接已修复。不知道你想要什么样的标签-像在?嗨,拉尔斯,再次感谢!是的,这是我从中提取代码的教程,但不幸的是,条形图上的值标签不起作用。我想把值放在每个条的顶部。再次感谢您抽出时间!啊,好吧,应该让@Larskothoff解释完。。。他的比我的简洁多了!原来的小提琴似乎已被删除。代码的相关部分在答案中。嗨,拉尔斯,谢谢!!!但你的jFIDLE链接不起作用。另外,为什么我的条形图标签没有出现?谢谢哎呀,对不起。不确定哪里出了问题-链接已修复。不知道你想要什么样的标签-像在?嗨,拉尔斯,再次感谢!是的,这是我从中提取代码的教程,但不幸的是,条形图上的值标签不起作用。我想要一个地方
每个条顶部的值。再次感谢您抽出时间!啊,好吧,应该让@Larskothoff解释完。。。他的比我的简洁多了!原来的小提琴似乎已被删除。代码的相关部分在答案中。你好,阿米莉亚,谢谢你的建议!真棒的帮助!你好,阿米莉亚,谢谢你的建议!真棒的帮助!