带有水平滚动的SVG [英] SVG with Horizontal Scrolling

查看:319
本文介绍了带有水平滚动的SVG的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用D3创建SVG图( https://jsfiddle.net/bikrantsharma/zw264tfc/12/

这是我的体重秤的定义方式

var barWidth = 30,
  paddingFactor = 2.2,
  responsiveDIVHeight = 300,
  responsiveDIVWidth = tempData.length * barWidth * paddingFactor;



var x = d3.scale.ordinal().rangeRoundBands([0, responsiveDIVWidth], 0.5)
  .domain(tempData.map(function(d) {
    return d.Type
  })),
  y = d3.scale.linear().rangeRound([responsiveDIVHeight, 0])
  .domain([0, d3.max(tempData, function(d) {
    return (d.Count + 10);
  })]),

我需要解决两个问题:

  1. 条形图沿相反方向翻转.如何使div翻转或条形转换?

  2. 条形图的高度略小于实际值.因此,例如,如果计数"为"5",则条形高度会返回4.8或类似值.那里是什么问题?

解决方案

不会翻转.这里发生的事情非常简单:您有两个SVG,一个在顶部,一个在底部,并在底部SVG中绘制矩形.矩形如何神奇地出现在 top SVG中?这是不可能的.

相反,请并排绘制SVG.带有垂直轴的左边一个具有<div>所在样式的float: left,右边的一个可滚动显示的具有<div>样式的overflow-x: scroll.

以下是一个演示,它在您的代码中进行了尽可能少的更改:

 var tempData = [];
for (var i = 1; i < 30; i++) {
  var obj = {

    "Id": 1,
    "Type": 'A' + i,
    "Count": 5
  };
  tempData.push(obj);
}


var barWidth = 30,
  paddingFactor = 2.2,
  padding = 20,
  responsiveDIVHeight = 300,
  responsiveDIVWidth = tempData.length * barWidth * paddingFactor;

var x = d3.scale.ordinal().rangeRoundBands([0, responsiveDIVWidth], 0.5)
  .domain(tempData.map(function(d) {
    return d.Type
  })),
  y = d3.scale.linear().rangeRound([responsiveDIVHeight - padding, padding])
  .domain([0, d3.max(tempData, function(d) {
    return (d.Count + 10);
  })]),
  xAxis = d3.svg.axis().scale(x).orient('bottom'),
  yAxis = d3.svg.axis().scale(y).orient('left');


var svgY = d3.select('#verticalSVG')
  .append('svg')
  .attr('height', responsiveDIVHeight)
  .attr("width", 50);

svgY.append('g')
  .attr('class', 'y axis')
  .call(yAxis)
  .attr('dx', '-0.3em')
  .attr('transform', "translate(50, 0)");;

var svgX = d3.select('#horizontalSVG')
  .append('svg')
  .attr('width', responsiveDIVWidth)
  .attr('height', responsiveDIVHeight);

svgX.append('g')
  .attr('class', 'x axis')
  .attr('transform', "translate(0," + (responsiveDIVHeight - padding) + ")")
  .call(xAxis)
  .selectAll('text')
  .attr('dx', '-0.8em')
  .attr('dy', '-.15em')
  .attr('transform', function(d) {
    return "rotate(-60)"
  });


var startPoint = 0;

var bar = svgX.selectAll('.bar')
  .data(tempData)
  .enter()
  .append('rect')
  .attr('y', function(d) {
    return y(d.Count)
  })
  .attr('x', function(d) {
    return x(d.Type)
  })
  .attr('width', barWidth)
  .attr('height', function(d) {
    return responsiveDIVHeight - y(d.Count) - padding
  }) 

 .legend-main-div {
  padding: 2%;
  max-height: 150px;
  overflow-y: scroll;
  border: 1px solid blue;
}

.axis line,
.axis path {
  fill: none;
  stroke: black;
} 

 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div class="row">
  <div class="col-md-12">

    <div id="verticalSVG" style="float:left">

    </div>
    <div id="horizontalSVG" style="overflow-x:scroll">

    </div>
  </div>

</div> 

I am trying to do a SVG graph with D3 (https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js) where the bar width is defined manually and the thing has a horizontal scroll..

I have a working fiddle here

https://jsfiddle.net/bikrantsharma/zw264tfc/12/

This is how my scales are defined

var barWidth = 30,
  paddingFactor = 2.2,
  responsiveDIVHeight = 300,
  responsiveDIVWidth = tempData.length * barWidth * paddingFactor;



var x = d3.scale.ordinal().rangeRoundBands([0, responsiveDIVWidth], 0.5)
  .domain(tempData.map(function(d) {
    return d.Type
  })),
  y = d3.scale.linear().rangeRound([responsiveDIVHeight, 0])
  .domain([0, d3.max(tempData, function(d) {
    return (d.Count + 10);
  })]),

There are two problems which i need help with:

  1. The Bars are flipped in opposite direction. How to get the div flipped or the bars transformed?

  2. The height of the bar comes a slightly less than the actual value. So for e.g if the Count is '5' bar height comes back as 4.8 or something. What is the issue there?

解决方案

Your bars are not flipped. What's happening here is very simple: You have two SVGs, one at the top and one at the bottom, and you're drawing the rectangles in the bottom SVG. How can the rectangles magically appear in the top SVG? It's not possible.

Instead of that, draw the SVGs side by side. The left one, with the vertical axis, has float: left in the style of the <div> it is in, and the right one, scrollable, has overflow-x: scroll in the style of the <div> it is in.

Here is a demo making the minimal possible changes in your code:

var tempData = [];
for (var i = 1; i < 30; i++) {
  var obj = {

    "Id": 1,
    "Type": 'A' + i,
    "Count": 5
  };
  tempData.push(obj);
}


var barWidth = 30,
  paddingFactor = 2.2,
  padding = 20,
  responsiveDIVHeight = 300,
  responsiveDIVWidth = tempData.length * barWidth * paddingFactor;

var x = d3.scale.ordinal().rangeRoundBands([0, responsiveDIVWidth], 0.5)
  .domain(tempData.map(function(d) {
    return d.Type
  })),
  y = d3.scale.linear().rangeRound([responsiveDIVHeight - padding, padding])
  .domain([0, d3.max(tempData, function(d) {
    return (d.Count + 10);
  })]),
  xAxis = d3.svg.axis().scale(x).orient('bottom'),
  yAxis = d3.svg.axis().scale(y).orient('left');


var svgY = d3.select('#verticalSVG')
  .append('svg')
  .attr('height', responsiveDIVHeight)
  .attr("width", 50);

svgY.append('g')
  .attr('class', 'y axis')
  .call(yAxis)
  .attr('dx', '-0.3em')
  .attr('transform', "translate(50, 0)");;

var svgX = d3.select('#horizontalSVG')
  .append('svg')
  .attr('width', responsiveDIVWidth)
  .attr('height', responsiveDIVHeight);

svgX.append('g')
  .attr('class', 'x axis')
  .attr('transform', "translate(0," + (responsiveDIVHeight - padding) + ")")
  .call(xAxis)
  .selectAll('text')
  .attr('dx', '-0.8em')
  .attr('dy', '-.15em')
  .attr('transform', function(d) {
    return "rotate(-60)"
  });


var startPoint = 0;

var bar = svgX.selectAll('.bar')
  .data(tempData)
  .enter()
  .append('rect')
  .attr('y', function(d) {
    return y(d.Count)
  })
  .attr('x', function(d) {
    return x(d.Type)
  })
  .attr('width', barWidth)
  .attr('height', function(d) {
    return responsiveDIVHeight - y(d.Count) - padding
  })

.legend-main-div {
  padding: 2%;
  max-height: 150px;
  overflow-y: scroll;
  border: 1px solid blue;
}

.axis line,
.axis path {
  fill: none;
  stroke: black;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div class="row">
  <div class="col-md-12">

    <div id="verticalSVG" style="float:left">

    </div>
    <div id="horizontalSVG" style="overflow-x:scroll">

    </div>
  </div>

</div>

这篇关于带有水平滚动的SVG的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