如何限制在D3.js中显示的刻度数?

时间:2018-11-14 13:30:14

标签: javascript d3.js

我找到了一个例子。 http://jsfiddle.net/aWJtJ/8/,用于限制刻度数,但它使用的是D3.js版本3。我将代码转换为版本5,但没有得到相同的结果。它仅显示两个小节。完成小提琴:http://jsfiddle.net/pmLf095y/

// Margins, width and height.
var margin = {top: 20, right: 20, bottom: 30, left: 10},
    body_width = 500,
    width = body_width - margin.left - margin.right,
    height = 200 - margin.top - margin.bottom;

// Scales.
var x = d3.scaleTime().range([width/data.length/2, width-width/data.length/2]);
var y = d3.scaleLinear().range([height, 0]);

// Construct our SVG object.
var svg = d3.select(".system-efficiency").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// X-axis.
var xAxis = d3.axisBottom(x)
    .ticks(d3.timeMonth.every(1))
    .tickFormat(d3.timeFormat('%b %Y'));
svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

// Set scale domains.
x.domain(data.map(d => new Date(d.datestr)));
y.domain([0, d3.max(data, function(d) { return d.air_used; })]);

// Call x-axis.
d3.select(".x.axis")
    .transition().duration(1000)
    .call(xAxis);

// Draw bars.
var bars = svg.selectAll(".air_used")
    .data(data, function(d) { return d.datestr; });

bars.exit().remove();

bars.transition().duration(1000)
    .attr("x", function(d) { return x(d.date) - width/data.length/2; })
    .attr("width", width / data.length)
    .attr("y", function(d) { return y(d.air_used); })
    .attr("height", function(d) { return height - y(d.air_used);});

bars.enter().append("rect")
    .attr("class", "air_used")
    .attr("width", width / data.length)
    .attr("x", function(d) { return x(new Date(d.datestr)) - (width/data.length)/2; })
    .attr("y", height)
    .attr("height", 0)
    .transition().duration(1000)
    .attr("y", function(d) { return y(d.air_used); })
    .attr("height", function(d) { return height - y(d.air_used);}); 

2 个答案:

答案 0 :(得分:1)

要设置x域,您无需映射日期,而是查找日期范围。

x.domain(d3.extent(data, (d => new Date(d.datestr))));

更改的代码:

var data = [
    {
        "air_produced": 0.660985,
        "air_used": 0.342706,
        "datestr": "2012-12-01 00:00:00",
        "energy_used": 0.106402
    },
    {
        "air_produced": 0.824746,
        "air_used": 0.400776,
        "datestr": "2013-01-01 00:00:00",
        "energy_used": 0.250462
    },
    {
        "air_produced": 0.181898,
        "air_used": 0.003541,
        "datestr": "2013-02-01 00:00:00",
        "energy_used": 0.000582
    },
    {
        "air_produced": 1.096685,
        "air_used": 0.97719,
        "datestr": "2013-03-01 00:00:00",
        "energy_used": 0.923212
    },
    {
        "air_produced": 0.283379,
        "air_used": 0.241088,
        "datestr": "2013-04-01 00:00:00",
        "energy_used": 0.23381
    }
];

// Margins, width and height.
var margin = {top: 20, right: 20, bottom: 30, left: 10},
    body_width = 500,
    width = body_width - margin.left - margin.right,
    height = 200 - margin.top - margin.bottom;

// Scales.
var x = d3.scaleTime().range([width/data.length/2, width-width/data.length/2]);
var y = d3.scaleLinear().range([height, 0]);

// Construct our SVG object.
var svg = d3.select(".system-efficiency").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// X-axis.
var xAxis = d3.axisBottom(x)
    .ticks(d3.timeMonth.every(1))
    .tickFormat(d3.timeFormat('%b %Y'));

// Set scale domains.
x.domain(d3.extent(data, (d => new Date(d.datestr))));
y.domain([0, d3.max(data, function(d) { return d.air_used; })]);

svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")");
    
// Call x-axis.
d3.select(".x.axis")
    .transition().duration(1000)
    .call(xAxis);

// Draw bars.
var bars = svg.selectAll(".air_used")
    .data(data, function(d) { return d.datestr; });

bars.exit().remove();

bars.transition().duration(1000)
    .attr("x", function(d) { return x(d.date) - width/data.length/2; })
    .attr("width", width / data.length)
    .attr("y", function(d) { return y(d.air_used); })
    .attr("height", function(d) { return height - y(d.air_used);});

bars.enter().append("rect")
    .attr("class", "air_used")
    .attr("width", width / data.length)
    .attr("x", function(d) { return x(new Date(d.datestr)) - (width/data.length)/2; })
    .attr("y", height)
    .attr("height", 0)
    .transition().duration(1000)
    .attr("y", function(d) { return y(d.air_used); })
    .attr("height", function(d) { return height - y(d.air_used);});
.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.air_used {
  fill: steelblue;
}

.x.axis path {
  display: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div class="section system-efficiency">
    <h4>SYSTEM EFFICIENCY</h4>
</div>

希望这可以清除。

答案 1 :(得分:0)

以下行仅返回一个值[0],但我需要定义范围[0, ?]

x.domain(data.map(d => new Date(d.datestr)));

我改回原来的行:

x.domain(d3.extent(data, function(d) { return d.date; }));

完整代码:

// Margins, width and height.
var margin = {top: 20, right: 20, bottom: 30, left: 10},
    body_width = 600,
    width = body_width - margin.left - margin.right,
    height = 200 - margin.top - margin.bottom;

// Scales.
var x = d3.scaleTime().range([width / data.length / 2, width - width / data.length / 2]);
var y = d3.scaleLinear().range([height, 0]);

// Construct our SVG object.
var svg = d3.select(".system-efficiency").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// X-axis.
var xAxis = d3.axisBottom(x)
    .ticks(d3.timeMonth.every(1))
    .tickFormat(d3.timeFormat('%b %Y'));
svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

// Date parsing.
const parseDate = d3.timeParse("%Y-%m-%d %H:%M:%S");
data.forEach(function(d) {
    d.date = parseDate(d.datestr);
});

console.log(data);

// Set scale domains.
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function (d) {
    return d.air_used;
})]);

// Call x-axis.
d3.select(".x.axis")
    .transition().duration(1000)
    .call(xAxis);

// Draw bars.
var bars = svg.selectAll(".air_used")
    .data(data, function (d) {
        return d.datestr;
    });

bars.exit().remove();

bars.transition().duration(1000)
    .attr("x", function (d) {
        return x(d.date) - width / data.length / 2;
    })
    .attr("width", width / data.length)
    .attr("y", function (d) {
        return y(d.air_used);
    })
    .attr("height", function (d) {
        return height - y(d.air_used);
    });

bars.enter().append("rect")
    .attr("class", "air_used")
    .attr("width", width / data.length)
    .attr("x", function (d) {
        return x(d.date) - (width / data.length) / 2;
    })
    .attr("y", height)
    .attr("height", 0)
    .transition().duration(1000)
    .attr("y", function (d) {
        return y(d.air_used);
    })
    .attr("height", function (d) {
        return height - y(d.air_used);
    });

注意:我从一个stackoverflow问题中获取了v3示例,但现在找不到它可以引用。