简体   繁体   English

带有 JSON 列表变量的 ChartJS 散点图不起作用

[英]ChartJS Scatter plot with JSON list variable not working

I want to plot scatter plots from a JSON variable (list of lists; in the format needed for Chart JS scatter plots) that I passed from Flask.我想从我从 Flask 传递的 JSON 变量(列表列表;以 Chart JS 散点图所需的格式)绘制散点图。

render_template('chart.html',data2 = data2)

The below code when I manually create datasets using jinja variable {{data2}} is working :当我使用 jinja 变量 {{data2}} 手动创建数据集时,以下代码正在运行

var chartData = {
        datasets : [{
            label: 'Cluster 1',
            fill: false,
            showLine: false,
            lineTension: 0.1,
            backgroundColor: "green",
            borderColor: "black", // The main line color
            borderCapStyle: 'square',
            borderDash: [], // try [5, 15] for instance
            borderDashOffset: 0.0,
            borderJoinStyle: 'miter',
            pointBorderColor: "green",
            pointBackgroundColor: "green",
            pointBorderWidth: 1,
            pointHoverRadius: 8,
            pointHoverBackgroundColor: "yellow",
            pointHoverBorderColor: "brown",
            pointHoverBorderWidth: 2,
            pointRadius: 4,
            pointHitRadius: 10,
            // notice the gap in the data and the spanGaps: true
            data :{{data2[0]}},
            spanGaps: true,
        },
        {
            label: 'Cluster 2',
            fill: false,
            showLine: false,
            lineTension: 0.1,
            backgroundColor: "blue",
            borderColor: "black", // The main line color
            borderCapStyle: 'square',
            borderDash: [], // try [5, 15] for instance
            borderDashOffset: 0.0,
            borderJoinStyle: 'miter',
            pointBorderColor: "blue",
            pointBackgroundColor: "blue",
            pointBorderWidth: 1,
            pointHoverRadius: 8,
            pointHoverBackgroundColor: "yellow",
            pointHoverBorderColor: "brown",
            pointHoverBorderWidth: 2,
            pointRadius: 4,
            pointHitRadius: 10,
            // notice the gap in the data and the spanGaps: true
            data :{{data2[1]}},
            spanGaps: true,
        },
        {
            label: 'Cluster 3',
            fill: false,
            showLine: false,
            lineTension: 0.1,
            backgroundColor: "red",
            borderColor: "black", // The main line color
            borderCapStyle: 'square',
            borderDash: [], // try [5, 15] for instance
            borderDashOffset: 0.0,
            borderJoinStyle: 'miter',
            pointBorderColor: "red",
            pointBackgroundColor: "red",
            pointBorderWidth: 1,
            pointHoverRadius: 8,
            pointHoverBackgroundColor: "yellow",
            pointHoverBorderColor: "brown",
            pointHoverBorderWidth: 2,
            pointRadius: 4,
            pointHitRadius: 10,
            // notice the gap in the data and the spanGaps: true
            data :{{data2[2]}},
            spanGaps: true,
        },.....so on

 // get chart canvas
      var holder = document.getElementById("myChart2");
      var ctx = document.getElementById("myChart2").getContext("2d");

      // create the chart using the chart canvas
      var myChart = new Chart(ctx, {
        type: 'scatter',
        data: chartData,
        options: {
          scales: {
            xAxes: [{
              display: true,
              ticks: {
                beginAtZero: true,
                autoSkip: true,
                autoSkipPadding: 30,
                stepSize: 500,
                maxTicksLimit: 10        
              },
              scaleLabel: {
                display: true,
                labelString: 'Days',
                fontStyle: 'bold'
              }      
            }],
            yAxes: [{
              display: true,
              scaleLabel: {
                display: true,
                labelString: 'Oil Rate',
                fontStyle: 'bold'
              }
            }]
          }
        }
      });

But when I use tojson and use the same variable in a for loop its not working (Rendering a blank chart) :但是当我使用 tojson 并在 for 循环中使用相同的变量时,它不起作用(呈现空白图表)

var ds = []    
var d2 = {{data2|tojson}}
      for (var j=0; j < {{o}}; j++){
      ds.push ({
            label: 'Cluster' +j,
            fill: false,
            showLine: false,
            lineTension: 0.1,
            backgroundColor: colorlist[j],
            borderColor: colorlist[j], // The main line color
            borderCapStyle: 'square',
            borderDash: [], // try [5, 15] for instance
            borderDashOffset: 0.0,
            borderJoinStyle: 'miter',
            pointBorderColor: "green",
            pointBackgroundColor: "green",
            pointBorderWidth: 1,
            pointHoverRadius: 8,
            pointHoverBackgroundColor: "yellow",
            pointHoverBorderColor: "brown",
            pointHoverBorderWidth: 2,
            pointRadius: 4,
            pointHitRadius: 10,
            // notice the gap in the data and the spanGaps: true
            data :d2[j],
            spanGaps: true,
        });
        }     
      var chartData2 = {
        datasets : ds
       }

      var holder = document.getElementById("myChart2");
      var ctx = document.getElementById("myChart2").getContext("2d");

      // create the chart using the chart canvas
      var myChart2 = new Chart(ctx, {
        type: 'scatter',
        data: chartData2,
        options: {
          scales: {
            xAxes: [{
              display: true,
              ticks: {
                beginAtZero: true,
                autoSkip: true,
                autoSkipPadding: 30,
                stepSize: 500,
                maxTicksLimit: 10        
              },
              scaleLabel: {
                display: true,
                labelString: 'Days',
                fontStyle: 'bold'
              }      
            }],
            yAxes: [{
              display: true,
              scaleLabel: {
                display: true,
                labelString: 'Oil Rate',
                fontStyle: 'bold'
              }
            }]
          }
        }
      });

For more clarity, this is how my data2 was created for scatter chart js:为了更清楚,这是我的 data2 是如何为散点图 js 创建的:

x2 = {}
y2 = {}
data = {}
for i in n:
   x2[i] = list(df_no_anamolies['Days'[df_no_anamolies["clusters_oilvsDays"]==i])
   y2[i] = list(df_no_anamolies['Oil_rate(stb/d)'[df_no_anamolies["clusters_oilvsDays"]==i])
   T = []
   for j,k in zip(x2[i],y2[i]):
      T.append({'x': j, 'y': k})
   data[i] = str(T).replace('\'', '')
dt2 = list(data.items())
data2 = []
for i in range(len(dt2)):
    data2.append(dt2[i][1])

This how my data2 looks like:这是我的 data2 的样子:

['[{x: 429, y: 21862.782000000003}, {x: 430, y: 21769.1868}]', 
 '[{x: 431, y: 21752.5183}, {x: 432, y: 21406.0022}]', 
 '[{x: 433, y: 20823.7369},'[{x: 434, y: 21101.5033}]', 
 '[{x: 435, y: 22031.354}, {x: 434, y: 21101.5033}]'....]

Can someone help me with how to do this with a loop.有人可以帮助我如何用循环来做到这一点。

I think you'll need to parse those json strings before passing them to chart.js我认为你需要在将它们传递给 chart.js 之前解析这些 json 字符串

var chartData2 = {
        datasets : [{label: 'Cluster 1',
            fill: false,
            showLine: false,
            lineTension: 0.1,
            backgroundColor: "green",
            borderColor: "black",
            borderCapStyle: 'square',
            borderDash: [], 
            borderDashOffset: 0.0,
            borderJoinStyle: 'miter',
            pointBorderColor: "green",
            pointBackgroundColor: "green",
            pointBorderWidth: 1,
            pointHoverRadius: 8,
            pointHoverBackgroundColor: "yellow",
            pointHoverBorderColor: "brown",
            pointHoverBorderWidth: 2,
            pointRadius: 4,
            pointHitRadius: 10,
            data : JSON.parse( {{ data[1] }} ),
            spanGaps: true,
       }]      
}

Your "Y" objects are Decimal objects and the JsonEnconder doesn't accept Decimal objects.您的“Y”对象是 Decimal 对象,而 JsonEnconder 不接受 Decimal 对象。 I usually just create a subclass of the json.JSONEncoder.我通常只创建 json.JSONEncoder 的子类。

class DecimalEncoder(json.JSONEncoder):
    def _iterencode(self, o, markers=None):
        if isinstance(o, decimal.Decimal):
            return (str(o) for o in [o])
        return super(DecimalEncoder, self)._iterencode(o, markers)

then you can use it as然后你可以用它作为

json.dumps({'Y': decimal.Decimal('21769.1868')}, cls=DecimalEncoder) json.dumps({'Y': decimal.Decimal('21769.1868')}, cls=DecimalEncoder)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM