D3 treemap json data format - d3.js

I'm new to d3js. I've gone through several examples of the treemap visualization and noticed that the data has the same hierarchical structure:
{
"name": "flare",
"children": [
...
]
...
}
But what if I have an array of objects with same set of properties without nesting:
[
{
"CourseID": "15.010B",
"Subject": "15.01",
"Section": "B",
"Department": "Managerial Economics",
"Professor": "Doyle",
...
},
{
"CourseID": "15.010B",
"Subject": "15.01",
"Section": "B",
...
},
...
]
Should I make it hierarchical by myself? Can you provide me with visual treemap example for this type of data format. Thanks in advance.

d3's built-in nest feature can easily create this type of hierarchical data for you, for example:
var nest = d3.nest()
.key(function(d) { return d.Department; })
.key(function(d) { return d.Subject; })
.key(function(d) { return d.Section; })
.entries(_dataset_name_);
will create a suitably hierarchical dataset.

Formatting your JSON into a hierarchical structure can be tedious. I used Google Refine which allowed me to import CSV,JSON or Excel files and "refine" them into the JSON structures of my choice. It seem a bit of a pain to set up, but once completed, you will have a tool for manipulating your data into structures of your choice going forward.

Related

GraphQL: Explore API without a wildcard (*)?

I am new to GraphQL and I wonder how I can explore an API without a possible wildcard (*) (https://github.com/graphql/graphql-spec/issues/127).
I am currently setting up a headless Craft CMS with GraphQL and I don't really know how my data is nested.
Event with the REST API I have no chance of just getting all the data, because I have to setup all the endpoints and therefore I have to know all field names as well.
So how could I easily explore my CraftCMS data structure?
Thanks for any hints on this.
Cheers
merc
------ Edit -------
If I use #simonpedro s suggestion:
{
__schema {
types {
name
kind
fields {
name
}
}
}
}
I can see a lot of types (?)/fields (?)...
For example I see:
{
"name": "FlexibleContentTeaser",
"kind": "OBJECT",
"fields": [
{
"name": "id"
},
{
"name": "enabled"
},
{
"name": "teaserTitle"
},
{
"name": "text"
},
{
"name": "teaserLink"
},
{
"name": "teaserLinkConnection"
}
]
But now I would like to know how a teaserLink ist structured.
I somehow found out that the teaserLink (it is a field with the type Entries, where I can link to another page) has the properties url & title.
But how would I set up query to explore the properties available within teaserLink?
I tried all sorts of queries, but I am always confrontend with messages like this:
I would be really glad if somebody could give me another pointer how I can find out which properties I can actually query...
Thank you
As far as I'm concerned currently there is no graphql implementation with that capability. However, if what you want to do is to explore the "data structure", i.e, the schema, you should use schema instrospection, which was thought for that (explore the graphql schema). For example, a simple graphql instrospection query would be like this:
{
__schema {
types {
name
kind
fields {
name
}
}
}
}
References:
- https://graphql.org/learn/introspection/
UPDATE for edit:
What you want to do I think is the following:
Make a query like this
{
__schema {
types {
name
kind
fields {
name
type {
fields {
name
}
}
}
}
}
}
And then find the wished type field to grab more information (the fields) from it. Something like this (I don't know if this works, just an idea):
const typeFlexibleContentTeaser = data.__schema.types.find(t => t === "FlexibleContentTeaser")
const teaserLinkField = typeFlexibleContentTeaser.fields.find(f => f.name === "teaserLink")
const teaserLinkField = teaserLinkField.type.fields;
i.e, you have to transverse recursively through the type field.

Gatsby and GraphQL - How to Filter Array Within Query

I started using Gatsby along with GraphQL to return a query that lists all galleries that are part of a specific category. In this example the category is called "Lifestyle". This all works successfully and I get an array with all of the Galleries in the category. I also need to sort this array based off a sub field called "date". Is that possible to do via the GraphQL query itself? I tried adding (sort: { fields: [date], order: DESC }) to the gallery field but that didn't work.
Any thoughts on how to achieve this or is this as close as GraphQL can get me to what I need?
Thanks in advance for any help. Still trying to wrap my head around GraphQL.
Ryan
Example of my current query
Could you provide a bit more details about your content model?
If you use a "Reference" field in contentful, it is sadly not possible as of now with the plugin as far as I know.
If you use a "Short text, list" field, like the tags in the default example.
With the default example, you can do the following query:
{
allContentfulPost(filter:{tags:{eq:"fantasy"}}, sort:{fields:[date], order:DESC}) {
edges {
node {
title {
childMarkdownRemark {
html
}
}
slug
date
}
}
}
}
It will give you the following result:
{
"data": {
"allContentfulPost": {
"edges": [
{
"node": {
"title": {
"childMarkdownRemark": {
"html": "<p>Disney Movie</p>"
}
},
"slug": "down-the-rabbit-hole",
"date": "2017-11-26"
}
},
{
"node": {
"title": {
"childMarkdownRemark": {
"html": "<p>Old book</p>"
}
},
"slug": "down-the-rabbit-hole-2",
"date": "1865-11-26"
}
}
]
}
}
}
I came across this same issue as I was trying to sort posts from a category tag that I was using in Contentful. Like #chmac said, you can sort the data from GraphQL with Javascript.
I had to search for a good example, but I finally found one in this Gatsby starter:
Github: https://github.com/ryanwiemer/gatsby-starter-gcn/blob/master/src/templates/tag.js
Live Example: https://gcn.netlify.com/tag/fancy/
You can see in the source file that they sorted the data in a new constant called posts using moment (https://www.npmjs.com/package/moment) and lodash. In my personal example I had to tweak my constant like so:
const courses = orderBy(
this.props.data.contentfulCategory.course,
// eslint-disable-next-line
[object => new moment(object.createdAt)],
['desc']
)
Then I just used a map function like so in the component return:
{/* Courses */}
{courses.map(course => (
<div className="hero__profile" key={course.id}>
<h2>{course.title}</h2>
</div>
))}
I hope this helps!

format flare.jason from existing json

I am formatting regular json data to a flare format for a chart I am working on and ran into an issue creating the children. I have a fiddle of my current work and was hoping someone could spot what I missed.
not working
I only get it to return this [no children]:
[
{
"parent": "new skill",
"name": "Advanced",
"AgtName": "amy"
},
{
"parent": "new skill",
"name": "Advanced",
"AgtName": "GARY"
}
]
Since you are using d3, you can use d3.nest to get a hierarchical structure from an array. Here is a snippet based on your code:
let tree = d3.nest().key(node => node.name).entries(data);
Working demo

Try to understand normalizr's schema.entity VS Array and Object

All:
I am trying to understand the relationship between Entity Array and Object:
Are they just different format to describe diff structure of data? Or Entity is quite diff from the rest two?
The normalized data result has a structure like {result:,entities:}, are the data structures only defined with schema.Entity put inside entities or so can schema.Array and Object? When I define a schema only use Object and Array, it seems nothing put in entities, I am not sure if it is my schema def fault or this is how normalizr work?
If only schema.Entity() defined data can put into entities, then how can I put an data array into it, something like {0:.., 1:..,2:,}?
For exmaple, I have data like:
var data = [
{
id:"0",
items:[
{
id: "0",
data: {name:"data-0-0"}
},
{
id: "1",
data: {name:"data-0-1"}
}
]
},
{
id:"1",
items:[
{
id: "0",
data: {name:"data-1-0"}
},
{
id: "1",
data: {name:"data-1-1"}
}
]
}
]
const normalizedData = normalize(data, [{items:[{data:{}}]}]);
And the normalized data is like:
{
"entities": {},
"result": {
"0": {
"id": "0",
"items": [
{
"id": "0",
"data": {
"name": "data-1-0"
}
}
]
}
}
}
Thanks
Question: Are they just different format to describe diff structure of data? Or Entity is quite diff from the rest two?
Answer: Yes. An Entity is a singular object that has a unique identifier associated with it. Array and Object are more generic structures that can't be uniquely identified. In your case, it looks like you only need to use Array and Entity for the data you're describing.
Question: Are the data structures only defined with schema? Entity put inside entities?
Answer: Yes.

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