D3js排行榜

时间:2017-08-25 20:50:23

标签: javascript html css d3.js charts

我正在努力获得响应式d3js图表。我已将宽度和高度设置为100%,因为图表具有调整大小功能,应该减小尺寸。到目前为止我所做的只是设法减少x轴上的标签,但线图仍然保持相同的大小。这是我试图以正确的方式做出响应的方式,或者是他们更好的方式任何d3js图表(条形/饼图/线条)都可以做出响应。

var margin = {
    top: 30,
    right: 20,
    bottom: 30,
    left: 50
};
 var width = parseInt(d3.select("#chart").style("width")) - margin.left - margin.right,
    height = parseInt(d3.select("#chart").style("height")) - margin.top - margin.bottom;



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

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

var xAxis = d3.svg.axis().scale(x)
    .orient("bottom").ticks(5).tickFormat(function (d) {
    return d.replace('SEASONAL_', '');
    });;

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

var valueline = d3.svg.line()
    .x(function (d) {
      return x(d.name);
    })
    .y(function (d) {
      return y(d.count);
    });

var 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 + ")");

// Get the data
var all = [{
                "name": "Seasonal Pop",
                "code": "SEASONAL_POP",
                "children": [{
                    "name": "SEASONAL_LYQ1",
                    "code": "SEASONAL_LYQ1",
                    "count": 1200
                }, {
                    "name": "SEASONAL_LYQ2",
                    "code": "SEASONAL_LYQ2",
                    "count": 2000
                }, {
                    "name": "SEASONAL_LYQ3",
                    "code": "SEASONAL_LYQ3",
                    "count": 1060
                }, {
                    "name": "SEASONAL_LYQ4",
                    "code": "SEASONAL_LYQ4",
                    "count": 2300
                }, {
                    "name": "SEASONAL_CYQ1",
                    "code": "SEASONAL_CYQ1",
                    "count": 1300
                }, {
                    "name": "SEASONAL_CYQ2",
                    "code": "SEASONAL_CYQ2",
                    "count": 3400
                }, {
                    "name": "SEASONAL_CYQ3",
                    "code": "SEASONAL_CYQ3",
                    "count": 4500
                }, {
                    "name": "SEASONAL_CYQ4",
                    "code": "SEASONAL_CYQ4",
                    "count": 5500
                }]
            }];
 var data = all[0].children;

data.forEach(function (d) {
    // d.name = +d.date ;
    d.count = +d.count;
});

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

svg.append("path") // Add the valueline path.
.attr("d", valueline(data));

svg.append("g") // Add the X Axis
.attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

svg.append("g") // Add the Y Axis
.attr("class", "y axis")
    .call(yAxis);
    
     // Define responsive behavior
    function resize() {
      var width = parseInt(d3.select("#chart").style("width")) - margin.left - margin.right,
      height = parseInt(d3.select("#chart").style("height")) - margin.top - margin.bottom;

      // Update the range of the scale with new width/height
      x.range([0, width]);
      y.range([height, 0]);

      // Update the axis and text with the new scale
      svg.select('.x.axis')
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

      svg.select('.y.axis')
        .call(yAxis);

      // Force D3 to recalculate and update the line
      svg.selectAll('.line')
        .attr("d", function(d) { return line(d.count); });

      // Update the tick marks
      xAxis.ticks(Math.max(width/75, 2));
      yAxis.ticks(Math.max(height/50, 2));

    };

    // Call the resize function whenever a resize event occurs
    d3.select(window).on('resize', resize);

    // Call the resize function
    resize();
body {
    font: 12px Arial;
}
path {
    stroke: steelblue;
    stroke-width: 2;
    fill: none;
}
.axis path, .axis line {
    fill: none;
    stroke: grey;
    stroke-width: 1;
    shape-rendering: crispEdges;
}

#chart {
  width: 100%;
  height: 100%;
  position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<body><svg id="chart"></svg></body>

1 个答案:

答案 0 :(得分:1)

你的代码有点有用。除了你正在处理两个SVG。页面上有id =“chart”,这个附加了。

var svg = d3.select("body")
    .append("svg")

但它不是真正的D3问题,它更多地与响应式SVG有关。响应式图表存在缩放问题。 X&amp; Y轴可能会被误传。

一种方法是缩放整个Chart / SVG。忘了听窗口调整大小事件。只需在主svg上设置viewBox属性即可。并设置一个静态宽度高度,这也是聊天的正确比例。

var svg = d3.select("#chart")
    .attr("viewBox", "0 0 " + viewWidth + " " + viewHeight)

例如

var margin = {
    top: 30,
    right: 20,
    bottom: 30,
    left: 50
};
 var width = 500 - margin.left - margin.right,
    height = 240 - margin.top - margin.bottom;

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

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

var xAxis = d3.svg.axis().scale(x)
    .orient("bottom").ticks(5).tickFormat(function (d) {
    return d.replace('SEASONAL_', '');
    });;

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

var valueline = d3.svg.line()
    .x(function (d) {
      return x(d.name);
    })
    .y(function (d) {
      return y(d.count);
    });
var viewWidth = width - margin.left - margin.right;
var viewHeight = height + margin.top + margin.bottom;
var svg = d3.select("#chart")
    .attr("viewBox", "0 0 " + viewWidth + " " + viewHeight)


// Get the data
var all = [{
                "name": "Seasonal Pop",
                "code": "SEASONAL_POP",
                "children": [{
                    "name": "SEASONAL_LYQ1",
                    "code": "SEASONAL_LYQ1",
                    "count": 1200
                }, {
                    "name": "SEASONAL_LYQ2",
                    "code": "SEASONAL_LYQ2",
                    "count": 2000
                }, {
                    "name": "SEASONAL_LYQ3",
                    "code": "SEASONAL_LYQ3",
                    "count": 1060
                }, {
                    "name": "SEASONAL_LYQ4",
                    "code": "SEASONAL_LYQ4",
                    "count": 2300
                }, {
                    "name": "SEASONAL_CYQ1",
                    "code": "SEASONAL_CYQ1",
                    "count": 1300
                }, {
                    "name": "SEASONAL_CYQ2",
                    "code": "SEASONAL_CYQ2",
                    "count": 3400
                }, {
                    "name": "SEASONAL_CYQ3",
                    "code": "SEASONAL_CYQ3",
                    "count": 4500
                }, {
                    "name": "SEASONAL_CYQ4",
                    "code": "SEASONAL_CYQ4",
                    "count": 5500
                }]
            }];
 var data = all[0].children;

data.forEach(function (d) {
    // d.name = +d.date ;
    d.count = +d.count;
});

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

svg.append("path") // Add the valueline path.
.attr("d", valueline(data));

svg.append("g") // Add the X Axis
.attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

svg.append("g") // Add the Y Axis
.attr("class", "y axis")
    .call(yAxis);
body {
    font: 12px Arial;
}
path {
    stroke: steelblue;
    stroke-width: 2;
    fill: none;
}
.axis path, .axis line {
    fill: none;
    stroke: grey;
    stroke-width: 1;
    shape-rendering: crispEdges;
}

#chart {
  width: 100%;
  height: 100%;
  position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<body><svg id="chart"></svg></body>