简体   繁体   English

如何将数据列指定为行生成器中使用的属性?

[英]How to specify a data column as the property used in a line generator?

In d3.js it is possible to access parts of a dataset by using the syntax d.measure with d accessing the data property and "measure" accessing a specific field in our dataset. 在d3.js中,可以通过使用语法d.measure来访问数据集的各个部分,其中d访问data属性,而“ measure”访问数据集中的特定字段。 Based on the code I found on bl.ocks.org I created a line chart. 根据在bl.ocks.org上找到的代码,我创建了一个折线图。 I however wanted to alter the function dsLineChart() in such a way that I can pass the name of the column that I want to use for visualising the values on the y-axis, ie how to specify an argument dsLineChart(argument) that determines the column to use egdmeasure2 instead of d.measure. 但是,我想以某种方式更改函数dsLineChart(),以便我可以传递要用于在y轴上可视化值的列的名称,即如何指定确定dsLineChart(argument)的参数该列使用 egdmeasure2代替d.measure。

See below for the script. 参见下面的脚本。 The dataset I have contains the columns "measure", "measure2", "measure3" and "measure4" of which "measure" is visualised by d.measure, but I want to call eg dsLineChart("measure2") to use the same function but for another column. 我拥有的数据集包含列“ measure”,“ measure2”,“ measure3”和“ measure4”,其中的“ measure”通过d.measure可视化,但是我想调用dsLineChart(“ measure2”)来使用功能,但用于另一列。

eg 例如

  • Dataset 数据集

var data =  [
{group:"All",category:2011,measure:28107,measure2:53301,measure3:89015.40,measure4:138394},
{group:"All",category:2012,measure:39400,measure2:7001, measure3:55550.50,measure4:18004},
{group:"All",category:2013,measure:33894,measure2:690597,measure3:68289.50,measure4:17455},
{group:"All",category:2014,measure:55261,measure2:7172,measure3:73380.93,measure:418143} ];
  • Script 脚本

I have created a minimal working script that can be found on the following link Fiddle D3js line chart 我创建了一个最小的工作脚本,该脚本可以在下面的链接Fiddle D3js折线图中找到

