且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

带有水平滚动的SVG

更新时间:2022-10-19 13:47:14

不会翻转.这里发生的事情非常简单:您有两个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>