Conversion from nested objects to hierarchical data structure in d3.js - d3.js

I want to convert the following nested object into hierarchical data structure
{
"AP":{
"districts":{
"Anantapur":{
"total":{
"confirmed":66593,
"deceased":587,
"recovered":65697
}
},
"Chittoor":{
...
}
}
},
"AR":{
"districts":{....}
}...so on
}
to
[
{
"name":"AP",
"children":[
{
"name":"Anantapur",
"children":[
{
"name":"confirmed",
"value":66593
},
{
"name":"deceased",
"value":587
},
{
"name":"recovered",
"value":65697
}
]
},
{
...
}
]
},...so on
]
How can this be done?...I tried using d3 nest but there is no common key value like
"state":"AP", "state":"AR".
Here "AP" and "AR" are keys themselves. Is there any other method of doing this?

You can use Object.keys(data).map(function(key) { to create an array with an item for every property in your objects. You can nest this approach to get to the desired outcome. Here's a manual solution for your data structure (you could use a recursive function for arbitrarily nested data with a slightly different output, but given the depth of the object and the structure of the output, I have not done that):
var data = { "State One":{
"districts":{
"Region A":{
"total":{
"confirmed":1,
"deceased":2,
"recovered":3
}
},
"Region B":{
"total":{
"confirmed":4,
"deceased":5,
"recovered":6
}
}
}
},
"State Two":{
"districts":{
"Region C":{
"total":{
"confirmed":7,
"deceased":8,
"recovered":9
}
}
}
}
}
var output = Object.keys(data).map(function(key) {
return {
name:key,
children: Object.keys(data[key]["districts"]).map(function(district) {
return {
name:district,
children: Object.keys(data[key]["districts"][district]["total"]).map(function(d) {
return { name: d, value:data[key]["districts"][district]["total"][d] }
})
}
})
}
})
console.log(output);

Related

Spring Boot Mongo update nested array of documents

I'm trying to set an attribute of a document inside an array to uppercase.
This is a document example
{
"_id": ObjectId("5e786a078bc3b3333627341e"),
"test": [
{
"itemName": "alpha305102992",
"itemNumber": ""
},
{
"itemName": "beta305102630",
"itemNumber": "P5000"
},
{
"itemName": "gamma305102633 ",
"itemNumber": ""
}]
}
I already tried a lot of thing.
private void NameElementsToUpper() {
AggregationUpdate update = AggregationUpdate.update();
//This one does not work
update.set("test.itemName").toValue(StringOperators.valueOf(test.itemName).toUpper());
//This one also
update.set(SetOperation.set("test.$[].itemName").withValueOfExpression("test.#this.itemName"));
//And every variant in between these two.
// ...
Query query = new Query();
UpdateResult result = mongoTemplate.updateMulti(query, update, aClass.class);
log.info("updated {} records", result.getModifiedCount());
}
I see that Fields class in spring data is hooking into the "$" char and behaving special if you mention it. Do not seem to find the correct documentation.
EDIT: Following update seems to work but I do not seem to get it translated into spring-batch-mongo code
db.collection.update({},
[
{
$set: {
"test": {
$map: {
input: "$test",
in: {
$mergeObjects: [
"$$this",
{
itemName: {
$toUpper: "$$this.itemName"
}
}
]
}
}
}
}
}
])
Any solutions?
Thanks!
For now I'm using which does what i need. But a spring data way would be cleaner.
mongoTemplate.getDb().getCollection(mongoTemplate.getCollectionName(Application.class)).updateMany(
new BasicDBObject(),
Collections.singletonList(BasicDBObject.parse("""
{
$set: {
"test": {
$map: {
input: "$test",
in: {
$mergeObjects: [
"$$this",
{
itemName: { $toUpper: "$$this.itemName" }
}
]
}
}
}
}
}
"""))
);

Unknown Type of Strapi/Gatsby Graphql Query Fragment

I'm trying to query data within a Strapi Dynamic Zone in Gatsby. In the Graphql Playground I can get this to work, but using the same query in Gatsby I receive the following error in the terminal:
error Unknown type "ComponentTextArticleCopy" graphql/template-strings
And my query in article.js
export const query = graphql`
query ArticleTemplate($id: String!) {
strapiArticle(id: { eq: $id }) {
articleHeader {
articleTitle
articleSnippet
}
articleContent {
__typename
... on ComponentTextArticleCopy {
contentCopy
}
... on ComponentImageContentImg {
imgCaption
}
... on ComponentTextArticleQuote {
contentQuote
}
}
}
}
`
According to the Graphql docs, Inline Fragment would seem to be the right approach but clearly I've got something wrong somewhere.
The following query 'works' on Gatsby but tries to resolve for all components:
query MyQuery {
allStrapiArticle {
edges {
node {
__typename
articleContent {
contentCopy
contentQuote
}
}
}
}
}
{
"data": {
"allStrapiArticle": {
"edges": [
{
"node": {
"__typename": "StrapiArticle",
"articleContent": [
{
"contentCopy": null,
"contentQuote": null
},
{
"contentCopy": "What a great city Gothenburg is. We even took a trip out to the archipelago. ",
"contentQuote": null
},
{
"contentCopy": null,
"contentQuote": null
},
{
"contentCopy": null,
"contentQuote": "You must visit at have fika"
}
]
}
}
]
}
},
Deleting Cache folder and running again worked for me.

How to query multiple images in Gatsby from Strapi using Graphql

I have set up a multiple media(images) field called pictures on my project content type on Strapi and I have added 2 projects with pictures containing 4 images each.
I want to query these images in Gatsby using Graphql.
This is my plugins array in gatsby-config.js
plugins: [
`gatsby-plugin-react-helmet`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images`,
},
},
`gatsby-plugin-sharp`,
`gatsby-transformer-sharp`,
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `gatsby-starter-default`,
short_name: `starter`,
start_url: `/`,
background_color: `#663399`,
theme_color: `#663399`,
display: `minimal-ui`,
icon: `src/images/gatsby-icon.png`,
},
},
{
resolve: `gatsby-source-strapi`,
options: {
apiURL: `http://localhost:1337`,
queryLimit: 1000,
contentTypes: [`project`],
},
}]
This is my graphql query on localhost:8000/___graphql
query MyQuery {
allStrapiProject {
nodes {
pictures {
formats {
thumbnail {
childImageSharp {
fluid {
src
}
}
}
}
}
}
}
}
This is the result I am getting
{
"data": {
"allStrapiProject": {
"nodes": [
{
"pictures": [
{
"formats": {
"thumbnail": null
}
},
{
"formats": {
"thumbnail": {
"childImageSharp": {
"fluid": {
"src": "/static/eb8a7ee6108ecc0e6185aced82c3316b/b4216/167f320a448c2d6ff65acf179ee627e2.jpg"
}
}
}
}
},
{
"formats": {
"thumbnail": null
}
},
{
"formats": {
"thumbnail": null
}
}
]
},
{
"pictures": [
{
"formats": {
"thumbnail": null
}
},
{
"formats": {
"thumbnail": null
}
},
{
"formats": {
"thumbnail": null
}
},
{
"formats": {
"thumbnail": null
}
}
]
}
]
}
}
}
All of the thumbnails contain null except for one.
I have tried running 'gatsby clean' and sometimes get the query output to have same image urls in multiple places even though i don't have repeating images on Strapi.
As of now, there is no "official" way to make it happen. But there is a workaround which creates a custom node in the build process. For a graphql query like below
query MyQuery {
allStrapiPortfolio {
edges {
node {
category {
images {
localFile {
childImageSharp {
fluid {
base64
tracedSVG
srcWebp
srcSetWebp
originalImg
originalName
}
}
}
}
}
}
}
}
}
The code given below creates the localFile node after images. The code should go in gatsby-node.js.
const { createRemoteFileNode } = require(`gatsby-source-filesystem`);
exports.onCreateNode = async ({ node, actions, store, cache }) => {
const { createNode, createNodeField } = actions;
if (node.internal.type !== null && node.internal.type === "StrapiPortfolio") {
for (const category of node.category) {
for (const image of category.images) {
console.log(image);
const fileNode = await createRemoteFileNode({
url: "http://localhost:1337" + image.url,
store,
cache,
createNode,
createNodeId: (id) => image.id.toString(),
});
if (fileNode) {
image.localFile___NODE = fileNode.id;
}
}
}
}
};
Please note that you will have to customize the code depending on your needs. In my solution, I used two for loops because of my data structure. If you're unsure or just want to check if your custom code works, you can simply add a console.log(node) before the first if statement and a console.log(image) after the second for loop(in my case). That should give you an indication about your data structure and in which way you should proceed.
You need to create a localFile___NODE.
First, you need to edit gatsby-node.js file.
const { createRemoteFileNode } = require(`gatsby-source-filesystem`)
exports.onCreateNode = async ({
node,
actions,
store,
cache,
createNodeId,
}) => {
const { createNode } = actions
// replace ".sliderHome" for the name of multiple media in Strapi CMS
let sliderImages = node.sliderHome
// replace “StrapiHome” for your node type
if (node.internal.type === "StrapiHome") {
if (sliderImages.length > 0) {
// sliderImages.forEach(el => console.log(el))
const images = await Promise.all(
sliderImages.map(el =>
createRemoteFileNode({
url: `http://localhost:1337${el.url}`,
parentNodeId: node.id,
store,
cache,
createNode,
createNodeId,
})
)
)
sliderImages.forEach((image, i) => {
image.localFile___NODE = images[i].id
})
}
}
}
later restart Gatsby and now this is your query
query MyQuery {
allStrapiProject {
nodes {
pictures {
localFile{
childImageSharp{
fluid(maxWidth: 1200){
// or for gatsby use ...GatsbyImageSharpFluid_withWebp
src
}
}
}
}
}
}
}
this has worked for me to bring multiple images with a good quality I hope it works for you
Try below, replace the value you need to display:
Here I am the example for the user avatar
query MyQuery {
allStrapiUser {
edges {
node {
id
avatar {
publicURL
childImageSharp {
fluid {
src
aspectRatio
}
}
}
}
}
}
}
and:
const poster = data.allStrapiUser.edges[0].node
<Img fluid={{aspectRatio: 1.6, src: poster.avatar.publicURL}}/>

How to flat query result?

With a sample make it easy understand, with https://developer.github.com/v4/explorer/
query the viewer info:
query {
viewer {
followers {
totalCount
}
following {
totalCount
}
}
}
the result is:
{
"data": {
"viewer": {
"followers": {
"totalCount": 131
},
"following": {
"totalCount": 28
}
}
}
}
what I want is:
{
"data": {
"viewer": {
"followersCount" 131,
"followingCount": 28
}
}
}
so does GraphQL support this ? and how to do it?
GraphQL doesn't support this type of data flattening.
You must change the data structure in your code or work with the returned data structure.
EDIT: I just came across this repository (graphql-lodash) that could help you achieve what you want.

awesome_nested_set and json

I have a tree of json data. This data contains a nested array of IDs. I need to convert the tree back to awesome_nested_set.
My tree looks like this:
{
"menu_211"=>
{
"menu_135"=>
{
"menu_197"=>
{
}
},
"menu_144"=>
{
},
"menu_208"=>
{
}
},
"menu_1"=>
{
"menu_80"=>
{
"menu_81"=>
{
},
"menu_82"=>
{
},
"menu_202"=>
{
}
}
}
What is the best way to convert this to what nested set needs to save the records new left and right fields?
Found a solution. http://github.com/matenia/jQuery-Awesome-Nested-Set-Drag-and-Drop

Resources