【问题标题】:Parsing CSV and then Using the Data to Build Highcharts Bar Chart解析 CSV,然后使用数据构建 Highcharts 条形图
【发布时间】:2018-08-21 19:30:26
【问题描述】:

我想创建一个条形图可视化 IN JS FIDDLE,它将可视化每个消费者类别的“Q1 / 18 (TTM) 年度客户价值”和“第一次和第二次访问之间的天数”是:['1', '2', .....'29+']。条形图应如下所示(图例涵盖第一类,但我会解决这个问题):

我假设数据已经存在于 CSV 中,如下所示:

我有一个允许用户导入 CSV 文件的界面。在这里:

// The event listener for the file upload 
document.getElementById('txtFileUpload').addEventListener('change', upload, false);
	
// Method that checks that the browser supports the HTML5 File API
function browserSupportFileUpload() {
    var isCompatible = false;
    if (window.File && window.FileReader && window.FileList && window.Blob) {
        isCompatible = true;
    }

    return isCompatible;
}

function upload(evt) {
    if (!browserSupportFileUpload()) {
        alert('The File APIs are not fully supported in this browser!');
    } else {
        var data = null;
        var file = evt.target.files[0];
        var reader = new FileReader();
        reader.readAsText(file);
        reader.onload = function(event) {
            var csvData = event.target.result; //alert(csvData);
            var data2 = csvData.split("\n"); //alert(data2);
            var i;
            for (i = 0; i < data2.length; ++i) {
                // here's the data row separated by commas
                alert(i+': '+data2[i]);
                // call your ajax and submit this one row
                // now wait for response
                // if not error:
                // advance progress bar, and number converted, etc in modal
                // else:
                // show error message
            }
                    
            if (data2 && data2.length > 0) {
                alert('Imported -' + data2.length + '- rows successfully!');
            } else {
                alert('No data to import!');
            }
        };
        reader.onerror = function() {
            alert('Unable to read ' + file.fileName);
        };
    }
}
<h1>File Upload Test</h1>
<p>
    <div id="dvImportSegments" class="fileupload ">
        <fieldset>
            <legend>Select the CSV file to upload</legend>
            <input type="file" name="File Upload" id="txtFileUpload" accept=".csv" />
        </fieldset>
    </div>
</p>
  

然后,我使用 .get() 来引入变量 csvData(来自上述代码中的函数),然后我将使用函数 parseCSVData 解析它(函数写在下面)。然后,我将制作数据的条形图。这是我这部分的代码:

