I created a chrome extension which activates when I enter in an specified folder in Google Drive. This extension adds a diagram made with D3.js in that folder as you can see in the following picture:
Apart from the diagram, it also adds a dropdown list but the problem is that it doesn't work when I click on it (it doesn't show the options). The only thing it does is to create the rectangle to select elements as you can see in the next picture:
I tried to add other HTML elements in Google Drive such as buttons but they didn't work either. It seems that Google Drive deactivate the onclick event of the html elements I add.
The code of the dropdown list:
d3.select("#divSelect")
.append("select")
.attr("class","desplegable")
.attr("id","desplegable")
.on('change',function (d,i) {
var grupoSeleccionado = d3.select("#desplegable").node().value; //Examen seleccionado
if (grupoSeleccionado=="Total"){ //Vision general de los examenes
dibujarSpiderChart(data);
} else { //Vision de un examen en concreto
var notasAlumnoExamen=_.filter(data[0],{'group':grupoSeleccionado});
var notasMediasExamen=_.filter(data[1],{'group':grupoSeleccionado});
var dataGrupo=[];
dataGrupo.push(notasAlumnoExamen);
dataGrupo.push(notasMediasExamen);
dibujarSpiderChart(dataGrupo);
}
;})
.selectAll("option")
.data(gruposLista)
.enter()
.append("option")
.attr("value", function (d) { return d.id; })
.text(function (d) { return d.nombre; });
Related
I have created an aggregated data table that filters other tables using clickable rows. Tried to create a drill down capability using DC.js aggregated tables and was able to put together a solution that works, thanks to Gordon's solution here on stack overflow. However,currently I am not able to figure out how I can keep a track of all the clicked row keys across tables, so that the user can undo any filters that were already selected.
Code for the aggregated data table that has row click filtering enabled.
//Fake Dimension
rank = function (p) { return "" };
var filterKeys = [];
//Remove any table row that has 0 or a garbage value
function checkRows(d){
if(d.value.total<=0 || isNaN(d.value.total)||isNaN(d.value.average) ||d.value.average<=0 ||isNaN(d.value.count)||d.value.count<=0 ){
return 0;
}
return d;
}
//MarketTable
marketTable.width(500)
.height(480)
.dimension(AECMarketsGroup)
.group(rank)
.columns([function (d) { d=checkRows(d);
while(d!=0){
return d.key;
}
},
function (d) { d=checkRows(d);
while(d!=0){
return
formatter(d.value.total);
}
},
function (d) {
d=checkRows(d);
while(d!=0){
return formatter(d.value.count);
}
},
function (d) {
d=checkRows(d);
while(d!=0){
return d.value.average;
}
}])
.sortBy(function (d) { return d.value.total })
.order(d3.descending)
//Enable click filtering
marketTable.on('pretransition', function (table) {
table.selectAll('td.dc-table-column')
.on('click',function(d){
if(filterKeys.indexOf(d.key)===-1)
filterKeys.push(d.key);
else
filterKeys = filterKeys.filter(k => k != d.key);
if(filterKeys.length === 0)
marketDim.filter(null);
else
marketDim.filterFunction(function(d) {
return filterKeys.indexOf(d) !== -1;
})
dc.redrawAll();
})
});
Here is the js fiddle with all 3 tables : https://jsfiddle.net/yashnigam/kvt9xnbs/21/
For example, if a user clicks on Europe in the first table, Amazon in the second table and Electronics in the third, I want to show a breadcrumb of the path the user has taken in the drill down, in this case Europe>>Amazon>>Electronics and be able to disable any of the applied filters, say I disable amazon, then the filter selection should be Europe>>Electronics
Another thing that I am facing trouble with is that the "reset all" button that I have implemented using dc.filterAll;dc.renderAll; does not reset the data after I make selections across tables.
<h6 class="dc-data-count" style="float: left;margin-left:5px;">
<span>
<span class="filter-count"></span>
selected out of
<span class="total-count"></span>
records |
<a id="reset"
href="javascript:dc.filterAll();dc.renderAll();"> Reset All</a>
</span>
</h6>
It would be of great help if you can help me with any of the two problems I am facing
1. Keeping a track of filters and being able to disable them
2. Reset all data after filtering using rows in the tables or a reset option for individual tables.
Please help. Thanks!
I'm a newbie using d3.js to create a multi-level filter plot based on user selections. All filters are working exceptenter link description here the categorical color selection. Colors are defaulting to fluid type (default should be material type) and using the radio button to switch doesn't work. Can anyone help?
https://plnkr.co/edit/yoFCbe?p=preview
function filter_color(){
colored = document.getElementById("color_Filter");
svg.append("circle")
.style("fill", function(d) {
if (colored == 0) {
return color(d["Material group"]);
} else {
return color(d["Fluid type"]);
}
})
}
You're not checking for the actual value of the radio box.
Get the checked/unchecked state and that if statement will run as it should:
colored = document.getElementById("color_Filter")[0].checked; // <= mind here
if (colored == 0) {
return color(d["Material group"]);
} else {
return color(d["Fluid type"]);
}
See https://plnkr.co/edit/gZOIbDgYj6OCs5aM1CV2?p=preview
I have a map with d3 circles showing the site locations, as well as a linechart showing the time trend for each of the site. I am trying to make a particular line highlight when a corresponding circle is clicked. Here is the code. I can't seem to connect the siteIDs with the following function:
function highlightLine(id) {
lineGroup.classed("g-highlight", function(d) {
return d.siteID == id.siteID;
});
};
Insert a console.log as shown below, and it should become clearer:
function highlightLine(id) {
lineGroup.classed("g-highlight", function(d) {
console.log(d);
return d.siteID == id.siteID;
});
};
Because you're binding to data that you've run through d3.nest, the id of d that you're interested in is actually d.key not d.siteID, which does not exist on that level. So the boolean inside classed should be
return d.key == id.siteID
That will cause the appropriate trendline's <g> to have a "g-highlight" class, however it still will not visibly color the line. I believe that's because your css rule .g-highlight { stroke:... } applies the stroke to the containing <g> instead of the <path> inside it. You can change that css rule to be .g-highlight path { ... } and that will color the path as you'd like.
To bind the click event in d3 you should select the object with that class and bind the click:
d3.selectAll(".g-highlight").on("click", function(d) {
return d.siteID == id.siteID;
});
I am in the process of creating a bubble chart with D3.js. Now I want it to display a comment in the <h3 id="comment"></h3> tag when I click on each bubble.
Here is my data.csv file:
name,count,group,comment
apple,5,red,"This is the best apple ever."
grape,10,purple,"Grapes are huge."
banana,8,yellow,"Are these bananas even ripe?"
pineapple,1,yellow,"Great for making juice."
...
And in my viz.coffee, I have:
idValue = (d) -> d.name
textValue = (d) -> d.name
groupValue = (d) -> d.group
commentValue= (d) -> d.comment
Originally, I use the following code to display the name of the bubble when clicked:
updateActive = (id) ->
node.classed("bubble-selected", (d) -> id == idValue(d))
if id.length > 0
d3.select("#comment").html("<h3>#{id} is selected.</h3>")
else
d3.select("#comment").html("<h3>Nothing is selected</h3>")
How should I change it, so that when you click on the bubble, the comment displays instead?
I tried:
updateActive = (id) ->
node.classed("bubble-selected", (d) -> id == idValue(d))
if id.length > 0
d3.select("#comment").html(d.comment)
else
d3.select("#comment").html("<h3>Click on a bubble to read its comment.</h3>")
But it doesn't seem to work, because d is undefined, which I can see why, but I'm not sure what I should do. Please help.
Even though I'm not completely sure of your code I think this should work:
updateActive = (id) ->
node.classed("bubble-selected", (d) -> id == idValue(d))
if id
for x in data when idValue(x) is id
d3.select("#comment").html(commentValue(x))
else
d3.select("#comment").html("<h3>Click on a bubble to read its comment.</h3>")
Here data is what you supply to d3 through .data().
I am building a small UI where the user has to select a point on each of the two SVGs shown.
These points coordinates are then shown under the SVGs. I would like to achieve this using D3's data-binding with the enter() and exit() methods. However it seems that D3 doesn't always update the part where I display the points coordinates, even if I call the enter() method on the bound elements. When removing data, the exit() methods works however.
Here is the main code :
function showPoints() {
var coordinatesElements = d3.select('#coordinates').selectAll('.point').data(points);
coordinatesElements.enter().append('div').classed('point', true)
.text(function (d) {
var textParts = [];
if (d.firstSvg) { textParts.push('first : '+JSON.stringify(d.firstSvg)); }
if (d.secondSvg) { textParts.push('second : '+JSON.stringify(d.secondSvg)); }
return textParts.join(' - ');
})
.append("span")
.classed('removeCalibrationPoint', true)
.html(" X")
.on('click', function(d, i) {
points.splice(i, 1);
showPoints();
});
coordinatesElements.exit().remove();
}
I have created a JSBin fiddle that demonstrates the problem.
The first problem is that you have an empty div of class point in your HTML. This will be selected by the .selectAll('.point') and cause the first element in your data not to show up.
The second problem is that you're not handling the update selection -- in some cases, you're not adding new data, but modifying existing data. The following code updates the text for the data in the update selection.
coordinatesElements.text(function (d) {
var textParts = [];
if (d.firstSvg) { textParts.push('first : '+JSON.stringify(d.firstSvg)); }
if (d.secondSvg) { textParts.push('second : '+JSON.stringify(d.secondSvg)); }
return textParts.join(' - ');
});
Complete demo here. Notice I've simplified the code slightly by setting the text only on the update selection -- elements added from the enter selection merge into the update selection, so there's no need to do it twice.