Thanks to the of feedback @GerardoFurtado the resulting script is provided in below snippet and allows for calling the function dsLineChart() with different arguments resulting in linecharts using different measures eg dsLineChart("measure2") vs. dsLineChart("measure"). 感谢@GerardoFurtado的反馈,以下脚本提供了结果脚本,该脚本可使用不同的参数(例如dsLineChart(“ measure2”)与dsLineChart(“ measure”)调用带有不同参数的函数dsLineChart()生成线图。

 // dataset var lineChartData = [{ category: 2011, measure: 28107, measure2: 53301, measure3: 89015.40, measure4: 138394 }, { category: 2012, measure: 39400, measure2: 7001, measure3: 55550.50, measure4: 18004 }, { category: 2013, measure: 33894, measure2: 690597, measure3: 68289.50, measure4: 17455 }, { category: 2014, measure: 55261, measure2: 7172, measure3: 73380.93, measure: 418143 } ]; // layout var margin = { top: 20, right: 10, bottom: 0, left: 50 }, width = 350 - margin.left - margin.right, height = 250 - margin.top - margin.bottom; // function to draw linechart function dsLineChart(selMeasure) { //convert object to array var data = d3.values(lineChartData); var property; var measures = [selMeasure]; var xScale = d3.scaleLinear() .domain([0, data.length - 1]) .range([0, width]); var yScale = d3.scaleLinear() .domain([0, d3.max(data, function(d) { return d[selMeasure]; })]) .range([height, 0]) .range([height, 0]); var line = d3.line() .x(function(d, i) { return xScale(i); }) .y(function(d) { return yScale(d[property]); }); var svg = d3.select("#lineChart").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .attr("position", "absolute") .attr("top", "10px") .attr("left", "410px") var plot = svg .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")") .attr("id", "lineChartPlot"); var paths = plot.selectAll(null) .data(measures) .enter() .append("path") .attr("class", "line") .attr("d", function(d) { property = d; return line(data) }) .attr("stroke", "lightgrey") .attr("fill", "none") .attr("stroke-width", "4px"); } dsLineChart("measure2"); 
 <script src="https://d3js.org/d3.v4.min.js"></script> <div id="lineChart"></div> 

The most "elegant" solution here, and probably the most idiomatic one, is nesting your data, in such a way that the y value property can have the same name for all lines. 这里最“优雅”的解决方案,也许也是最惯用的解决方案,是嵌套数据,以使y value属性在所有行中都具有相同的名称。

However, this doesn't mean that what you're asking is not possible: it certainly is. 但是,这并不意味着您要问的是不可能的:的确可以。 You can specify what scale you pass to the line generator (for instance, have a look at this answer ), and what property you use for each method. 您可以指定传递给行生成器的比例(例如,查看此答案 ),以及每种方法使用的属性。

For this to work, we'll first declare a variable: 为此,我们首先声明一个变量:

var property;

That's the variable we'll use in the line generator: 这就是我们将在行生成器中使用的变量:

var line = d3.line()
    .x(function(d, i) {
        return xScale(i);
    })
    .y(function(d) {
        return yScale(d[property]);
    });

Now, let's get the real properties. 现在,让我们获取真实的属性。 Here I'm hardcoding them, but you can easily extract them from the data: 在这里,我对它们进行了硬编码,但是您可以轻松地从数据中提取它们:

var measures = ["measure", "measure2", "measure3", "measure4"];

Then, we bind that array as data: 然后,我们将该数组绑定为数据:

var paths = plot.selectAll(null)
    .data(measures)
    .enter()
    .append("path")

Now comes the important part: in the callback, you simply assign the value of property , which is used by the line generator: 现在是重要的部分:在回调中,您只需分配property值,该值由行生成器使用:

.attr("d", function(d) {
    property = d;
    return line(data)
})

All together, here is your code with those changes: 总之,这是您的代码,其中包含以下更改:

 // dataset var data = [{ group: "All", category: 2011, measure: 28107, measure2: 53301, measure3: 89015.40, measure4: 138394 }, { group: "All", category: 2012, measure: 39400, measure2: 7001, measure3: 55550.50, measure4: 18004 }, { group: "All", category: 2013, measure: 33894, measure2: 690597, measure3: 68289.50, measure4: 17455 }, { group: "All", category: 2014, measure: 55261, measure2: 7172, measure3: 73380.93, measure: 418143 } ]; var property; var measures = ["measure", "measure2", "measure3", "measure4"]; // layout var margin = { top: 20, right: 10, bottom: 0, left: 50 }, width = 350 - margin.left - margin.right, height = 250 - margin.top - margin.bottom; // function to draw linechart function dsLineChart() { var firstDatasetLineChart = data var xScale = d3.scaleLinear() .domain([0, firstDatasetLineChart.length - 1]) .range([0, width]); var yScale = d3.scaleLinear() .domain([0, d3.max(firstDatasetLineChart, function(d) { return d.measure; })]) .range([height, 0]) .range([height, 0]); var line = d3.line() .x(function(d, i) { return xScale(i); }) .y(function(d) { return yScale(d[property]); }); var svg = d3.select("#lineChart").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .attr("position", "absolute") .attr("top", "10px") .attr("left", "410px") var plot = svg .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")") .attr("id", "lineChartPlot"); var paths = plot.selectAll(null) .data(measures) .enter() .append("path") .attr("class", "line") .attr("d", function(d) { property = d; return line(data) }) .attr("stroke", "lightgrey") .attr("fill", "none") .attr("stroke-width", "4px"); } dsLineChart(); 
 <script src="https://d3js.org/d3.v4.min.js"></script> <div id="lineChart"></div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM