我在我的网站上使用amCharts库。在侧边栏我正在显示图表快照(缩略图),如果点击它会进入图表本身。要显示这些快照,应该预先生成它们,但是当我在图表页面上时,我只能这样做。此外,我需要每天按计划更新这些快照。我需要一种方法(如果可能的话)生成这些快照,而无需访问网页,最好是通过命令行。
目前我将图表保存为服务器端的图像:
<script src="/static/amcharts/amcharts.js" type="text/javascript"></script>
<script src="/static/amcharts/serial.js" type="text/javascript"></script>
<script src="/static/amcharts/amstock.js" type="text/javascript"></script>
<script src="/static/amcharts/exporting/amexport.js" type="text/javascript"></script>
<script src="/static/amcharts/exporting/rgbcolor.js" type="text/javascript"></script>
<script src="/static/amcharts/exporting/canvg.js" type="text/javascript"></script>
<script src="/static/amcharts/exporting/filesaver.js" type="text/javascript"></script>
<script>
var cdata = {{ chartData|safe }};
AmCharts.ready(function () {
generateChartData();
createStockChart();
});
var chartData = [];
function generateChartData() {
for (var i = 0; i < cdata.length; i++)
{
chartData.push({
date: new Date(cdata[i]["date"]),
value: cdata[i]["value"],
volume: cdata[i]["volume"]
});
}
}
var chart;
function createStockChart() {
chart = new AmCharts.AmStockChart();
chart.exportConfig = {
menuItems: []
};
chart.addListener('rendered', function (event) {
chart.AmExport.output({format:"png", output: 'datastring'},
function(data) {
$.post("/charts/save_chart_snapshot/", {
imageData: encodeURIComponent(data)
});
});
});
chart.pathToImages = "/static/amcharts/images/";
var categoryAxesSettings = new AmCharts.CategoryAxesSettings();
categoryAxesSettings.minPeriod = "DD";
chart.categoryAxesSettings = categoryAxesSettings;
// DATASETS //////////////////////////////////////////
var dataSet = new AmCharts.DataSet();
dataSet.color = "#9cc11a";
dataSet.fieldMappings = [{
fromField: "value",
toField: "value"
}, {
fromField: "volume",
toField: "volume"
}];
dataSet.dataProvider = chartData;
dataSet.categoryField = "date";
// set data sets to the chart
chart.dataSets = [dataSet];
// PANELS ///////////////////////////////////////////
// first stock panel
var stockPanel1 = new AmCharts.StockPanel();
stockPanel1.showCategoryAxis = false;
stockPanel1.title = "Value";
stockPanel1.percentHeight = 70;
// graph of first stock panel
var graph1 = new AmCharts.StockGraph();
graph1.valueField = "value";
graph1.type = "smoothedLine";
graph1.lineThickness = 2;
graph1.bullet = "round";
graph1.bulletBorderColor = "#FFFFFF";
graph1.bulletBorderAlpha = 1;
graph1.bulletBorderThickness = 3;
stockPanel1.addStockGraph(graph1);
// create stock legend
var stockLegend1 = new AmCharts.StockLegend();
stockLegend1.valueTextRegular = " ";
stockLegend1.markerType = "none";
stockPanel1.stockLegend = stockLegend1;
// second stock panel
var stockPanel2 = new AmCharts.StockPanel();
stockPanel2.title = "Volume";
stockPanel2.percentHeight = 30;
var graph2 = new AmCharts.StockGraph();
graph2.valueField = "volume";
graph2.type = "column";
graph2.cornerRadiusTop = 2;
graph2.fillAlphas = 1;
stockPanel2.addStockGraph(graph2);
// create stock legend
var stockLegend2 = new AmCharts.StockLegend();
stockLegend2.valueTextRegular = " ";
stockLegend2.markerType = "none";
stockPanel2.stockLegend = stockLegend2;
// set panels to the chart
chart.panels = [stockPanel1, stockPanel2];
// OTHER SETTINGS ////////////////////////////////////
var scrollbarSettings = new AmCharts.ChartScrollbarSettings();
scrollbarSettings.graph = graph1;
scrollbarSettings.updateOnReleaseOnly = true;
scrollbarSettings.usePeriod = "WW"; // this will improve performance
scrollbarSettings.position = "top";
chart.chartScrollbarSettings = scrollbarSettings;
var cursorSettings = new AmCharts.ChartCursorSettings();
cursorSettings.valueBalloonsEnabled = true;
chart.chartCursorSettings = cursorSettings;
// PERIOD SELECTOR ///////////////////////////////////
var periodSelector = new AmCharts.PeriodSelector();
periodSelector.position = "top";
periodSelector.dateFormat = "YYYY-MM-DD";
periodSelector.inputFieldWidth = 150;
periodSelector.periods = [{
period: "DD",
count: 1,
label: "1 day"
}, {
period: "DD",
count: 2,
label: "2 days"
}, {
period: "DD",
count: 5,
label: "5 days"
}, {
period: "DD",
count: 12,
label: "12 days"
}, {
period: "MAX",
label: "MAX"
}];
chart.periodSelector = periodSelector;
var panelsSettings = new AmCharts.PanelsSettings();
panelsSettings.usePrefixes = true;
chart.panelsSettings = panelsSettings;
chart.write('chartdiv');
}
</script>
这就是我在服务器端保存它的方式:
def save_chart_snapshot(request):
if request.POST:
data = urllib.unquote(request.POST['imageData'])
imageData = data.split(';')[1].split(',')[1]
filename = "static/temp/charts/snapshots/" + request.POST['isin'] + ".png"
if not os.path.exists(filename):
try:
fh = open(filename, "wb")
fh.write(imageData.decode('base64'))
except IOError:
logger.error("Cannot find file or read data: " + filename)
else:
fh.close()
logger.debug("Chart snapshot is generated: " + filename)
return HttpResponse("done")
答案 0 :(得分:1)
这有点晚了,但我最近遇到了类似的情况,我需要在服务器端导出报告功能并想使用 amcharts.js。在探索过程中,我发现可以使用提供无头浏览器的 puppeteer 运行 amcharts。
以下文章详细解释: https://www.amcharts.com/docs/v4/tutorials/automating-report-generation-using-puppeteer/
还有一个可下载的示例 here。
希望这对寻找类似功能的人有所帮助。
答案 1 :(得分:0)
您可以使用uzbl-core或netserf或wkhtmltopdf之类的工具在虚拟帧缓冲区中使用WebKit“浏览器”访问图表页面来自动化此过程,所有这些都支持JS。
然后将上述任务添加到每天启动的cron作业的脚本中。
从技术上讲,您仍在使用此解决方案在浏览器中访问页面,但至少可以从数据中心中的无头服务器中合理地实现自动化。