x-axis zooming with d3 line charts

2019-07-31 14:22发布

I'm just getting into using d3, and relatively novice in js still. I'm trying to set up a page of log file visualizations for monitoring some servers. Right now I'm focusing on getting a line chart of CPU utilization, where I can focus on specific time periods (So an x-zoom only). I am able to do a static charts easily, but when it comes to the zooming the examples are going over my head and I can't seem to make them work.

This is the static example I followed to get things up and running, and this is the zoom example I've been trying to follow.

My input csv is from a rolling set of log files (which will not be labled on the first row), each row looks like this:

datetime,server,cpu,memory,disk,network_in,network_out

So far what I've been able to get on the zoom looks like this:

var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;

// define dimensions of graph
var margin = {top: 20, right: 80, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 200 - margin.top - margin.bottom;

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

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .tickSize(-height, 0)
    .tickPadding(6);

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .tickSize(-width)
    .tickPadding(6);

// Define how we will access the information needed from each row
var line = d3.svg.line()
    .interpolate("step-after")
    .x(function(d) { return x(d[0]); })
    .y(function(d) { return y(d[2]); });

// Insert an svg element into the document for each chart
svg = d3.select("body").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 + ")");

// Declare zoom handler
var zoom = d3.behavior.zoom().on("zoom", draw);

// Open the log and extract the information
d3.text("log.csv", function(text) {
    var data = d3.csv.parseRows(text).map(function(row) {
        return row.map(function(value, index) {
            if (index == 0) {
                return parseDate(value);
            }
            else if (index > 1) {
                return +value;
            }
            else {
                return value;
            }
        });
    });

    // Set the global minimum and maximums
    x.domain(d3.extent(data, function(d) { return d[0]; }));
    y.domain(d3.extent(data, function(d) { return d[2]; }));
    zoom.x(x);

    // Finally, we have the data parsed, and the parameters of the charts set, so now we
    // fill in the charts with the lines and the labels
    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    svg.append("g")
        .attr("class", "y axis")
        .call(yAxis)
        .append("text")
        .attr("transform", "rotate(-90)")
        .attr("y", 6)
        .attr("dy", ".71em")
        .attr("text-anchor", "end")
        .text("Percent (%)");

    svg.append("path")
        .datum(data)
        .attr("class", "line")
        .attr("d", line);

    svg.append("text")
        .attr("x", margin.left)             
        .attr("y", 0 - (margin.top / 2))
        .attr("text-anchor", "middle")  
        .text('all');

    svg.append("rect")
        .attr("class", "pane")
        .attr("width", width)
        .attr("height", height)
        .call(zoom);

    svg.select("path.line").data([data]);
    draw();
});

function draw() {
    svg.select("g.x.axis").call(xAxis);
    svg.select("g.y.axis").call(yAxis);
    svg.select("path.line").attr("d", line);
}

What this gives me is a very sluggish chart that can be zoomed and panned, but it does not clip off the line at the ends of the chart. I've tried adding in the clipping elements described in the example, but that ends up fully erasing my line every time.

Thanks for any help or direction

0条回答
登录 后发表回答