未捕获的TypeError:dp [ds.categoryField] .setFullYear不是Object.AmCharts.baseYearInitialize

时间:2017-04-11 13:41:34

标签: javascript jquery json amcharts amstock

在Amcharts Stock图表中,我正在尝试显示数据,我从数据库中以json格式获取此数据。它显示的错误,“未捕获的TypeError:dp [ds.categoryField] .setFullYear不是Object.AmCharts.baseYearInitialize ”中的函数。 JSON数组很好,如果我只保留一个数据集,那么它工作正常,只要我输入一年,其数据已经是json形式,它会显示错误。

var chart;
var SER = [];
//var SER;

first();

function first() {
    for (var i = 0; i < 5; i++) {
        generateChartData(2000 + i);
    }
    //SER = JSON.stringify(SER1);
    //console.log(SER1);
    dd();
}

function generateChartData(year) {
    var firstDate = new Date(year, 0, 1);
    var temp = [];
    for (var i = 0; i < 365; i++) {
        var newDate = new Date(firstDate);
        newDate.setDate(newDate.getDate() + i);
        newDate = ((newDate.getMonth() + 1) < 10 ? "0" + (newDate.getMonth() + 1) : (newDate.getMonth() + 1)) +
            "-" + (newDate.getDate() < 10 ? "0" + newDate.getDate() : newDate.getDate()) +
            "-" + year;
        temp.push({
            date: newDate,
            value: Math.round(Math.random() * (40 + i)) + 100 + i
        });
    }
    SER.push(temp);
}

function dd() {
    AmCharts.addInitHandler(function(chart) {
        AmCharts.baseYearInitialize = function(chart) {
            for (var x = 0; x < chart.dataSets.length; x++) {
                var ds = chart.dataSets[x];
                if (ds.baseYear !== undefined) {
                    for (var i = 0; i < ds.dataProvider.length; i++) {
                        var dp = ds.dataProvider[i];  dp[ds.categoryField].setFullYear(ds.baseYear);
                    }
                }
            }
        }
        AmCharts.baseYearInitialize(chart);
    }, ["stock"]);
    
    chart = AmCharts.makeChart("chartdiv", {
        "type": "stock",
        "theme": "light",
        "dataSets": [{
            "title": "2000",
            "fieldMappings": [{
                "fromField": "value",
                "toField": "value"
            }],
            "dataProvider": SER[0],
            "categoryField": "date"
        }
        /* keeping more than one dataset showing error
        , {
            "title": "2001",
            "fieldMappings": [{
                "fromField": "value",
                "toField": "value"
            }],
            "dataProvider": SER[1],
            "categoryField": "date",
            "compared": true,
            "baseYear": 2000
        }, {
            "title": "2002",
            "fieldMappings": [{
                "fromField": "value",
                "toField": "value"
            }
        */
        ],
        "panels": [{
            "title": "Value",
            "categoryAxis": {},
          	"dateFormats": 'DD-MM-YYYY',
            "stockGraphs": [{
                "id": "g1",
                "valueField": "value",
                "lineThickness": 2,
                "comparable": true,
                "compareField": "value",
                "balloonText": "[[title]]:<b>[[value]]</b>",
                "compareGraphBalloonText": "[[title]]:<b>[[value]]</b>",
                "compareGraph": {
                    "dashLength": 5,
                    "lineThickness": 2
                }
            }],
            "stockLegend": {
                "periodValueTextComparing": "[[percents.value.close]]%",
                "periodValueTextRegular": "[[value.close]]"
            }
        }],
        "panelsSettings": {
            "recalculateToPercents": "never"
        },
        "chartScrollbarSettings": {
            "graph": "g1"
        },
        "chartCursorSettings": {
            "valueBalloonsEnabled": true,
            "fullWidth": true,
            "cursorAlpha": 0.1,
            "valueLineBalloonEnabled": true,
            "valueLineEnabled": true,
            "valueLineAlpha": 0.5
        },
        "periodSelector": {
            "position": "bottom",
            "periods": [{
                "period": "MM",
                "selected": true,
                "count": 1,
                "label": "1 month"
            }, {
                "period": "YYYY",
                "count": 1,
                "label": "1 year"
            }, {
                "period": "YTD",
                "label": "YTD"
            }, {
                "period": "MAX",
                "label": "MAX"
            }]
        }

    });
    $('document').ready(function() {
        $('#submit').on('click', function() {
            add(document.getElementById('year').value);
        });
    });
}

