JSON / Highcharts 中的日期

Date in JSON / Highcharts

我在使用 JSON 对象和 Highcharts 插件的图形中绘制日期时间时遇到问题。

我的代码是有组织的:

我的服务器端尽快向我的客户端发送一个 JSON 对象:

        [HttpGet]
    public JsonResult DadosAtendimentosParticularesPorDentistas()
    {

        DateTime DataAtual = DateTime.Now;
        DateTime InicioMes = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);

        var _listaProducao = _session.CreateSQLQuery("SELECT DATA_ATENDIMENTO, VALOR FROM T_LANCAMENTO_PRODUCAO_PARTICULAR " +
                                                   "WHERE DATA_ATENDIMENTO BETWEEN :INICIO AND :FIM")
                                   .SetParameter("INICIO", InicioMes.AddMonths(-3))
                                   .SetParameter("FIM", DataAtual)
                                   .List();



        return Json(_listaProducao, JsonRequestBehavior.AllowGet);
    }

我的客户端收到一个 JSON 对象并进行以下处理:

<script type="text/javascript">

function producaoDentista(data) {

    Highcharts.setOptions({
        global: {
            useUTC: false
        }
    });

    $('#testegrafico').highcharts({

        chart: {
            type: 'spline'
        },
        title: {
            text: 'Grafico de Faturamento',
            x: -20
        },
        subtitle: {
            text: 'Amostragem de Convenio e Particular',
            x: -20
        },
        xAxis: {
            type: "datetime",
            categories: Date,
            tickPixelInterval: 150,
            maxZoom: 5,
            dateTimeLabelFormats: {
                month: '%b %e, %Y',
                year: '%Y'
            }

            //dateTimeLabelFormats: {
            //    month: '%b %e, %Y',
            //    year: '%Y'
            //}
        },
        yAxis: {
            title: {
                text: 'Valor em R$'
            },
            plotLines: [{
                value: 0,
                width: 1,
                color: '#808080'
            }],
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'middle',
                borderWidth: 0
            },
        },
        series: [{

            name: 'Atendimento Particular',
            data: data
            //name: 'Atendimento Particular',
            //data: data,
            //tooltip: {
            //    pointFormat: 'R$:{point.y:.2f}',
            //}
        //}, {
        //    name: 'Atendimento Convênio',
        //    data: [2.0, 3.1, 10, 40.59, 100, 200, 500, 10, 500,11, 33]
        ,}]
    });
}
$(document).ready(function () {
    $.ajax({
        url: 'GraficoAtendimento/DadosAtendimentosParticularesPorDentistas',
        type: 'GET',
        async: true,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (data) {
            producaoDentista(data)
        }
    });
});

</script>

我的 JSON 由以下数据组成:

[["/日期(1418223600000)/",80],["/日期(1415631600000)/",10],["/日期(1415804400000)/",40],["/日期( 1420077600000)/",8],["/日期(1420164000000)/",10],["/日期(1420164000000)/",30],["/日期(1420164000000)/",140],["/日期(1420164000000)/",10],["/日期(1420423200000)/",560]]

图表上的日期显示如下:/Date(1418223600000)

如何解决这个问题?

创建适配器

public class JsonAdapter : JsonResult
{
    /// <summary>
    /// <para></para>
    /// </summary>
    private const string _dateFormat = "dd/MM/yyyy_HH:mm:ss";

    /// <summary>
    /// <para></para>
    /// </summary>
    /// <param name="context"></param>
    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }

        HttpResponseBase response = context.HttpContext.Response;

        if (!String.IsNullOrEmpty(ContentType))
        {
            response.ContentType = ContentType;
        }
        else
        {
            response.ContentType = "application/json";
        }
        if (ContentEncoding != null)
        {
            response.ContentEncoding = ContentEncoding;
        }
        if (Data != null)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            serializer.RegisterConverters(new JavaScriptConverter[] { new DateTimeJavaScriptConverter() });

            response.Write(serializer.Serialize(Data));
        }
    }
}

