簡體   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