D3.js使用json格式資料繪出曲線圖(Line Chart)之程式範例

D3.js使用json格式資料繪出曲線圖(Line Chart)之程式範例

由於工作專案要用D3.js和json格式資料畫出曲線圖(Line Chart),寫出了第一個版本,但現在的專案改寫了第二版,因此將第一版程式碼記錄如下:
 

    //第一版:時間x軸以小時為單位,並且限制資料配合0~24小時的刻度
    function GenerateSVGLineChart(SVGName, FacilityID, ParameterID, yScaleTitle, LikeFacilityParameterID) {
        // Set the dimensions of the canvas / graph
        var svg = d3.select(SVGName),
         margin = { top: 30, right: 70, bottom: 80, left: 80 },
         width = parseInt(d3.select(".tab-content").style("width")) - margin.left - margin.right,
         height = 300 - margin.top - margin.bottom;
        padding = 20;

        // Parse the date / time
        var parseDateTime = d3.timeParse("%Y/%m/%d %H:%M");

        //定義 x 尺度
        var xScale = d3.scaleLinear()
            .domain([0, 24])
            .nice(d3.timeDay,1)
            .range([padding, width - padding * 2]);

        var yScale = d3.scaleLinear().range([height, 0]);

        // Define the line
        var temperatureline = d3.line()
            .x(function (d) {
                return xScale(d.date);
            })
            .y(function (d) {
                return yScale(d.temperature);
            });

        // Adds the svg canvas
        var svg2 = d3.select(SVGName)
                .attr("width", width + margin.left + margin.right)
                .attr("height", height + margin.top + margin.bottom)
                .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        // Get the data
        $.ajax({
            type: 'POST',
            url: '@Url.Action("GetFacilityHistory", "FM")',
            data: {
                FacilityID: FacilityID,
                FacilityParameterID: ParameterID,
                LikeFacilityParameterID: LikeFacilityParameterID
            },
            async: false,
            success: function (data) {
                var jsonData = data.jsonData;

                jsonData.forEach(function (d) {
                    d.date = parseDateTime(d.ProcessTime).getHours();
                    d.temperature = +d.FacilityImmediateValue;
                });

                var xAxis = d3.axisBottom(xScale)
                    .tickFormat(function (d) {
                        return d;
                    });

                yScale.domain([0, d3.max(jsonData, function (d) {
                    return d.temperature;
                })]);

                // Nest the entries by symbol
                var dataNest = d3.nest()
                    .key(function (d) {
                        if (FacilityID == null || FacilityID == "") {
                            //若沒有廠務設備就是篩選出不同的廠務設備
                            return d.FacilityName;
                        }
                        else {
                            //若有廠務設備就是篩選出不同的參數名稱
                            return d.FacilityParameterName;
                        }
                    })
                    .entries(jsonData);

                // set the colour scale
                var color = d3.scaleOrdinal(d3.schemeCategory10);

                legendSpace = width / dataNest.length; // spacing for the legend

                // Loop through each symbol / key
                dataNest.forEach(function (d, i) {

                    svg2.append("path")
                        .attr("class", "line")
                        .style("stroke", function () {
                            // Add the colours dynamically
                            return d.color = color(d.key);
                        })
                        .attr("d", temperatureline(d.values));

                    // Add the Legend
                    svg2.append("text")
                        .attr("x", (legendSpace / 2) + i * legendSpace)  // space legend
                        .attr("y", height + (margin.bottom / 2) + 5)
                        .attr("class", "legend")    // style the legend
                        .style("fill", function () { // Add the colours dynamically
                            return d.color = color(d.key);
                        })
                        .text(d.key);

                    if (FacilityID == null || FacilityID == "") {
                        //若沒有廠務設備就是篩選出不同的廠務設備
                        svg2.selectAll(".dottxt")//增加點上的文字
                              .data(jsonData).enter().append("text")
                              .attr("class", "dottxt")
                              .attr("x", function (d) {
                                  return xScale(d.date) - 10;
                              })
                              .attr("y", function (d) {
                                  return yScale(d.temperature) - 10;
                              })
                              .style("fill", function (d) {
                                  return color(d.FacilityName)
                              })
                              .text(function (d) {
                                  return d.temperature;
                              });

                        svg2.selectAll("circle")//增加線上的圓點
                              .data(jsonData).enter().append("circle")
                              .attr("r", 4)
                              .attr("cx", function (d) {
                                  return xScale(d.date);
                              })
                              .attr("cy", function (d) {
                                  return yScale(d.temperature);
                              })
                              .style("fill", function (d) {
                                  return color(d.FacilityName)
                              })
                              .append("text")
                              .attr("class", "dottxt")
                              .text(d.key)
                              .style("fill", "#000");
                    }
                    else {
                        //若有廠務設備就是篩選出不同的參數名稱
                        svg2.selectAll(".dottxt")//增加點上的文字
                              .data(jsonData).enter().append("text")
                              .attr("class", "dottxt")
                              .attr("x", function (d) { return xScale(d.date) - 10; })
                              .attr("y", function (d) { return yScale(d.temperature) - 10; })
                              .style("fill", function (d) { return color(d.FacilityParameterName) })
                              .text(function (d) { return d.FacilityParameterDataName; });

                        svg2.selectAll("circle")//增加線上的圓點
                              .data(jsonData).enter().append("circle")
                              .attr("r", 4)
                              .attr("cx", function (d) { return xScale(d.date); })
                              .attr("cy", function (d) { return yScale(d.temperature); })
                              .style("fill", function (d) { return color(d.FacilityParameterName) })
                              .append("text")
                              .attr("class", "dottxt")
                              .text(d.key)
                              .style("fill", "#000");
                    }
                });

                // Add the X Axis
                svg2.append("g")
                  .attr("class", "axis line-x")
                  .attr("transform", "translate(0," + height + ")")
                  .call(xAxis)//d3.axisBottom(xScale)//xAxis
                  .append("text")
                  .attr("transform", "rotate(0)")
                  .attr("x", width / 2)
                  .attr("y", 30)
                  .attr("fill", "#000")
                  .text("時間").style("font-size", "14px");

                // Add the Y Axis
                svg2.append("g")
                    .attr("class", "axis line-y")
                    .call(d3.axisLeft(yScale))
                    .append("text")
                    .attr("transform", "rotate(-90)")
                    .attr("y", -46)
                    .attr("dy", "0.71em")
                    .attr("fill", "#000")
                    .text(yScaleTitle).style("font-size", "14px");
            }
        });
    }