[英]custom chart using google sheets data
我是新手,所以请多多包涵:)
我有一个带有列的谷歌表:'姓名,A-Score,T-Score,R-Score,P-Score'
分数是从 0 到 20 的数值。这些数据需要转换为一个特殊但非常简单的图表,我认为在现有的图表选项中不可用。 我试图编写一些代码(即从许多堆栈溢出答案组装)来构建我需要的图形:
问题:
我是否错过了现有图表选项中的一些基本内容,可以让我以这种方式绘制图表?
...如果不是,这可以在带有 google-scripts 或扩展的工作表中完成吗?
我怎么能有效地为几百行创建单独的图表(导出到 png)? 也许通过某种方式重用我到目前为止的代码。
非常感谢!
//javascript
//data from sheets
var Name = "santayan";
var Activist = 12;
var Theorist = 9;
var Reflector = 14;
var Pragmatist = 12;
//set up canvas
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
//set up click target
var link = document.getElementById("link");
//reset coordinates and white bg
ctx.translate(200, 200);
ctx.beginPath();
ctx.rect(-200, -200, 400, 400);
ctx.fillStyle = "white";
ctx.fill();
//plot main graph
ctx.lineCap = "round";
ctx.lineWidth = 5;
ctx.strokeStyle = "#806";
ctx.beginPath();
ctx.moveTo(Theorist * 10, 0);
ctx.lineTo(0, Reflector * 10);
ctx.lineTo(Activist * -10, 0);
ctx.lineTo(0, Pragmatist * -10);
ctx.closePath();
ctx.stroke();
//plot axes and labels
ctx.strokeStyle = "#d3d3d3";
ctx.lineWidth = 1;
ctx.moveTo(-200, 0);
ctx.lineTo(200, 0);
ctx.moveTo(0, -200);
ctx.lineTo(0, 200);
ctx.stroke();
ctx.font = "1em Helvetica";
ctx.textAlign = "right";
ctx.fillStyle = "#806";
ctx.fillText(Name, 195, -185);
ctx.font = ".5em Helvetica";
ctx.fillText("LEARNING STYLE", 195, -170);
ctx.fillStyle = "#000";
ctx.textAlign = "center";
ctx.fillText("ACTIVIST", -170, 12);
ctx.fillText("THEORIST", 170, -5);
ctx.rotate(Math.PI / 2);
ctx.fillText("PRAGMATIST", -165, 12);
ctx.fillText("REFLECTOR", 170, -5);
//click handler
function downloadImage() {
link.setAttribute("download", Name + " LearningStyle.png");
link.setAttribute(
"href",
canvas.toDataURL("image/png").replace("image/png", "image/octet-stream")
);
}
//html
<div class="container"> <a id="link" OnClick=downloadImage()><canvas id="myCanvas" width="400" height="400" </canvas></a> click on the image to download</div>
//css
a{cursor:pointer}body{font-family:Helvetica,Sans;font-size:.8em;text-align:right;background-color:#888;margin:0}.container{width:440px;height:460px;display:block;background-color:#aaa;margin:0 auto;padding:10px}canvas{box-sizing:border-box;background:#fff;padding:20px;margin:0 auto;border:1px solid grey;border-box:inner}
不幸的是,谷歌目前没有此类图表的选项。 尽管您的代码看起来画得很好! 要使用工作表进行此操作,您需要使用HtmlService来呈现客户端 HTML 和 JavaScript。 然后要在客户端和服务器之间进行通信(应用脚本与您的工作表和驱动器交互),您将使用google.script.run...
,请参阅客户端服务器通信。
这是最有效的方法吗? 可能不是。 然而,这是完全在 Apps Script 中执行此操作的一种相当简洁的方式。
我会用 10 行,然后是 20 行,然后是 50 行等来测试它。以防它被太多的东西淹没。
您的 Apps 脚本项目中需要两个文件:
<!DOCTYPE html>
<html>
<head>
<style>
a {cursor:pointer;}body{font-family:Helvetica,Sans;font-size:.8em;text-align:right;background-color:#888;margin:0}.container{width:440px;height:460px;display:block;background-color:#aaa;margin:0 auto;padding:10px}canvas{box-sizing:border-box;background:#fff;padding:20px;margin:0 auto;border:1px solid grey;border-box:inner}
</style>
</head>
<body>
<div class="container">
<canvas id="myCanvas" width="400" height="400"></canvas>
</div>
</body>
<script>
// Your drawing code wrapped in a function
function drawChart(Name, Activist, Theorist, Reflector, Pragmatist){
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
//reset coordinates and white bg
ctx.translate(200, 200);
ctx.beginPath();
ctx.rect(-200, -200, 400, 400);
ctx.fillStyle = "white";
ctx.fill();
//plot main graph
ctx.lineCap = "round";
ctx.lineWidth = 5;
ctx.strokeStyle = "#806";
ctx.beginPath();
ctx.moveTo(Theorist * 10, 0);
ctx.lineTo(0, Reflector * 10);
ctx.lineTo(Activist * -10, 0);
ctx.lineTo(0, Pragmatist * -10);
ctx.closePath();
ctx.stroke();
//plot axes and labels
ctx.strokeStyle = "#d3d3d3";
ctx.lineWidth = 1;
ctx.moveTo(-200, 0);
ctx.lineTo(200, 0);
ctx.moveTo(0, -200);
ctx.lineTo(0, 200);
ctx.stroke();
ctx.font = "1em Helvetica";
ctx.textAlign = "right";
ctx.fillStyle = "#806";
ctx.fillText(Name, 195, -185);
ctx.font = ".5em Helvetica";
ctx.fillText("LEARNING STYLE", 195, -170);
ctx.fillStyle = "#000";
ctx.textAlign = "center";
ctx.fillText("ACTIVIST", -170, 12);
ctx.fillText("THEORIST", 170, -5);
ctx.rotate(Math.PI / 2);
ctx.fillText("PRAGMATIST", -165, 12);
ctx.fillText("REFLECTOR", 170, -5);
// Had to add this to reset the canvas properly
ctx.resetTransform();
}
function getImage(Name) {
var canvas = document.getElementById("myCanvas");
var dataURL = canvas.toDataURL("image/png");
return dataURL;
}
function notification(msg){
let message = document.createElement("p");
message.textContent = msg
document.body.appendChild(message)
}
function main(data){
// data is 2D array
data.forEach(row => {
drawChart(row[0], row[1], row[2], row[3], row[4]);
let png = getImage();
google.script.run.withSuccessHandler(notification).saveToDrive(row[0], png)
})
}
google.script.run.withSuccessHandler(main).getData();
</script>
</html>
function getData() {
let file = SpreadsheetApp.getActive();
let sheet = file.getSheetByName("Sheet1");
let range = sheet.getDataRange();
let values = range.getValues();
// Get rid of headers
values.shift()
return values;
}
function saveToDrive(name, dataURL){
// https://stackoverflow.com/questions/56092146/convert-data-uri-using-google-apps-script-blob
var type = (dataURL.split(";")[0]).replace('data:','');
var imageUpload = Utilities.base64Decode(dataURL.split(",")[1]);
var blob = Utilities.newBlob(imageUpload, type, name + ".png");
let newFile = DriveApp.createFile(blob);
newFile.setName(name)
return name + "'s chart saved!"
}
function main(){
let html = HtmlService.createHtmlOutputFromFile("chart.html");
SpreadsheetApp.getUi().showSidebar(html);
}
电子表格如下所示:
Code.gs
运行main
来启动脚本并对其进行授权。SpreadsheetApp.getUi().showSidebar(html);
google.script.run
) 发送异步请求,以从电子表格中获取所有数据,它将以二维数组的形式接收。ctx.resetTransform();
并在绘图 function 的末尾正确重置 ctx。出现侧栏和图表。 这么少的图纸,我只看到了从白色到最终图的go。 之后,在图表下方,开始出现完成消息:
然后,如果您将 go 到您的主驱动器文件夹,您应该会看到 PNG 文件!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.