$.get(csvData, function (csvFile) { //retrieve csvData from other function above

var data = parseCSVData(csvFile);
  
  
  //create the chart
  
  Highcharts.chart('container', {
  chart: {
    type: 'bar'
  },
 
  title: {
    text: null,
    align: 'center',
    verticalAlign: 'bottom',
  },
  xAxis: {
    categories: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11-17', '18-28', '29+'],

    title: {
      text: 'Visits Per Customer (TTM)'
    },
  },
  yAxis: {
    min: 0,
    gridLineWidth: 0,
  	minorGridLineWidth: 0,     
    
    title: {
      text: 'Average Return Rate Overall: 64 Days',
      y: 10
    },
    
    labels: {
      overflow: 'justify'
      
    }
  },
  
  tooltip: {
    headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
    pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
      '<td style="padding:0"><b>{point.y:.0f} </b></td></tr>',
    footerFormat: '</table>',
    shared: true,
    useHTML: true
  },
  plotOptions: {
    bar: {
      dataLabels: {
        enabled: true,
      }
    }
  },
  legend: {
  
    layout: 'horizontal',
    align: 'right',
    verticalAlign: 'top',
    x: -25,
    y: 5,
    floating: true,
    borderWidth: 1,
    backgroundColor: ((Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'),
   
    shadow: true
    
  },
  credits: {
    enabled: false
  },
  series: [{
    name: 'Q1 / 18 (TTM) Annual Guest Value',
    //data: 2nd column of CSV file
    color: 'grey',
    // label color
    dataLabels: {
      style: {
        color: 'grey'
       
      }
    }
  }, {
    name: 'Days Between 1st and 2nd Visits',
    //data: 3rd Column of CSV file
    color: 'green',
    // label color
    dataLabels: {
      style: {
        color: 'green'
      }
    }
  }]
})

})
  
  
function parseCSVData (csvFile){

    //empty array for storing the chart data
    var guestvalue_and_visits = []; //2nd and 3rd column extraction
  
    var lines = csvFile.split("\n");
  
    $.each(lines, function (lineNumber, line){
        if(lineNumber != 0) { //skipping header lines
            var fields = line.split(",");
            var a = parseFloat(fields[1]); // this is guest value
            var b = parseFloat(fields[2]); //this is days between visit
            guestvalue_and_visits.push([a , b]);
        }
    })
    return guestvalue_and_visits.reverse();
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>

<div id="container" style="min-width: 310px; max-width: 800px; height: 400px; margin: 0 auto"></div>

我的问题是:

我需要解析的数据的正确形式是什么?是 var data2 = csvData.split("\n") 还是 var csvData = event.target.result?

我是否在 .get() 中正确地引入了变量 csvData(或 data2,如果这是正确的)?我不是 Javascript 方面的专家,但我很确定变量 csvData 是 reader.onload = function(event){} 的本地变量,所以我需要以某种方式访问​​这个局部变量。我如何将它正确地带入.get()?简单地写 .get(csvData, function (csvFile){ 可以吗?

另外,如果您查看“系列”下的“数据”属性,我将其留空,因为我不知道如何将 guestvalue_and_visits 变量中的数据带入 Highcharts 代码。 (我做了 guestvalue_and_visits.push([a , b] 因为这是 Highcharts 接受的形式)。我想从数据结构中提取 'a' 和 'b' 部分并将它们放在相应的 'data' 属性中系列”。我该怎么做?

最后但并非最不重要的一点是,将所有内容放在一起我将如何允许界面首先允许用户上传 CSV 文件,然后在上传时,界面将更改为 Highcharts 条形图?我需要编写某种代码来执行此操作吗?

【问题讨论】:

    标签: javascript jquery html css highcharts


    【解决方案1】:

    我需要解析的数据的正确形式是什么?是 var data2 = csvData.split("\n") 或者是 var csvData = event.target.result?

    在您的情况下,我建议您将 CSV 字符串解析器中的类别和系列数据分开,并返回两个包含数据的不同系列,就像这样:

    var parseCSV = function(csv) {
        var lines = csv.split("\n").map(line => line.split(",")) // split string to lines
        var categories = []
        var series = [{
          name: 'Q1 / 18 (TTM) Annual Guest Value',
          color: 'grey',
          data: [],
          dataLabels: {
            style: {
              color: 'grey'
    
            }
          }
        }, {
          name: 'Days Between 1st and 2nd Visits',
          color: 'green',
          data: [],
          dataLabels: {
            style: {
              color: 'green'
            }
          }
        }]
            // Parse every line of csv file.
        lines.forEach((line, i) => {
          if (i !== 0) {
            var cat = line[0].slice(1, -1)
            var p1 = parseFloat(line[1])
            var p2 = parseFloat(line[2])
    
            categories.push(cat)
            series[0].data.push(p1)
            series[1].data.push(p2)
          }
        })
        // return the object with categories and series
        return {
            categories: categories,
          series: series
        }
      }
    

    然后只需分配类别和系列:

    var parsedCSV = parseCSV(csv)
    
    Highcharts.chart('container', {
      xAxis: {
        categories: parsedCSV.categories
      },
      series: parsedCSV.series
    })
    

    我是否在 .get() 中正确地引入了变量 csvData(或 data2,如果这是正确的)?我不是 Javascript 方面的专家,但我很确定变量 csvData 是 reader.onload = function(event){} 的本地变量,所以我需要以某种方式访问​​这个本地变量。我如何将它正确地带入.get()?简单地写 .get(csvData, function (csvFile){ 可以吗?

    我没有看到您的整个项目结构,但是是的,csvDatadata2 变量范围仅限于 reader.onload 函数,因此,除了此事件函数之外,您不能在任何地方调用 get()

    最后但并非最不重要的一点是,将所有内容整合在一起,我将如何允许 FIRST 接口允许用户上传 CSV 文件,然后当 上传了,界面会变成Highcharts条形图吗? 我需要编写某种代码来执行此操作吗?

    其实我觉得生成图表的过程应该是这样的:

    1. 生成一个空图表(或带有一些初始数据)
    2. 从文件中获取 CSV
    3. 解析已有的 CSV
    4. 解析后,只需使用 Chart.update() 方法使用新的 categories 和整个 series 对象更新图表。

    API 参考: https://api.highcharts.com/class-reference/Highcharts.Chart#update

    正确解析数据的实例:http://jsfiddle.net/db0vsgmh/

    【讨论】:

      猜你喜欢
      • 2016-07-06
      • 2014-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-25
      相关资源
      最近更新 更多