function add(yr) {
    chart.dataSets.push({
        "title": yr,
        "fieldMappings": [{
            "fromField": "value",
            "toField": "value"
        }],
        "dataProvider": SER[yr-2000],
        "categoryField": "date",
        "compared": true,
        "baseYear": 2000
    });
    AmCharts.baseYearInitialize(chart);
    chart.validateData();
}
#chartdiv {
                width: 100%;
                height: 500px;
                font-family: Verdana;
                font-size: 12px;
            }
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
        <script type="text/javascript" src="https://www.amcharts.com/lib/3/amcharts.js"></script>
        <script type="text/javascript" src="https://www.amcharts.com/lib/3/serial.js"></script>
        <script type="text/javascript" src="https://www.amcharts.com/lib/3/themes/light.js"></script>
        <script type="text/javascript" src="https://www.amcharts.com/lib/3/amstock.js"></script>
        <input type="text" id="year"><input type="submit" id="submit">
        <div id="chartdiv"></div>

我将日期格式称为“DD-MM-YYYY”。 为什么会出现这个错误?

1 个答案:

答案 0 :(得分:0)

该插件假定日期已经是日期对象。由于您正在使用字符串日期,因此您需要在将日期对象添加到dataProvider之前将其转换为日期对象,或者更新插件以将字符串日期转换为日期对象。

如果您使用的是基于字符串的日期,则必须设置dataDateFormat,以便图表知道如何正确解析日期。您在generateChartData函数中生成的dataProvider中的字符串日期实际上是“MM-DD-YYYY”格式,因此您需要在图表配置的顶层设置dataDateFormat: "MM-DD-YYYY"

