Appending multiple elements in D3 - dynamic

Can anyone explain why a selectAll + data + enter + append works fine initially, but when I call it again it only appends a single element?
http://jsfiddle.net/scottieb/wQJen/
When I run
vis.selectAll("circle")
.data(datafiltered).enter().append("svg:circle")
.attr("cx", function(d) { return x(d.x)})
.attr("cy", function(d) { return y(d.y)})
.attr("fill", "red").attr("r", 15);
I get four points (corresponding to the four pairs of data in 'datafiltered.'). But on button click, I run
vis.selectAll("circle")
.data(datafiltered2)
.enter().append("svg:circle")
.attr("cx", function(d) {
return x(d.x)
}).attr("cy", function(d) {
return y(d.y)
}).attr("fill", "black").attr("r", 5);
and only add the final element of 'datafiltered2' (five pairs in this one). So, the data are different and the second one occurs on button click, but not sure why I'm only getting the one point added!

The issue here is that there is no key function on the data you are binding, so D3 uses the index instead - hence the first four (pre-existing) elements are bound with new data, and the single 5th element gets added.
See this recent tutorial for details on key functions: http://bost.ocks.org/mike/constancy/
Possibly you really only wanted to add the single element, but also change the existing elements to represent their newly bound data, as in: http://jsfiddle.net/jsl6906/wQJen/2/

The result of calling the .enter() method is a set for new elements. Use the original selection for existing elements. See Enter and Exit on the D3 site.
// Update…
var p = d3.select("body").selectAll("p")
.data([4, 8, 15, 16, 23, 42])
.text(String);
// Enter…
p.enter().append("p")
.text(String);
// Exit…
p.exit().remove();

Related

How to set custom colors for Odoo 12 calendar view events?

