You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Timeline图表与Ajax/JSON请求绑定问题及解决方案咨询

Google Charts Timeline图表Ajax绑定问题排查与解决

一、初始实现(硬编码正常运行)

采用硬编码单条数据的方式可正常渲染Timeline图表,代码如下:

google.charts.load("current", { packages: ["timeline"] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
    var container = document.getElementById('CurrentOrders');
    var chart = new google.visualization.Timeline(container);
    var data = new google.visualization.DataTable();
    data.addColumn({ id: 'OrderNum', label: 'Order Number', type: 'string' });
    data.addColumn({ id: 'PN', label: 'Part Number', type: 'string' });
    data.addColumn({ id: 'StartDate', label: 'Start', type: 'date' });
    data.addColumn({ id: 'EndDate', label: 'End', type: 'date' });
    
    data.addRows([                
        ['M12345', 'MyPartNumber', new Date(2023, 1, 4), new Date(2023, 1, 6)]
    ]);
    var options = {
        timeline: {
            groupByRowLabel: true
        }
    };
    chart.draw(data, options);
}

二、WebMethod实现(数据返回符合预期)

通过WebMethod从数据库获取数据并序列化为JSON返回,返回结果格式正确:

<System.Web.Services.WebMethod>
Public Shared Function GetOrders() As String
    Dim mOrder As List(Of Morder) = New List(Of Morder)()
    Dim constr As String = ConfigurationManager.ConnectionStrings("HYDMCS").ConnectionString
    Dim Query As String = "SELECT TOP(1) OrderNumber,Part_Number, CONVERT(DATE,GETDATE()) AS StartDate, CONVERT(DATE,DATEADD(DAY,2,GETDATE())) AS EndDate, MfgDueDate FROM HYD_GP_ProductionSchedule ORDER BY Part_Number DESC "
    Using con As New SqlConnection(constr)
        Try
            con.Open()
            Using sqlCmd As SqlCommand = New SqlCommand(Query, con)
                Using reader As SqlDataReader = sqlCmd.ExecuteReader
                    While reader.Read
                        If reader.HasRows Then
                            mOrder.Add(New Morder() With {
                                .OrderNum = reader(0).ToString(),
                                .PN = reader(1).ToString(),
                                .StartDate = reader(2),
                                .EndDate = reader(3)
                            })
                        End If
                    End While
                End Using
            End Using
            con.Close()
        Catch ex As Exception
            If con.State = ConnectionState.Open Then
                con.Close()
            End If
        End Try
    End Using
    Dim js As JavaScriptSerializer = New JavaScriptSerializer()
    Return js.Serialize(mOrder)
End Function

返回的JSON结果:

[{"OrderNum":"M531270     ","PN":"VXLD0500510 C            ","StartDate":"/Date(1704344400000)/","EndDate":"/Date(1704517200000)/"}]

三、Ajax绑定问题(图表加载失败)

使用Ajax请求数据并绑定时出现错误,相关代码如下:

google.charts.load("current", { packages: ["timeline"] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
    $.ajax({
        type: 'POST',
        dataType: 'JSON',
        contentType: 'application/json',
        url: 'PlannersWorkBench.aspx/GetOrders',
        success: function (response) {
            drawGraph(response.d);
        }
    });
};
function drawGraph(dataValues) {
    var data = new google.visualization.DataTable();
    data.addColumn({ id: 'OrderNum', label: 'Order Number', type: 'string' });
    data.addColumn({ id: 'PN', label: 'Part Number', type: 'string' });
    data.addColumn({ id: 'StartDate', label: 'Start', type: 'date' });
    data.addColumn({ id: 'EndDate', label: 'End', type: 'date' });
    
    for (var i = 0; i < dataValues.length; i++) {
        data.addRow([dataValues[i].OrderNum, dataValues[i].PN, dataValues[i].StartDate, dataValues[i].EndDate]);
        // data.addRow(['M1', 'PN1', new Date(2023, 1, 4), new Date(2023, 1, 6)]);
    }
    
    var container = document.getElementById('CurrentOrders');
    var chart = new google.visualization.Timeline(container);
    var options = {
        timeline: {
            groupByRowLabel: true
        }
    };
    chart.draw(data, options);
}

问题详情

  • 直接使用返回数据绑定时,图表无法加载,仅显示错误;
  • 排查时发现dataValues.length为136(实际仅1条数据),循环后图表出现136行;硬编码数据虽能显示,但订单号不显示。

解决方案

核心问题分析

  1. 数据类型错误:WebMethod返回的是序列化后的JSON字符串,而非直接的JSON对象,导致dataValues是字符串,length取的是字符串长度而非数组长度;
  2. 日期格式不兼容:返回的日期格式为/Date(时间戳)/,Google Charts Timeline需要JavaScript原生Date对象,无法直接识别该字符串格式;
  3. 多余空格影响显示:返回的OrderNum和PN包含多余空格,可能导致标签显示异常。

修改后的完整代码

google.charts.load("current", { packages: ["timeline"] });
google.charts.setOnLoadCallback(drawChart);

function drawChart() {
    $.ajax({
        type: 'POST',
        dataType: 'JSON',
        contentType: 'application/json',
        url: 'PlannersWorkBench.aspx/GetOrders',
        success: function (response) {
            // 解析JSON字符串为数组对象
            var parsedData = JSON.parse(response.d);
            drawGraph(parsedData);
        },
        error: function(xhr, status, error) {
            // 可选:添加错误处理
            console.error('Ajax请求失败:', error);
        }
    });
};

function drawGraph(dataValues) {
    var data = new google.visualization.DataTable();
    data.addColumn({ id: 'OrderNum', label: 'Order Number', type: 'string' });
    data.addColumn({ id: 'PN', label: 'Part Number', type: 'string' });
    data.addColumn({ id: 'StartDate', label: 'Start', type: 'date' });
    data.addColumn({ id: 'EndDate', label: 'End', type: 'date' });
    
    for (var i = 0; i < dataValues.length; i++) {
        // 处理日期格式:提取时间戳并转为Date对象
        var startTimestamp = parseInt(dataValues[i].StartDate.replace('/Date(', '').replace(')/', ''));
        var endTimestamp = parseInt(dataValues[i].EndDate.replace('/Date(', '').replace(')/', ''));
        var startDate = new Date(startTimestamp);
        var endDate = new Date(endTimestamp);
        
        // 去除多余空格,优化显示
        var orderNum = dataValues[i].OrderNum.trim();
        var partNum = dataValues[i].PN.trim();
        
        data.addRow([orderNum, partNum, startDate, endDate]);
    }
    
    var container = document.getElementById('CurrentOrders');
    var chart = new google.visualization.Timeline(container);
    var options = {
        timeline: {
            groupByRowLabel: true
        }
    };
    chart.draw(data, options);
}

额外优化建议

  • 在WebMethod中可以直接返回List(Of Morder)而非序列化后的字符串,ASP.NET会自动处理JSON序列化,前端无需手动解析;
  • 可以在前端添加错误处理逻辑,便于排查请求失败问题;
  • 若数据量较大,可考虑添加加载状态提示。

内容的提问来源于stack exchange,提问作者SoundWaves

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:12:06