如何使用 Tabletop.js 从 Google 工作表中提取数据以绘制热图图表?

How to pull data from Google sheets using Tabletop.js for a plotly heatmap chart?

我正在尝试使用 Tabletop.js 从 Google 张(如 json)中提取的数据绘制热图图表。 到目前为止,我已经完成了从 Googleseet 提取数据为 json 并将其显示在控制台中的操作。但是,事实证明,让它显示为热图很麻烦。任何帮助将不胜感激。

var publicSpreadsheetUrl = 'https://docs.google.com/spreadsheets/d/1BFPjROVypCGNeLxhk5_PW6PoOb4FDzJsL3DEOEdW_Rc/edit?usp=sharing';

function init() {
  Tabletop.init({
    key: publicSpreadsheetUrl,
    callback: showInfo,
    simpleSheet: true
  })
}

function showInfo(data, tabletop) {
  console.log(data);
}

window.addEventListener('DOMContentLoaded', init)

var data = [{
  graphdata,
  type: 'heatmap'
}];

Plotly.newPlot('myDiv', data1);

Plotly 的热图需要一个二维数组(y 是第一个索引,x 第二个)作为其 z 值。 tabletopreturns一个JSON,所以需要解析成数组

var publicSpreadsheetUrl = 'https://docs.google.com/spreadsheets/d/1BFPjROVypCGNeLxhk5_PW6PoOb4FDzJsL3DEOEdW_Rc/edit?usp=sharing';

function init() {
  Tabletop.init({
    key: publicSpreadsheetUrl,
    callback: showPlot,
    simpleSheet: true
  })
}

function showPlot(data, tabletop) {
  var xValues = []; //all the values which are shown on the x-axis
  var yValues = []; //all the values which are shown on the y-axis

  //get all possible x and y-values
  for (var i = 0; i < data.length; i++) {
    if (xValues.indexOf(data[i].x) === -1) {
      xValues.push(data[i].x);
    }
    if (yValues.indexOf(data[i].y) === -1) {
      yValues.push(data[i].y);
    }
  }
  
  //create an empty array for all possible z-values based on the dimensions of x and y
  var zValues = new Array(yValues.length).fill(0).map(row => new Array(xValues.length).fill(0));

  var x = 0;
  var y = 0;

  for (i = 0; i < data.length; i++) {
    x = xValues.indexOf(data[i].x);
    y = yValues.indexOf(data[i].y);
    if (x !== -1 && y !== -1) {
      zValues[y][x] = parseFloat(data[i].z);
    }
  }

  //the data which is passed to Plotly
  var plotlyData = [{
    x: xValues,
    y: yValues,
    z: zValues,
    type: 'heatmap'
  }];
  
  //finally draw the plot
  Plotly.plot('myPlot', plotlyData);
}

init()
<script src="https://cdnjs.cloudflare.com/ajax/libs/tabletop.js/1.5.1/tabletop.min.js"></script>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="myPlot"></div>

请看我的评论。我已经描述了如何将数据转换为所需的格式。我曾经使用 lodash 来做到这一点。

var publicSpreadsheetUrl = 'https://docs.google.com/spreadsheets/d/1BFPjROVypCGNeLxhk5_PW6PoOb4FDzJsL3DEOEdW_Rc/edit?usp=sharing';

    function init() {
        Tabletop.init({
            key: publicSpreadsheetUrl,
            callback: showInfo,
            simpleSheet: true
        })
    }

    function showInfo(data, tabletop) {
        if (!data || !data.length) {
            throw new Error('Unable to get any data from the spreadsheet');
        }

        // First we want to parse some values
        var parsed = data.map(val => {
            return {month: val.x, year: parseInt(val.y), z: parseFloat(val.z)};
        });


        // I'm going to hardcode the months here as we wanna keep the order.
        // You might consider using something like moment.js to get month names.
        var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

        var minYear = _.minBy(parsed, p => p.year);
        var maxYear = _.maxBy(parsed, p => p.year);

        // Create the range of years. This is going to be our Y axis.
        var years = _.range(minYear.year, maxYear.year);

        // Now we are going to iterate over months and years, searching for values.
        // By doing this we're going to end up with the data format accepted by plotly.
        // https://plot.ly/javascript/heatmaps/#heatmap-with-categorical-axis-labels
        var zValues = _.map(months, m => {
            return _.map(years, y => {
                var matchingElement = _.find(parsed, p => p.year === y && p.month === m);
                if (matchingElement) {
                    return matchingElement.z;
                }
                // If we haven't found the value fill it with null.
                return null;
            })
        })

        var chartData = [{
            z: zValues, x: months, y: years,
            type: 'heatmap'
        }];

        Plotly.newPlot('myDiv', chartData);
    }

    window.addEventListener('DOMContentLoaded', init)
<div id="myDiv"></div>

<script src='https://cdnjs.cloudflare.com/ajax/libs/tabletop.js/1.5.1/tabletop.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js'></script>

<!-- Latest compiled and minified plotly.js JavaScript -->
<script type="text/javascript" src="https://cdn.plot.ly/plotly-latest.min.js"></script>