如何在不访问浏览器的情况下生成amCharts的快照

时间:2014-04-04 06:21:30

标签: javascript charts

我在我的网站上使用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")

2 个答案:

答案 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作业的脚本中。

从技术上讲,您仍在使用此解决方案在浏览器中访问页面,但至少可以从数据中心中的无头服务器中合理地实现自动化。