d3.js stack layout upgrading from v3 to v4 - d3.js

Using D3 v3, I formatted my data to match Mike's example to quick start my dev process. Example page here https://github.com/d3/d3-3.x-api-reference/blob/master/Stack-Layout.md
var data = [
{
"name": "apples",
"values": [
{ "x": 0, "y": 91},
{ "x": 1, "y": 290}
]
},
{
"name": "oranges",
"values": [
{ "x": 0, "y": 9},
{ "x": 1, "y": 49}
]
}
];
Then all i had to do to obtain the stacked values was
var stack = d3.layout.stack().values(d=>d.values)
var layers = stack(data)
Exactly how he did it in his example.
However, in v4 it seems like the stack function expects tabular formatted data, so the above data would look like this.
var data = [
{x: 0, apples: 91, oranges: 9},
{x: 1, apples: 290, oranges: 49},
];
Is there an easy way to keep my data format and use the v4 stack function? I can't seem to grok the new way to do this. In my current data format, i have useful properties associated with the values array. If i change my data format to tabular, I don't see a convenient way to pair properties with values.

I've been having the same problem. Unfortunately, the new way doesn't seem to match the way APIs serialize model instances (sort of like your original data); instead you're stuck with JSONified tabular data format. I feel like this works when you're working with csv dumps, but that's not generally how databases are organised.
I've posted a related answer here that transforms object-grouped format (eg by fruit in your example) into data-point format (by x-coordinate in your example) as expected by d3.stack(). You'll be able to adapt the code to your particular case.

Related

How to access celldata objects in sheets api

I'm working on a google sheets integration project where I'd like to add formatted text to cells (bold, italic). This needs to be for only part of the cell (e.g. only some of the text in the cell is bold ) I can see that this can be done though the CellData object, documented in the sheets api here:
CellData
But I can't work out how to get an instance of these objects. I'm using the sheets service to successfully get a SpreadSheet, Sheet and ValueRange objects, but I can't work out how to get through to the cell data objects themselves to use these methods.
When a part of value of a cell has several formats, you want to retrieve the formats.
You want to put a value with several formats to a cell.
I understand your question as above. If my understanding is correct, how about these samples?
1. Retrieve value
When a part of value of a cell has several formats like below image,
the script for retrieving the values with the formats is as follows.
Sample script:
This sample script retrieves the value from the cell "A1" of "Sheet1".
spreadsheet_id = '### spreadsheet ID ###'
ranges = ['Sheet1!A1']
fields = 'sheets(data(rowData(values(textFormatRuns,userEnteredValue))))'
response = service.get_spreadsheet(spreadsheet_id, ranges: ranges, fields: fields)
Result:
{
"sheets": [
{
"data": [
{
"rowData": [
{
"values": [
{
"userEnteredValue": {
"stringValue": "abcdefg"
},
"textFormatRuns": [
{
"format": {}
},
{
"format": {
"fontSize": 24,
"foregroundColor": {
"red": 1
},
"bold": true
},
"startIndex": 2
},
{
"format": {},
"startIndex": 5
}
]
}
]
}
]
}
]
}
]
}
2. Put value
When a value with several formats is put to a cell, the script is as follows.
Sample script:
This sample script puts the value to the cell "B1" of "Sheet1". As a sample, update_cells is used for this situation.
spreadsheet_id = '### spreadsheet ID ###'
requests = {requests: [
update_cells: {
fields: 'userEnteredValue,textFormatRuns',
range: {sheet_id: 0, start_row_index: 0, end_row_index: 1, start_column_index: 1, end_column_index: 2},
rows: [{values: [{user_entered_value: {
string_value: 'abcdefg'},
text_format_runs: [{format: {}}, {format: {font_size: 24, foreground_color: {red: 1}, bold: true}, start_index: 2}, {format:{}, start_index: 5}]
}]}]
}
]}
response = service.batch_update_spreadsheet(spreadsheet_id, requests, {})
About sheet_id: 0, if you want to other sheet, please modify it.
Result:
Note:
These sample scripts supposes that your environment can use Sheets API.
These are simple samples. So please modify them to your situation.
References:
spreadsheets.get
spreadsheets.batchUpdate
textFormatRuns
updateCells

What data format/structure is this and how to handle it?

