I have a number of nvd3 charts on a page, and I store some useful information in the chart's id attribute (basically a rowkey that I used to populate the data).
What I want to do is fetch additional data when the user clicks a point on the graph.
The problem is, with many graphs on the page, when the user clicks (I have registered for lines.dispatch.on('elementClick')), I need to somehow know which graph I am on so I have the information I need to make the subsequent query.
Is there some way to grab the containing chart information when the user clicks on a point? Or knowing the chart's ID?
If you have jquery on your page, then you can use jquery.closest to look for the parent chart element and extract its ID:
.on('elementClick', function (d, i) {
var chartId = $(this).closest('svg').attr('id');
// ...
});
Related
I am new to d3 and I have objects that are connected to each other. Each of these objects has multiple fields that I want to display. I was wondering how can you do this in d3.
I’m not sure I understand the question, but what I think you’re going for is something like this:
Make your selection and bind the data.
let update = d3.selectAll(".object").data(objects);
Remove old elements (if necessary).
update.exit().remove();
Create an enter selection and append a child for each field.
let enter = update.enter()
.append("g").attr("class", "object");
enter.append("g").attr("class", "field1");
enter.append("g").attr("class", "field2");
Merge your enter selection back into update, then fill in the fields.
update = update.merge(enter);
update.select(".field1").text(d => d.field1);
update.select(".field2").text(d => d.field2);
Currently I have 4 charts. The selection (via column or legend) of a category from the main one triggers multiple events. It changes the selected item's color on two charts and it creates two more charts.
For the two created charts, I'm having problems with redrawing/removing (that is what I'm assuming I will have to do) when the column/legend is deselected.
I may be wrong but from what I've looked at, it seems that when you prevent show/hide it doesn't change the visibility property so I wasn't sure if there was a way to use that.
Any help would be appreciated!
Fiddle here: http://jsfiddle.net/jlm578/gy9og69r/4/
I also thought about whether I needed to add it into the logic of the function (possibly one below) or if the sibling aspect needed to be added to the others.
function drawSignifNonSignifEruptionsChart(series){
if (series.index == '0'){
var eruptVEI = ['VEI 0'];
var signifErupt = [10];
var nonSignifErupt = [600];
}
So for a while I had struggled with how to filter a dataTable in dc.js without affecting other dimensions. This seems counter-intuitive, as it goes against what crossfilter(the data filter behind dc.js) does best, but I'll explain why this can be relevant.
Suppose I have a dataset of peoples name age and gender. In one of my datatables, I only want to display males; using one crossfilter, I would be forced to filter all my other datatables by males.
Suppose I also have a pie chart that lists the first letter of each person's name, and I want to be able to filter on the 'M's. I have a table for males, and a table for females. I don't want these tables to affect the distribution of the pie chart, but I want to be able to click on the pie chart and have it filter the dc.js datatables. More or a less a one way filter.
What is the way to achieve this?
dc.js datatables accept crossfilter dimensions. I got around the problem by extending the dimension as follows.
function preFilter(dim,okey,oval){
return{
top:function(x){
var a1 = dim.top(x).filter(function(v){
return v[okey] === oval;
});
return a1;
}
};
}
This worked well for me, I hope it can help others.
In dc.js I'm displaying the number of filtered and total rows with dc.dataCount:
dc.dataCount(".dc-data-count", "charts")
.dimension(data_cf)
.group(all);
and
<div class="dc-data-count">
<strong class="filter-count"></strong> selected out of <strong class="total-count"></strong> records
On the same page, I have a d3 donut chart that I've drawn. Within this chart I'd like to display the filter-count (which updates as filters are applied), as well as other calculations like the sum of a value in the current selection. Given that dc.dataCount is accessed by a div class, I don't know how to access the number to place precisely in my donut chart.
How can I pass values from dc.dataCount or some other grouping into a d3 object?
Thanks!
I would do this with a renderlet on the donut chart that just reads the values you need, and adds them. Renderlets run after the chart has rendered, so there is a slight delay, but it shouldn't be too disturbing for this use.
As for how to get the numbers, there is no magic to the dataCount widget; it's just reading crossfilter values:
https://github.com/dc-js/dc.js/blob/master/src/data-count.js#L77
So you can add text elements to the svg using dimension.size() and group.value() in the same way.
I'm trying to have a d3.js Sankey visualisation filter a data set according to categories.
I'm using d3.csv method to input the data as shown in this example - http://bl.ocks.org/timelyportfolio/5052095
I would however like to upload a data set with four columns -
source, target, value, category
My aim is to have a visualisation with the ability to switch between categories. So each Sankey visualisation will only represent one particular category. Then user can switch from the dropdown to another one.
Is this possible using the current d3.csv input method?
Would this work ?
d3.csv("file.csv", function(data) {
[...]
// Called each time there is an action on the dropdown menu
function updateGraph() {
// Select only data that are tagged with a certain category
var dataset = data.filter(function(d) { return d.category == selectedCategory; });
// Update graph visualization
}
}
This way you wouldn't have to reload your csv file each time.
This a very long method for the second part but, creating multiple html/php and csv files depending on your categories and then adding the following code in each of your html/php files. This method would be extra work if you have a lot of categories.
Category 1
category 2
If you figured out a solution the way you were trying it, then if possible please update your answer. it would be helpful.
Thanks.