javascript - D3js 图表响应

标签 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>

最佳答案

嗯,您的代码可以正常工作。保存您正在处理两个 SVG。在带有 id="chart"的页面上,这是附加的。

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

但这并不是真正的 D3 问题,它更多地与响应式 SVG 有关。响应图表在缩放方面存在问题。 X 和 Y 轴可能会被错误表示。

一种方法是缩放整个图表/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>

关于javascript - D3js 图表响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45889237/

相关文章:

html - css - 三 Angular 形边框 100% 的屏幕

css - 渲染超过 20 列时 Angular Material Table 崩溃了

用于更改移动显示的 css 值的 Javascript

javascript - 为什么没有定义 meteor 模板对象?

javascript - 在 Angular2 中强制重新加载 HTML 模板

javascript - 响应式菜单不起作用(菜单正在关闭)

html - IE 浏览器中的指针事件问题

css - 使完整的 div 可点击 (html)

javascript - 此上下文中的异常 : Cannot call SpreadsheetApp. getUi()

javascript - innerHTML 将 CDATA 转换为注释