public class DateTimeJavaScriptConverter : JavaScriptConverter
{
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        return new JavaScriptSerializer().ConvertToType(dictionary, type);
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        if (!(obj is DateTime)) return null;
        DateTime data = (DateTime)obj;
        return new DateString(data == DateTime.MinValue || data == DateTime.MaxValue ? string.Empty : data.ToString("dd/MM/yyyy_HH:mm:ss"));
    }

    public override IEnumerable<Type> SupportedTypes
    {
        get { return new[] { typeof(DateTime) }; }
    }

    private class DateString : Uri, IDictionary<string, object>
    {
        public DateString(string str) : base(str, UriKind.Relative)
        {
        }

        void IDictionary<string, object>.Add(string key, object value)
        {
            throw new NotImplementedException();
        }

        bool IDictionary<string, object>.ContainsKey(string key)
        {
            throw new NotImplementedException();
        }

        ICollection<string> IDictionary<string, object>.Keys
        {
            get { throw new NotImplementedException(); }
        }

        bool IDictionary<string, object>.Remove(string key)
        {
            throw new NotImplementedException();
        }

        bool IDictionary<string, object>.TryGetValue(string key, out object value)
        {
            throw new NotImplementedException();
        }

        ICollection<object> IDictionary<string, object>.Values
        {
            get { throw new NotImplementedException(); }
        }

        object IDictionary<string, object>.this[string key]
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> item)
        {
            throw new NotImplementedException();
        }

        void ICollection<KeyValuePair<string, object>>.Clear()
        {
            throw new NotImplementedException();
        }

        bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> item)
        {
            throw new NotImplementedException();
        }

        void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
        {
            throw new NotImplementedException();
        }

        int ICollection<KeyValuePair<string, object>>.Count
        {
            get { throw new NotImplementedException(); }
        }

        bool ICollection<KeyValuePair<string, object>>.IsReadOnly
        {
            get { throw new NotImplementedException(); }
        }

        bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> item)
        {
            throw new NotImplementedException();
        }

        IEnumerator<KeyValuePair<string, object>> IEnumerable<KeyValuePair<string, object>>.GetEnumerator()
        {
            throw new NotImplementedException();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }
    }
}

然后使用:

return JsonAdapter(_listaProducao, JsonRequestBehavior.AllowGet);

您的问题是 JSON 从 .NET 传输日期的格式不容易被 JavaScript 理解,需要将其转换为整数时间戳以便 HighCharts 使用它。 您可以在服务器端或客户端解决这个问题,但要在客户端这样做,您需要在将数据发送到 HighCharts 之前转换数据,或者为 HighCharts 提供格式函数来进行转换。

在绘制图表之前将数据转换为整数

在这里,您通过将 .NET 提供给您的所有日期字符串解析为时间戳整数来处理您的数据,然后再将其交给 HighCharts。这允许 HighCharts 使用时间戳来格式化。

$(document).ready(function () {

    function parseJsonDateToTimeStamp(value) {
        return parseInt(value.substr(6), 10); // The 6 is for trimming '/Date('
    }

    $.ajax({
        url: 'GraficoAtendimento/DadosAtendimentosParticularesPorDentistas',
        type: 'GET',
        async: true,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (data) {

            // Iterate data and convert all date strings to integers using
            // the parseJsonDateToTimeStamp function above.
            // 
            // Without knowing the JSON structure I cannot show code to do this, but it
            // should be done before calling producaoDentista()
            //

            producaoDentista(data)
        }
    });
});

此函数修剪从 .NET 获取的字符串的第一部分,并将时间戳部分转换为整数以传递给 Date() 构造函数。您应该 运行 此函数针对 JSON 中的每个日期值,当您第一次收到它时,但在您将数据交给 HighCharts 进行渲染之前。

调整 HighCharts 配置以即时格式化

在这里,您修改 HighCharts 配置以在 xAxis 上为其提供格式化程序功能,该功能将在 运行 时间转换您的值。这是一个更简洁的解决方案,但您失去了使用 dateTimeLabelFormats 格式化日期的正常能力,必须手动使用 HighCharts.dataFormat()

$('#testegrafico').highcharts({

    chart: {
        type: 'spline'
    },
    title: {
        text: 'Grafico de Faturamento',
        x: -20
    },
    subtitle: {
        text: 'Amostragem de Convenio e Particular',
        x: -20
    },
    xAxis: {
        type: "datetime",
        categories: Date,
        tickPixelInterval: 150,
        maxZoom: 5,
        labels: {
            formatter: function() {

                // Parse the date string to an integer and format it
                return HighCharts.dateFormat('%b, %e, %Y', parseInt(this.value.substr(6), 10));
            }
        }
    },
    yAxis: {
        title: {
            text: 'Valor em R$'
        },
        plotLines: [{
            value: 0,
            width: 1,
            color: '#808080'
        }],
        legend: {
            layout: 'vertical',
            align: 'right',
            verticalAlign: 'middle',
            borderWidth: 0
        },
    },
    series: [{

        name: 'Atendimento Particular',
        data: data
        //name: 'Atendimento Particular',
        //data: data,
        //tooltip: {
        //    pointFormat: 'R$:{point.y:.2f}',
        //}
    //}, {
    //    name: 'Atendimento Convênio',
    //    data: [2.0, 3.1, 10, 40.59, 100, 200, 500, 10, 500,11, 33]
    ,}]
});