There is a good tutorial on how to achieve this in Odoo-8 here:
Tutorial , but it doesn't work on Odoo-12.
Odoo natively allows you to set a field of your model as a basis for color differentiation in calendar view.
<calendar ... color="your_model_field">
The problem is that he will decide automagically what color to assign to every value.
I need to be able to decide what color mapping to use.
Doing some diving in the web module js files, more specifically on
web/static/src/js/views/calendar/calendar_renderer.js on line 266
I found a promising function which appears to be the one responsible for deciding which color to set.
getColor: function (key) {
if (!key) {
return;
}
if (this.color_map[key]) {
return this.color_map[key];
}
// check if the key is a css color
if (typeof key === 'string' && key.match(/^((#[A-F0-9]{3})|(#[A-F0-9]{6})|((hsl|rgb)a?\(\s*(?:(\s*\d{1,3}%?\s*),?){3}(\s*,[0-9.]{1,4})?\))|)$/i)) {
return this.color_map[key] = key;
}
var index = (((_.keys(this.color_map).length + 1) * 5) % 24) + 1;
this.color_map[key] = index;
return index;
},
This function is fed the value of your field (for every calendar event) and returns the color to be used "supposedly" as background for the calendar event square.
According to the second if statement, if you manage to instantiate the CalendarRenderer class with a color_map object which has the possible values of your field as keys and color codes as values you should be ok.
According the the third if statement, if the values of your field are strings with color codes (#FFF, rgb(x, y, z) , etc) they will be set in the color_map object and returned to be used as background colors.
The last part I guess is how odoo decides on a color when no mapping is provided.
I tried both approaches with the same efect:
Image displaying the calendar view
Namely, all the calendar events are rendered with the default color taken from the fullcalendar.css stylesheet (line 529), but the color reference displays correctly on the sidebar to the right.
I would appreciate any light shed on this matter, It has to be possible to make this work!.
Thanks.

data loading to qlikview extension this.Data

I'm trying to use extension for Qlikview 11SR2.
I've tried to access data with this.Data.Rows, but this object is empty even though the data is not empty and I can display the data in a table.
The code I have used is:
var obj = this.Data;
for(var prop in obj) {
var div = document.createElement("div");
div.innerHTML = "" + prop + "" + obj[prop];
this.Element.appendChild(div);
}
I have no access to the internet - I work offline.
How can i make this.Data.Rows contain the data (it is undefined)?
Based on your feedback, I would say it might be worth trying a slightly different way of accessing your data as the this.Data.Rows object contains a collection of row objects which in turn contain one or more objects, which relate to the dimensions and measures passed to the script (and are defined in definition.xml).
For example, say that I have an extension that features a dimension and a measure (in that order). I can access each value of these in a loop as follows:
for (var rowIx = 0; rowIx < this.Data.Rows.length; rowIx++) {
var row = this.Data.Rows[rowIx];
myDimensionValue = row[0].text;
myMeasureValue = row[1].text;
}
I can then add code to output each value of myDimension and myMeasureValue to the loop, such as in your case adding a new div for each set of values.
I found the "QVConsole" extension invaluable when writing extensions, as it allows you to have a JavaScript console in your QlikView document, so you may then use statements like console.log(myDimensionValue) etc. to help you debug your extension. You can download it from https://github.com/thomasfriebel/QvConsole.
In you extension object in the webview, set the dimension and a valid expression. Let me know whether it works!

Datatables: Showing a summary row for sub rows

I'm new to Datatables...
I'm making a grid of rows, each with sub (details) rows. I'm using server-side data from a mysql database. It is returned as JSON containing all sub rows.
I need to create the "main" grid rows, summing up columns from the sub rows. I'm not sure if Datatables can do this or how it is done...
I'm thinking about starting by getting the JSON in a JQuery function. Then using a loop to sum up data I need and pass that on to the grid as array-data. Lastly I render the grid.
Is this best practice or is Datatables capable of doing it in a smarter way?
-- the concept of sub rows can be seen here: http://datatables.net/blog/Drill-down_rows --
I have completed something like this. I returned all the data I needed and put the "details" information into the last column in a hidden div. Then used a row click to put that information into the details row.
//In the example the table the first column has a plus icon that gets replace with a minus icon
// the last column added a hidden div that contained the details.
$("#results").dataTable({
"fnCreatedRow": function (nRow, aData, iDataIndex) {
//Attach the on click event to the row
var oTable = this;
$("td:eq(0) span", nRow).on("click", function () {
//First column has a image with the jQuery UI plus icon
if ($(this).hasClass("ui-icon-circle-plus")) {
//The details information is stored in the last column in a hidden div with the class wrapper
//Grab the hidden information and append that to the new row.
oTable.fnOpen(nRow, $(".wraper", nRow).html(), "details");
} else {
oTable.fnClose(nRow);
}
$(this).toggleClass("ui-icon-circle-plus ui-icon-circle-minus");
});
}
});

Dojo EnhancedGrid and programmatic selection

Here's my problem: in my application I have a Dojo EnhancedGrid, backed up by an ItemFileReadStore. The page flow looks like this:
The user selects a value from a selection list.
The item from the list is posted on a server and then the grid is updated with data from the server (don't ask why, this is how it's supposed to work)
The new item is highlighted in the grid.
Now, the first two steps work like a charm; however, the third step gave me some headaches. After the data is successfully POSTed to the server (via dojo.xhrPost() ) the following code runs:
myGrid.store.close();
myGrid._refresh();
myGrid.store.fetch({
onComplete : function(items) {
for ( var i = 0; i < items.length; i++) {
if (items[i].documentType[0].id == documentTypeId) {
var newItemIndex = myGrid.getItemIndex(items[i]);
exportMappingGrid.selection.deselectAll();
exportMappingGrid.selection.addToSelection(newItemIndex);
}
}
}
});
Now, the selection of the grid is updated (i.e. the selection object has a selectedIndex > 0), but visually there's no response, unless I hover the mouse over the "selected" row. If I remove the .deselectAll() line (which I suspected as the culprit) then I sometimes end up with two items selected at once, although the grid selectionMode attribute is set to single.
Any thoughts on this one?
Thanks a lot.
You need to use setSelected(), like so
exportMappingGrid.selection.setSelected(newItemIndex, true);
The second parameter is true to select the row, false to unselect it.
This is what works for me:
grid.selection.clear();
grid.selection.addToSelection(newItemIndex);
grid.selection.getFirstSelected();
Jon

Flexigrid - how to turn off row selection

Is it possible to turn off the row selection feature on Flexigrid?
It's somewhat annoying when you haven't implemented anything that makes use of the selection.
Unfortunately Mr Flibble's accepted answer does not stop all selection capability, it merely restricts it to one row.
To disable it completely, add a new property to the $.extend block (around line 20)
// apply default properties
p = $.extend({
<SNIP>
onSubmit: false, // using a custom populate function
disableSelect: true
Then in the .click section of the row (around line 754) add a check for the property
$(this)
.click(
function (e)
{
var obj = (e.target || e.srcElement); if (obj.href || obj.type) return true;
if (p.disableSelect) return true;
$(this).toggleClass('trSelected');
if (p.singleSelect) $(this).siblings().removeClass('trSelected');
}
)
Turns out you need to change the singleSelect property to true.
singleSelect: true
I know this thread is a bit old but I came upon it looking for the same thing. The singleSelect didn't work for me as I didn't want to be able to select any row. I found that I could remove any row selection with a single line of code:
$('.grid tr').unbind('click');
This a course removes all bindings on the table row so if you needed the binding you won't have it unless you rebind later but I needed to remove any and all row selection on my table. I didn't need to touch the flexigrid code to do so which I liked a bit more than previous answers.