繁体   English   中英

D3示例:看起来像一个javascript变量,但被称为一个函数

[英]D3 example: looks like a javascript variable, but is called like a function

我试图从D3示例中了解此Javascript代码的工作方式。 对我而言,没有意义的部分是buildLine()函数中的xScaleyScale “函数”。

xScale为例,它看起来像一个简单的变量,实例化为一个值:

    var xScale = d3.scale.linear()
                .domain([
                            d3.min(ds.monthlySales, function(d){ return d.month;}) ,
                            d3.max(ds.monthlySales, function(d){ return d.month;})
                        ])                
                .range([0, w])
                .nice(); 

...但随后在buildLine() ,似乎它们被称为函数:

    var lineFun = d3.svg.line()
        .x(function (d) {return xScale(d.month); } )
        .y(function (d) {return yScale(d.sales); })
        .interpolate("linear");

更具体地说,在:

.x(function (d) {return xScale(d.month); } )

...我不了解d来自何处(以及它如何具有.month属性),最重要的是xScale “函数”如何接收 d

我认为,要使此代码有意义,我需要了解Javascript的基本原理,但是那可能是什么呢?


基本数据可以在这里看到:

https://github.com/bsullins/d3js-resources/blob/master/monthlySalesbyCategoryMultiple.json

整个源代码:

<!DOCTYPE html>
<html>
    <head>
        <script src="d3.min.js" charset="utf-8"></script>
    </head>
    <body>
    <script>
        var h=100;
        var w=400;
        var padding = 20;             


        //build line
        function buildLine(ds) {
            console.log('xscale-max: '+ d3.max(ds.monthlySales, function (d){ return d.month; }));
            console.log('yscale-max: '+ d3.max(ds.monthlySales, function (d){ return d.sales; }));
            //scales
            var xScale = d3.scale.linear()
                        .domain([
                                    d3.min(ds.monthlySales, function(d){ return d.month;}) ,
                                    d3.max(ds.monthlySales, function(d){ return d.month;})
                                ])                
                        .range([0, w])
                        .nice(); 

            var yScale = d3.scale.linear()
                        .domain([0, d3.max(ds.monthlySales, function(d){ return d.sales;})])
                        .range([h,0])
                        .nice();

            var lineFun = d3.svg.line()
                .x(function (d) {return xScale(d.month); } )
                .y(function (d) {return yScale(d.sales); })
                .interpolate("linear");

            var svg = d3.select("body").append("svg").attr({ width:w, height:h});

            var viz = svg.append("path")
                        .attr({
                            d: lineFun(ds.monthlySales),
                            "stroke" : "purple",
                            "stroke-width": 2,
                            "fill" : "none"
                        });

        }

        //show header
        function showHeader(ds) {
            d3.select("body").append("h1")
                .text(ds.category + " Sales (2013)");
        }


        //get data and draw things  
        d3.json("https://api.github.com/repos/bsullins/d3js-resources/contents/monthlySalesbyCategoryMultiple.json", function(error, data) {

           if(error) {
               console.log(error);
           } else {
               console.log(data); //we're golden!
           }

            var decodedData = JSON.parse(window.atob(data.content));

            console.log(decodedData.contents);


            decodedData.contents.forEach(function(content){
                ds=content;
                console.log(ds);
                showHeader(ds);         
                buildLine(ds);                   
            })

        });  


    </script>
    </body>
</html>

好的javascript具有一流的函数,因此xScale是一个包含函数的变量。 这意味着您可以传递它并进行调用。

更具体地说,您发布的第一个代码段构建了一个函数,该函数接受.domain([d3.min ..., d3.max ... ])指定的间隔中的值,并返回由.domain([d3.min ..., d3.max ... ])指定的间隔中的值.range([0, w]) 它还说该函数返回的值应该是“ nice”(. .nice() ),即被截断为没有几个小数。 根据这些规范构建的功能将分配给xScale变量。

稍后,您可以在d3.svg.line生成器中使用此函数,就像d3.scale.linear一样, d3.scale.linear函数/对象生成(因此, 生成器 )一个函数,在这种情况下,当将数据集提供给输入,返回一个可用作svg path元素的d属性的字符串,以绘制所需的路径。 该函数被分配给变量lineFun (有趣的部分!)。

使用d3.svg.line生成器构建的lineFun函数将数据集作为输入:

lineFun(ds.monthlySales)

然后,对于数据集中的每个数据点,它会将其作为输入传递给访问器函数( d参数的来源),以便它们可以为该数据点创建ax和y值。 因此,访问器函数通常是根据数据点的某些属性来接受数据点并返回值的函数。 因此,例如:

function (d) {return xScale(d.month);

给定一个数据点d ,当将数据点的month属性作为输入传递时,xScale函数返回该值。

我知道我没有写出最清晰的解释,但我希望它能对您有所帮助。

关键点是:

  • Javascript中的函数可以分配给变量并作为参数传递,就像整数或字符串一样
  • d3.scale.lineard3.svg.line是生成器:它们生成并返回一个函数
  • 当给定数据作为输入时,d3使用形状生成器返回svg属性,这些属性用于绘制表示数据的路径。

来自https://github.com/mbostock/d3/wiki/SVG-Shapes#path-data-generators

路径生成器(例如d3.svg.line返回的路径生成器)既是对象也是函数。 即:您可以像调用其他任何函数一样调用生成器,并且生成器具有更改其行为的其他方法。 像D3中的其他类一样,路径生成器遵循方法链接模式,在此方法中,setter方法返回生成器本身,从而允许在简洁的语句中调用多个setter。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM