score:1
Your data needs updates for a d3 tree:
- A d3 tree needs a single root node -
IT
andIT-Tools
need a parent node - The
Testing
node is ambiguous as it is both a child ofProgramming
andIT-Tools
- so you will need update e.g.Testing1
andTesting2
Your 2nd data frame shows your hierarchy is unbalanced (leaves at different depths) because of the None
s in branch2
and branch3
. Therefore, your output JSON should be individual branch definitions, rather than multiple definitions per row, like this:
parent,child,color
IT,Programming,None
Programming,Trending,None
Trending,Demand,None
Demand,Python,#6200ea
etc
This is more efficient than multiple-branches-per-row which has redundancy. E.g. IT
being the parent of Programming
is defined multiple times whereas with the parent/ child structure it is defined a single time.
The following code translates your input to an output you can send as a response to a client and then use d3 to build a tree.
We can use a set to store unique strings of pairs of parents and then add an item for the last parent/ child. Then create another dataframe from this set (creating columns based on split by ;
in a similar vein to your OP) and then export as JSON:
import io
import pandas as pd
# data as a string
text = '''Parent Child Color
IT;Programming;Trending;Demand Python #6200ea
IT;Programming;Trending;Demand Docker #7c4dff
IT;Programming;Testing1 Selenium #b388ff
IT;Programming;Old C/C++/C# #ff1744
IT-Tools;Testing2 HP-UFT #aa00ff
IT-Tools;IDE PyCharm #9c27b0'''
# your original data frame
df = pd.read_csv(io.StringIO(text), sep=r'\s+')
# prepend a Root to Parent column
df.Parent = 'Root;' + df.Parent
# dataframe to set for unique branches
# start with just root in the set
branch_strings = set([';Root;'])
for index, row in df.iterrows():
parents = row.Parent.split(';')
for curr, next in zip(parents, parents[1:]):
branch_strings.add(';'.join([curr, next, '']))
branch_strings.add(';'.join([next, row.Child, row.Color]))
# set to list
branches = list(map(lambda row: row.split(';'), branch_strings))
# new dataframe from relations
df2 = pd.DataFrame(branches, columns=['parent', 'child', 'color'])
# JSON
json = df2.to_json(orient='records')
print(json)
Which produces this JSON output:
const data = [
{"parent":"Programming","child":"Old","color":""},
{"parent":"Testing1","child":"Selenium","color":"#b388ff"},
{"parent":"","child":"Root","color":""},{"parent":"IT-Tools","child":"IDE","color":""},
{"parent":"IDE","child":"PyCharm","color":"#9c27b0"},
{"parent":"Programming","child":"Trending","color":""},
{"parent":"IT","child":"Programming","color":""},
{"parent":"Trending","child":"Demand","color":""},
{"parent":"Root","child":"IT","color":""},
{"parent":"Old","child":"C\/C++\/C#","color":"#ff1744"},
{"parent":"Programming","child":"Testing1","color":""},
{"parent":"Root","child":"IT-Tools","color":""},{"parent":"IT-Tools","child":"Testing2","color":""},
{"parent":"Demand","child":"Docker","color":"#7c4dff"},
{"parent":"Demand","child":"Python","color":"#6200ea"},
{"parent":"Testing2","child":"HP-UFT","color":"#aa00ff"}
];
For a D3 example with that JSON - please review the accepted answer here. The adaptaion below is just a proof of concept for your unbalanced hierarchy input. To convert to the block in your OP is beyond the scope of a Stack Overflow answer but this should put you in the right direction:
const data = [
{"parent":"Programming","child":"Old","color":""},
{"parent":"Testing1","child":"Selenium","color":"#b388ff"},
{"parent":"","child":"Root","color":""},{"parent":"IT-Tools","child":"IDE","color":""},
{"parent":"IDE","child":"PyCharm","color":"#9c27b0"},
{"parent":"Programming","child":"Trending","color":""},
{"parent":"IT","child":"Programming","color":""},
{"parent":"Trending","child":"Demand","color":""},
{"parent":"Root","child":"IT","color":""},
{"parent":"Old","child":"C\/C++\/C#","color":"#ff1744"},
{"parent":"Programming","child":"Testing1","color":""},
{"parent":"Root","child":"IT-Tools","color":""},{"parent":"IT-Tools","child":"Testing2","color":""},
{"parent":"Demand","child":"Docker","color":"#7c4dff"},
{"parent":"Demand","child":"Python","color":"#6200ea"},
{"parent":"Testing2","child":"HP-UFT","color":"#aa00ff"}
];
const root = d3.stratify()
.id(d => d["child"])
.parentId(d => d["parent"])
(data);
const margin = {left: 40, top: 40, right: 40, bottom: 40}
const width = 500;
const height = 200;
const svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
const g = svg.append("g")
.attr('transform', `translate(${margin.left},${ margin.right})`);
const tree = d3.tree()
.size([height-margin.top-margin.bottom,width-margin.left-margin.right]);
const link = g.selectAll(".link")
.data(tree(root).links())
.enter()
.append("path")
.attr("class", "link")
.attr("d", d3.linkHorizontal()
.x(function(d) { return d.y; })
.y(function(d) { return d.x; })
);
const node = g.selectAll(".node")
.data(root.descendants())
.enter()
.append("g")
.attr("transform", function(d) {
return `translate(${d.y},${d.x})`;
});
node.append("circle")
.attr("r", 5)
.style("fill", function(d) {
return d.data.color ? d.data.color : "#000";
});
node.append("text")
.attr("class", "label")
.text(function(d) { return d.data.child; })
.attr('y', -4)
.attr('x', 0)
.attr('text-anchor','middle');
path {
fill: none;
stroke: steelblue;
stroke-width: 1px;
}
.label {
font-size: smaller;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
Source: stackoverflow.com
Related Query
- How to generate JSON from a pandas data frame for dynamic d3.js tree
- How to load data from an internal JSON array rather than from an external resource / file for a collapsible tree in d3.js?
- How to read JSON data from same json for tree layout insteadof reading from other .JSON file?
- How to fetch data from json file to draw a dynamic graph by using d3.js
- Updating links on a force directed graph from dynamic json data
- Generate (multilevel) flare.json data format from flat json
- How do I create a tree layout using JSON data in d3.v4 - without stratify()
- How can I efficiently move from a Pandas dataframe to JSON
- d3.js how to generate tree hierarchy from csv or table
- D3 Library — How To Access Data from JSON in this example
- how to add tooltip for rectangles in d3.js reading from json
- D3.js : How to read data from JSON in Grouped Bar Chart
- How to export/save updated d3.js v4 tree json data string
- How do I Bind Data from a .tsv to an SVG's paths using d3.js for a Choropleth Map
- Getting data from JSON for D3.js
- How to load external JSON data from a Web API in d3.js?
- How can i bind an json data with a key and Name for display
- How to request data from json in d3?
- How do you call data from nested JSON array using d3?
- how to display data from 1st point on words on y axis for line chart in d3.js
- Node generation from json data for force layout
- How to convert Data table to tree json format dynamically?
- How to load data to D3 chart from JSON when there are only tuples
- Given a data frame in JSON format, how can I automatically assign colors to variables in D3?
- How to call JSON from a file instead of in-line for Multi-Edge D3 Example
- D3js: How to generate X axis labels/ticks if data for one of axis is 0?
- How to generate a JSON file from Mondrian output
- How to get a data from an analysis in R in Json file format to get D3 visualisations?
- how to convert data selected from a postgres database to json or csv to use it with d3js lib?
- How to generate parent child relation data from networkx to work with d3.js?
More Query from same tag
- D3 samples in a Microsoft Stack
- Make SVGs on top of leaflet map not respond to pan events
- Is it possible to save extra data in the node object of a forced layout
- yFiles Graphsource alternative(js or python) for "DAGs" or "networks"
- Fix overlap on multiple stacked barchart
- how to start drawing a line with a space between y-axis and it using d3js
- d3.js force layout auto zoom/scale after loading
- Rendering hexagons in d3.js in the wordmap
- Inverting bars on d3.js bar chart
- Bar-chart Bars Bunching up with use of Brush
- How to plot line chart using Json File
- add different shapes to d3 force layout
- Area chart with multicolour gradient
- Passing a JSON object from visualwebgui to a htmlbox html page?
- How can I zoom in on a point in d3.js, manually, without using d3.behavior.zoom()?
- d3 Generate overlapping circles
- draw circle in the end of SVG path in realtime line chart D3.js
- How to make the scale to round to the nearest multiple of #?
- y scale in scatterplot scales y axis differently than y values D3.js
- d3 mouse event return element
- How do I associate SVG elements generated by graphviz to elements in the DOT source code
- How to display just the weekdays on x-axis?
- How can I refactor a d3 pie to accept more or less data points?
- Remove and update groups on redraw with D3
- d3.js time scale unexpected behaviour
- d3.min / d3.max - getting values with related date
- D3 Line Chart - Uncaught TypeError: Cannot read property 'length' of undefined
- d3 height function returns NaN
- Calculate string size without render
- d3 force layout - how to create a more sensible node structure