rawgraphs / rawgraphs-app

A web interface to create custom vector-based visualizations on top of RAWGraphs core
https://rawgraphs.io
Apache License 2.0
8.66k stars 1.84k forks source link

How to get label/key string for a given data set #89

Closed CorpusCallosum closed 9 years ago

CorpusCallosum commented 9 years ago

Hi, I am working on a custom chart, and I would like to extract the label of the data column, and use that in the chart. It seems that because the model.map function strips out the labels, there does not appear to be a way to retrieve them once we are inside chart.draw

It seems that the Parallel Coordinates chart is using the labels to label the axis via the String parameter here, but I am confused by this syntax. How is the data label being derived?

g.append("svg:g") .attr("class", "axis") .each(function(d) { d3.select(this).call(axis.scale(y[d])); }) .append("svg:text") .attr("text-anchor", "middle") .style("font-size","10px") .style("font-family","Arial, Helvetica") .attr("y", -9) .text(String);

In particular, this line of code I am baffled by: ".each(function(d) { d3.select(this).call(axis.scale(y[d])); })" Would appreciate any help. Thanks!

giorgiocaviglia commented 9 years ago

Hi, not sure what you mean by "the model.map function strips out the labels". You can totally (re)write the model.map function in your chart, as well as adding or removing any dimension from your model. If you need the user to select a label dimension from your data, be sure to add that dimension to the model. Then you can retrieve the value in the model.map function and using that (i.e. insert that in the data output).

The String value in the Parallel Coordinates is used to cast the underlying value of the axis as string. It is equivalent of:

.text(function(d){ return String(d); })

Maybe looking at how the Scatterplot chart is made will be more helpful for you. In particular you can see at line 118 which is where the text of each dot is retrieve from the label. Of course, you need to create the property .label in the model.map function.

Hope this helps to clarify. For more information please refer to the API reference or the Developer guide.

CorpusCallosum commented 9 years ago

Sorry, perhaps that was unclear, when I say "label" I am referring to the label of the data column. For example with my csv file that looks like this:

label, interviews Energy and Utility 209 Media and Entertainment 125 Telecommunications 209 Consumer Products 376

I'm trying to derive the label of the second column, in this case it is "interviews" and I would like to draw that onto my chart. When I do the data mapping, I am able to derive the values of interviews without a problem, but I can't figure out how to access the actual label for those values, which in this case is called "interviews". Does that make sense? Thanks!

giorgiocaviglia commented 9 years ago

Oh. I see. Sorry for the misunderstanding. You can retrieve the name of the column (or the columns) used in a dimension, by calling that dimension without any argument:

dimension()

For instance, in the Parallel Coordinates chart at line 18 you see that the model map iterate on list() which returns the columns used in the chart.

Of course, you cannot access names for columns not used in the chart. Hope this helps.

CorpusCallosum commented 9 years ago

OK thank you, this is the way I ended up doing it:

model.map(function (data){ return data.map(function (d){ if(size()) return { size : +size(d), //plus symbol converts the data into a number label : label(d), heading: size()[0] } }) })

Then, I get the "heading" parameter like so for displaying in the chart: //subtitle svg.append("text") .attr("y", 20) .attr("font-size", "15px") .text(data[0].heading) .attr("fill","#939597") .attr("font-weight", "normal")

It works, but I feel like this is not really the best way to do it. Let me know if you have a better suggestion. Thanks!

giorgiocaviglia commented 9 years ago

It seems ok to me. Of course, it depends what you want to achieve. If you need the heading just once and not in relation to the data you can change your model map and put that outside:

return {
 heading :  "" + size(), // print the array as string - assuming size can have only one value
 values : data.map(function(d){
  size : +size(d),
  label : label(d)
 })
}

And in the chart:

.text(data.heading)

Just a minor change though, yours works as well!

CorpusCallosum commented 9 years ago

Ah yes, that is what I wanted to do! Thanks for your help. I will do a pull request when I'm done with the chart. (though it is just a simple pie chart) :)