chart = AmCharts.makeChart("chartdiv", {
  // ...
  "dataDateFormat": "MM-DD-YYYY",
  // ...
}

从那里开始,您需要更新插件以检查setFullYear是否是该数据点的函数,并在使用{{3}设置基准年之前将其转换为日期对象}:

  AmCharts.addInitHandler(function(chart) {
    AmCharts.baseYearInitialize = function(chart) {
      for (var x = 0; x < chart.dataSets.length; x++) {
        var ds = chart.dataSets[x];
        if (ds.baseYear !== undefined) {
          for (var i = 0; i < ds.dataProvider.length; i++) {
            var dp = ds.dataProvider[i];
            // if this is not a date object (i.e. setFullYear is not defined) convert it using AmCharts.stringToDate and your chart's dataDateFormat)
            if (!dp[ds.categoryField].setFullYear) {
              dp[ds.categoryField] = AmCharts.stringToDate(dp[ds.categoryField], chart.dataDateFormat);
            }
            dp[ds.categoryField].setFullYear(ds.baseYear);
          }
        }
      }
    }
    AmCharts.baseYearInitialize(chart);
  }, ["stock"]);

在将数据添加到dataProvider之前,我还调整了代码以检查输入是否为数字和有效的数组元素:

var chart;
var SER = [];
//var SER;

first();

function first() {
  for (var i = 0; i < 5; i++) {
    generateChartData(2000 + i);
  }
  //SER = JSON.stringify(SER1);
  //console.log(SER1);
  dd();
}

function generateChartData(year) {
  var firstDate = new Date(year, 0, 1);
  var temp = [];
  for (var i = 0; i < 365; i++) {
    var newDate = new Date(firstDate);
    newDate.setDate(newDate.getDate() + i);
    newDate = ((newDate.getMonth() + 1) < 10 ? "0" + (newDate.getMonth() + 1) : (newDate.getMonth() + 1)) +
      "-" + (newDate.getDate() < 10 ? "0" + newDate.getDate() : newDate.getDate()) +
      "-" + year;
    temp.push({
      date: newDate,
      value: Math.round(Math.random() * (40 + i)) + 100 + i
    });
  }
  SER.push(temp);
}

function dd() {
  AmCharts.addInitHandler(function(chart) {
    AmCharts.baseYearInitialize = function(chart) {
      for (var x = 0; x < chart.dataSets.length; x++) {
        var ds = chart.dataSets[x];
        if (ds.baseYear !== undefined) {
          for (var i = 0; i < ds.dataProvider.length; i++) {
            var dp = ds.dataProvider[i];
            // if this is not a date object (i.e. setFullYear is not defined) convert it using AmCharts.stringToDate and your chart's dataDateFormat)
            if (!dp[ds.categoryField].setFullYear) {
              dp[ds.categoryField] = AmCharts.stringToDate(dp[ds.categoryField], chart.dataDateFormat);
            }
            dp[ds.categoryField].setFullYear(ds.baseYear);
          }
        }
      }
    }
    AmCharts.baseYearInitialize(chart);
  }, ["stock"]);

  chart = AmCharts.makeChart("chartdiv", {
    "type": "stock",
    "theme": "light",
    "dataDateFormat": "MM-DD-YYYY",
    "dataSets": [{
        "title": "2000",
        "fieldMappings": [{
          "fromField": "value",
          "toField": "value"
        }],
        "dataProvider": SER[0],
        "categoryField": "date"
      }
      /* keeping more than one dataset showing error
      , {
          "title": "2001",
          "fieldMappings": [{
              "fromField": "value",
              "toField": "value"
          }],
          "dataProvider": SER[1],
          "categoryField": "date",
          "compared": true,
          "baseYear": 2000
      }, {
          "title": "2002",
          "fieldMappings": [{
              "fromField": "value",
              "toField": "value"
          }
      */
    ],
    "panels": [{
      "title": "Value",
      "categoryAxis": {},
      "dateFormats": 'DD-MM-YYYY',
      "stockGraphs": [{
        "id": "g1",
        "valueField": "value",
        "lineThickness": 2,
        "comparable": true,
        "compareField": "value",
        "balloonText": "[[title]]:<b>[[value]]</b>",
        "compareGraphBalloonText": "[[title]]:<b>[[value]]</b>",
        "compareGraph": {
          "dashLength": 5,
          "lineThickness": 2
        }
      }],
      "stockLegend": {
        "periodValueTextComparing": "[[percents.value.close]]%",
        "periodValueTextRegular": "[[value.close]]"
      }
    }],
    "panelsSettings": {
      "recalculateToPercents": "never"
    },
    "chartScrollbarSettings": {
      "graph": "g1"
    },
    "chartCursorSettings": {
      "valueBalloonsEnabled": true,
      "fullWidth": true,
      "cursorAlpha": 0.1,
      "valueLineBalloonEnabled": true,
      "valueLineEnabled": true,
      "valueLineAlpha": 0.5
    },
    "periodSelector": {
      "position": "bottom",
      "periods": [{
        "period": "MM",
        "selected": true,
        "count": 1,
        "label": "1 month"
      }, {
        "period": "YYYY",
        "count": 1,
        "label": "1 year"
      }, {
        "period": "YTD",
        "label": "YTD"
      }, {
        "period": "MAX",
        "label": "MAX"
      }]
    }

  });
  $('document').ready(function() {
    $('#submit').on('click', function() {
      add(+document.getElementById('year').value);
    });
  });
}

function add(yr) {
  if (!isNaN(yr) && SER[yr - 2000] !== undefined) {
    chart.dataSets.push({
      "title": yr,
      "fieldMappings": [{
        "fromField": "value",
        "toField": "value"
      }],
      "dataProvider": SER[yr - 2000],
      "categoryField": "date",
      "compared": true,
      "baseYear": 2000
    });
    AmCharts.baseYearInitialize(chart);
    chart.validateData();
  }
}
#chartdiv {
  width: 100%;
  height: 500px;
  font-family: Verdana;
  font-size: 12px;
}
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="https://www.amcharts.com/lib/3/amcharts.js"></script>
<script type="text/javascript" src="https://www.amcharts.com/lib/3/serial.js"></script>
<script type="text/javascript" src="https://www.amcharts.com/lib/3/themes/light.js"></script>
<script type="text/javascript" src="https://www.amcharts.com/lib/3/amstock.js"></script>
<input type="text" id="year"><input type="submit" id="submit">
<div id="chartdiv"></div>