So I have ran into such data format:
{
"i": {
"hid|15#aid|9305#h|Openjobmetis Varese#a|Germani Basket Brescia#h2|VARESE#a2|BRESCIA#round|1019#nat|ita#hcolors": {
"bg|851010#g1|920000#g2|ad0b0b#g3|800000#c|"
},
"acolors": {
"bg|037f43#g1|00582d#g2|0fb966#g3|037f43#c|"
},
"hp|33#vp|20"
},
"idor": 0,
"jr|1#t": 19,
"t2": 30,
"ip|#b": false,
"v": {
"h": 0,
"a": 0,
"t": 30,
"h2": 12,
"a2": 12
}
}
I have never seen such structure and I could not find any sources to explain me this format. Actually I was not even sure how to search it.
So yeah, my question is, what is this data format and how can I handle it?
Looks like JSON.
It appears some data was also encoded as pipe-delimited string values in the JSON.
Ok, right after posting this question, I was able to decode this JSON. It seemed like a JSON all along but these pipes were kind of intimidating. This is how I solved it eventually.
function jsonDecode(json){
if(!json) return null;
json = json.replace(/#/g, '","').replace(/\|/g, '":"').replace(/%/g, '"},{"');
return JSON.parse(json);
}
Great! This question is now answered. Thanks everybody!

D3 Force, linkedByIndex returning empty array

EDIT: This was a simple fix, I'd bound my link simulation up in a timer function, which meant I was trying to create an array before the links "existed" moving the graph.link.forEach function into the timer function has sorted it right out. Thanks to Gerardo for making me think properly about the problem!
So I'm working on a force chart and trying to use a modified version of the fade function and I've been trying to implement the fade function found here (and in many other examples).
The trouble is:
var linkedByIndex = {};
graph.links.forEach(function (d) {
linkedByIndex[d.source.index + "," + d.target.index] = 1;
});
returns an empty array.
If I remove the .index, I get an array of source/target id's used to link the nodes.
Unfortunately, it seems to work fine with inline data in jsfiddle, but not when the data is from a get request. Also the source/target indexes show up in the links array in the console, so I'm not sure why the array's empty.
Any ideas?
Edit: An older version is here, linkedByIndex works in jsFiddle, but doesn't seem to after a PHP request.
The data structure is:
graph = "locations",
[
{"name": "a", "id": 1},
{"name": "b", "id": 2}
],
"nodes",
[
{"name": "A", "n_id": 1 "location": 1},
{"name": "B","n_id": 2, "location": 2}
],
"links",
[
{"source": "1", "target": "2"}
etc.
];

Query document with embedded document field using spring data repository

I am new to Spring-data, so pardon me if my question is to naive
I am trying to query the document which looks like this:
{
_id: 1,
name: "sue",
age: 19,
type: 1,
status: "P",
favorites: { artist: "Picasso", food: "pizza" },
finished: [ 17, 3 ],
badges: [ "blue", "black" ],
points: [
{ points: 85, bonus: 20 },
{ points: 85, bonus: 10 }
]
}
I wanted to do the query which gives me the list of the entries which contains the favourites.artist="Picasso".
I know how to do this using the MongoTemplate I wanted to do that using MongoRepository.
I was reading some document which shows query like this
findByFavorites(Favorites favorites)
but I couldn't find anything with which I can query using the field of the embedded document.
It should be
findByFavoritesArtist(#Param("favorites.artist") String artist);
So you just concatenate together the names of the properties in the property path in our embedded object. It is possible that the above query is redundant and you can leave out the #Param annotation.

D3.js - Assigning X and Y axis domain as max and min of data

Working with JSON data, I am able to set a domain X and Y to the minimum and maximum value of their respective data attributes, using
.y(d3.scale.linear().domain([0, d3.max(data, function(d) { return d.peopleVisited + 100; })]))
Here is an exemplary jsFiddle : http://jsfiddle.net/5H3Ay/15/
Can someone please suggest how to achieve this with csv data, using d3.csv()?
There should not be any difference in setting the domain, as long as you format your (CSV-) data properly.
The D3 Wiki page for CSV says that, using d3.csv.parse(string[, accessor]):
[For] the following CSV file:
Year,Make,Model,Length
1997,Ford,E350,2.34
2000,Mercury,Cougar,2.38
The resulting JavaScript array is:
[
{"Year": "1997", "Make": "Ford", "Model": "E350", "Length": "2.34"},
{"Year": "2000", "Make": "Mercury", "Model": "Cougar", "Length": "2.38"}
]
... which is a valid JSON array.
If you add peopleVisited as a header field in your CSV-file, your code should work already.
Just set up your data variable with csv.parse().
Edit
You can load your CSV, for example, by calling d3.csv() with an accessor function like this:
var data = d3.map();
d3.csv("../path/to/your/file.csv", /* accessor */ function(d) {
data.set(d.id, d.peopleVisited);
});
... which uses the column id as the key.

Resources