在D3

时间:2016-02-14 18:20:56

标签: javascript html d3.js

假设我根据我拥有的一些数据创建条形图。该条形图在一组x轴和y轴上生成。如何将一个函数(格式为y=f(x))绘制为同一组轴上的一条线?我想这样做,以便您可以轻松地比较条形图和功能显示的趋势。

3 个答案:

答案 0 :(得分:3)

您只需通过在域的所需值上运行函数来生成要提供给d3的数据,然后使用例如行生成器来绘制线。



var w = 400;
var h = 400;
var padding = 50;

var svg = d3.select('svg').attr('width', w + padding * 2).attr('height', h + padding * 2);

var xScale = d3.scale.linear().domain([-10, 10]).range([0, w]);
var yScale = d3.scale.linear().domain([2, -2]).range([0, h]);

var xAxis = d3.svg.axis().scale(xScale);
var yAxis = d3.svg.axis().scale(yScale).orient("left");

var g = svg.append("g").attr("transform", "translate(" + padding + "," + padding + ")");

g.append("g").attr("transform", "translate(0, " + w / 2 + ")").call(xAxis);
g.append("g").attr("transform", "translate(" + h / 2 + ", 0)").call(yAxis);

var line = d3.svg.line().interpolate("basis")
  .x(function(d, i) {
    return xScale(d.x);
  })
  .y(function(d, i) {
    return yScale(d.y);
  })
g.append('path')
  .data([fn1()])
  .attr("d", line);

g.append('path')
  .data([fn2()])
  .attr("d", line);

g.append('path')
  .data([fn3()])
  .attr("d", line);

g.append('path')
  .data([fn4()])
  .attr("d", line);

function fn1() {
  function f(x) {
    return Math.cos(x);
  }
  return _.chain(_.range(-10, 10)).map(function(x) {
    return {
      y: f(x),
      x: x
    };
  }).value();
}

function fn2() {
  function f(x) {
    return Math.sin(x);
  }
  return _.chain(_.range(-10, 10)).map(function(x) {
    return {
      y: f(x),
      x: x
    };
  }).value();
}

function fn3() {
  function f(x) {
    return Math.exp(x);
  }
  return _.chain(_.range(-10, 10)).map(function(x) {
    return {
      y: f(x),
      x: x
    };
  }).value();
}

function fn4() {
  function f(x, m, b) {
    return m * x + b;
  }
  return _.chain(_.range(-10, 10)).map(function(x) {
    return {
      y: f(x, 1, 1),
      x: x
    };
  }).value();
}

 path {
   stroke: black;
   fill: none;
 }

<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

<body>

  <svg></svg>

</body>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

我正在使用D3和Math.js

我使用Math.js的原因是函数可能非常复杂 从:

  • 4 * sin(x)+ 5 * tan(x / 2)
  • 4 * sin(x ^ 2)+ 5 * cos(x / 2)^ 3
  • 除了f(x)以外的任何东西:)

您可以在此处定义您选择的任何域名:

//define xDomain change it domain of your choice    
var xDomain = [-10, 10];
//define yDomain change it domain of your choice    
var yDomain = [-10, 10];

然后为该域制作传统的条形图没什么特别的,这是制作条形图的标准D3代码。

//make the bar chart by loading the tsv
d3.tsv("data.tsv", type, function(error, data) {
  if (error) throw error;
  //make x axis
  svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + y(0) + ")")
    .call(xAxis);
  //make y axis
  svg.append("g")
    .attr("class", "y axis")
    .attr("transform", "translate(" + x(0) + ",0)")
    .call(yAxis)
    .append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", 6)
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .text("Frequency");
  //make bar chart rectangle
  svg.selectAll(".bar")
    .data(data)
    .enter().append("rect")
    .attr("class", "bar")
    .attr("x", function(d) {
      return x(d.letter) - 10;
    })
    .attr("width", 20)
    .attr("y", function(d) {
      return y(d.frequency);
    })
    .attr("height", function(d) {
      return height / 2 - y(d.frequency);
    });
  makeLineFunction();

});

这是我的功能,它将根据在文本框中输入的值(对于xdomain)制作折线图:

function makeLineFunction() {
  //remove any line if present
  d3.selectAll(".line").remove();
  //make an array of all x points
  var xArray = d3.range(xDomain[0], xDomain[1], 0.5);
  //get the formula from the text box above
  var value = d3.select("#function_text").node().value;
  //generate the data using math.js
  var data = xArray.map(function(x1) {
    return {
      x: x1,
      //using math.js for evaluating y point for the given x
      y: math.eval(value, {
        x: x1
      })
    };
  });
  //make the path
  svg.append("path")
    .datum(data)
    .attr("class", "line")
    .attr("d", line);
}

工作代码here,为帮助添加了必要的评论。

希望这有帮助!

答案 2 :(得分:0)

以下示例说明了条形图聊天的折线图。您可以在运行时使用jsp或php生成y = f(x)值。 更新数据部分

series: [
    {
        title: 'Column',
        type: 'column',
        axisY: 'y1',
        data: [['A', 1], ['B', 4], ['C', 3],
               ['D', 5], ['E', 2], ['F', 1]]
    },
    {
        title: 'Line',
        type: 'line',
        axisY: 'y2',
        data: [['A', 40], ['B', 60], ['C', 62],
               ['D', 52], ['E', 70], ['F', 75]]
    }
]

&#13;
&#13;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>
    Multiple Axes Example
</title>

<link rel="stylesheet" type="text/css" href="http://www.jqchart.com/css/jquery.jqChart.css" />	
    
    <link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.21/themes/smoothness/jquery-ui.css" />
    <script src="http://www.jqchart.com/js/jquery-1.11.1.min.js" type="text/javascript"></script>
    <script src="http://www.jqchart.com/js/jquery.mousewheel.js" type="text/javascript"></script>
    <script src="http://www.jqchart.com/js/jquery.jqChart.min.js" type="text/javascript"></script>
    <script src="http://www.jqchart.com/js/jquery.jqRangeSlider.min.js" type="text/javascript"></script>
    
    <script lang="javascript" type="text/javascript">
        $(document).ready(function () {

            var background = {
                type: 'linearGradient',
                x0: 0,
                y0: 0,
                x1: 0,
                y1: 1,
                colorStops: [{ offset: 0, color: '#d2e6c9' },
                             { offset: 1, color: 'white' }]
            };

            $('#jqChart').jqChart({
                title: { text: 'Multiple Axes' },
                border: { strokeStyle: '#6ba851' },
                background: background,
                animation: { duration: 1 },
                shadows: {
                    enabled: true
                },
                axes: [
                    {
                        name: 'y1',
                        location: 'left'
                    },
                    {
                        name: 'y2',
                        location: 'right',
                        strokeStyle: '#FCB441',
                        majorGridLines: {
                            strokeStyle: '#FCB441'
                        },
                        majorTickMarks: {
                            strokeStyle: '#FCB441'
                        }
                    }
                ],
                series: [
                    {
                        title: 'Column',
                        type: 'column',
                        axisY: 'y1',
                        data: [['A', 1], ['B', 4], ['C', 3],
                               ['D', 5], ['E', 2], ['F', 1]]
                    },
                    {
                        title: 'Line',
                        type: 'line',
                        axisY: 'y2',
                        data: [['A', 40], ['B', 60], ['C', 62],
                               ['D', 52], ['E', 70], ['F', 75]]
                    }
                ]
            });
        });
    </script>

</head>
<body>
    <div>
        <div id="jqChart" style="width: 500px; height: 300px;"></div>
    </div>
</body>
</html>
&#13;
&#13;
&#13;