multi-ring pie chart using d3js - d3.js

I am trying to understand how to create a multi ring pie chart using d3js . Here is what I have tried and got so far. I am pretty sure its not reading the data correctly here. Any example on how should I be creating such a chart. What I am trying to do is to get each ring based on each group like pop quarter and so on.
var dataset = [
{
"name": "Population Quater",
"code": "POP_QUATER",
"parent": "POP_BY_QUAT",
"children": [
{
"name": "POP_CYQ1",
"code": "POP_CYQ1",
"parent": "POP_QUATER",
"value": "6772",
"label": "CYQ1",
"children": []
},
{
"name": "POP_CYQ2",
"code": "POP_CYQ2",
"parent": "POP_QUATER",
"value": "6716",
"label": "CYQ2",
"children": []
},
{
"name": "POP_CYQ3",
"code": "POP_CYQ3",
"parent": "POP_QUATER",
"value": "6714",
"label": "CYQ3",
"children": []
},
{
"name": "POP_CYQ4",
"code": "POP_CYQ4",
"parent": "POP_QUATER",
"value": "6703",
"label": "CYQ4",
"children": []
},
{
"name": "POP_LYQ1",
"code": "POP_LYQ1",
"parent": "POP_QUATER",
"value": "6721",
"label": "LYQ1",
"children": []
},
{
"name": "POP_LYQ2",
"code": "POP_LYQ2",
"parent": "POP_QUATER",
"value": "6671",
"label": "LYQ2",
"children": []
},
{
"name": "POP_LYQ3",
"code": "POP_LYQ3",
"parent": "POP_QUATER",
"value": "6708",
"label": "LYQ3",
"children": []
},
{
"name": "POP_LYQ4",
"code": "POP_LYQ4",
"parent": "POP_QUATER",
"value": "6734",
"label": "LYQ4",
"children": []
}
]
},
{
"name": "Transient Pop",
"code": "TRANSIENT_POP",
"parent": "POP_BY_QUAT",
"label": "Transient Pop",
"children": [
{
"name": "TRANSIENT_LYQ1",
"code": "TRANSIENT_LYQ1",
"parent": "TRANSIENT_POP",
"value": "54",
"label": "LYQ1",
"children": []
},
{
"name": "TRANSIENT_LYQ2",
"code": "TRANSIENT_LYQ2",
"parent": "TRANSIENT_POP",
"value": "86",
"label": "LYQ2",
"children": []
},
{
"name": "TRANSIENT_LYQ3",
"code": "TRANSIENT_LYQ3",
"parent": "TRANSIENT_POP",
"value": "219",
"label": "LYQ3",
"children": []
},
{
"name": "TRANSIENT_LYQ4",
"code": "TRANSIENT_LYQ4",
"parent": "TRANSIENT_POP",
"value": "191",
"label": "LYQ4",
"children": []
},
{
"name": "TRANSIENT_CYQ1",
"code": "TRANSIENT_CYQ1",
"parent": "TRANSIENT_POP",
"value": "52",
"label": "CYQ1",
"children": []
},
{
"name": "TRANSIENT_CYQ2",
"code": "TRANSIENT_CYQ2",
"parent": "TRANSIENT_POP",
"value": "91",
"label": "CYQ2",
"children": []
},
{
"name": "TRANSIENT_CYQ3",
"code": "TRANSIENT_CYQ3",
"parent": "TRANSIENT_POP",
"value": "222",
"label": "CYQ3",
"children": []
},
{
"name": "TRANSIENT_CYQ4",
"code": "TRANSIENT_CYQ4",
"parent": "TRANSIENT_POP",
"value": "186",
"label": "CYQ4",
"children": []
}
]
},
{
"name": "Seasonal Pop",
"code": "SEASONAL_POP",
"parent": "POP_BY_QUAT",
"label": "Seasonal Pop",
"children": [
{
"name": "SEASONAL_LYQ1",
"code": "SEASONAL_LYQ1",
"parent": "SEASONAL_POP",
"value": "2",
"label": "LYQ1",
"children": []
},
{
"name": "SEASONAL_LYQ2",
"code": "SEASONAL_LYQ2",
"parent": "SEASONAL_POP",
"value": "24",
"label": "LYQ2",
"children": []
},
{
"name": "SEASONAL_LYQ3",
"code": "SEASONAL_LYQ3",
"parent": "SEASONAL_POP",
"value": "152",
"label": "LYQ3",
"children": []
},
{
"name": "SEASONAL_LYQ4",
"code": "SEASONAL_LYQ4",
"parent": "SEASONAL_POP",
"value": "55",
"label": "LYQ4",
"children": []
},
{
"name": "SEASONAL_CYQ1",
"code": "SEASONAL_CYQ1",
"parent": "SEASONAL_POP",
"value": "2",
"label": "CYQ1",
"children": []
},
{
"name": "SEASONAL_CYQ2",
"code": "SEASONAL_CYQ2",
"parent": "SEASONAL_POP",
"value": "22",
"label": "CYQ2",
"children": []
},
{
"name": "SEASONAL_CYQ3",
"code": "SEASONAL_CYQ3",
"parent": "SEASONAL_POP",
"value": "161",
"label": "CYQ3",
"children": []
},
{
"name": "SEASONAL_CYQ4",
"code": "SEASONAL_CYQ4",
"parent": "SEASONAL_POP",
"value": "55",
"label": "CYQ4",
"children": []
}
]
}
];
var width = 460,
height = 300,
cwidth = 25;
var color = d3.scale.category20();
var pie = d3.layout.pie()
.sort(null).value(function (d) {
return d.value;//since score is the parameter for the pie
});
var arc = d3.svg.arc();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var gs = svg.selectAll("g").data(d3.values(dataset)).enter().append("g");
var path = gs.selectAll("path")
.data(function(d) { return pie(d.value); })
.enter().append("path")
.attr("fill", function(d, i) { return color(i); })
.attr("d", function(d, i, j) { return arc.innerRadius(10+cwidth*j).outerRadius(cwidth*(j+1))(d); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.13/d3.min.js"></script>

You are not binding the data array (dataset) to your groups. It should be:
var gs = svg.selectAll("g")
.data(dataset)
.enter()
.append("g");
And then, for the inner selections, use children:
var path = gs.selectAll("path")
.data(function(d) {
return pie(d.children);
})
//etc...
Here is your code with those changes:
var dataset = [{
"name": "Population Quater",
"code": "POP_QUATER",
"parent": "POP_BY_QUAT",
"children": [{
"name": "POP_CYQ1",
"code": "POP_CYQ1",
"parent": "POP_QUATER",
"value": "6772",
"label": "CYQ1",
"children": []
}, {
"name": "POP_CYQ2",
"code": "POP_CYQ2",
"parent": "POP_QUATER",
"value": "6716",
"label": "CYQ2",
"children": []
}, {
"name": "POP_CYQ3",
"code": "POP_CYQ3",
"parent": "POP_QUATER",
"value": "6714",
"label": "CYQ3",
"children": []
}, {
"name": "POP_CYQ4",
"code": "POP_CYQ4",
"parent": "POP_QUATER",
"value": "6703",
"label": "CYQ4",
"children": []
}, {
"name": "POP_LYQ1",
"code": "POP_LYQ1",
"parent": "POP_QUATER",
"value": "6721",
"label": "LYQ1",
"children": []
}, {
"name": "POP_LYQ2",
"code": "POP_LYQ2",
"parent": "POP_QUATER",
"value": "6671",
"label": "LYQ2",
"children": []
}, {
"name": "POP_LYQ3",
"code": "POP_LYQ3",
"parent": "POP_QUATER",
"value": "6708",
"label": "LYQ3",
"children": []
}, {
"name": "POP_LYQ4",
"code": "POP_LYQ4",
"parent": "POP_QUATER",
"value": "6734",
"label": "LYQ4",
"children": []
}]
}, {
"name": "Transient Pop",
"code": "TRANSIENT_POP",
"parent": "POP_BY_QUAT",
"label": "Transient Pop",
"children": [{
"name": "TRANSIENT_LYQ1",
"code": "TRANSIENT_LYQ1",
"parent": "TRANSIENT_POP",
"value": "54",
"label": "LYQ1",
"children": []
}, {
"name": "TRANSIENT_LYQ2",
"code": "TRANSIENT_LYQ2",
"parent": "TRANSIENT_POP",
"value": "86",
"label": "LYQ2",
"children": []
}, {
"name": "TRANSIENT_LYQ3",
"code": "TRANSIENT_LYQ3",
"parent": "TRANSIENT_POP",
"value": "219",
"label": "LYQ3",
"children": []
}, {
"name": "TRANSIENT_LYQ4",
"code": "TRANSIENT_LYQ4",
"parent": "TRANSIENT_POP",
"value": "191",
"label": "LYQ4",
"children": []
}, {
"name": "TRANSIENT_CYQ1",
"code": "TRANSIENT_CYQ1",
"parent": "TRANSIENT_POP",
"value": "52",
"label": "CYQ1",
"children": []
}, {
"name": "TRANSIENT_CYQ2",
"code": "TRANSIENT_CYQ2",
"parent": "TRANSIENT_POP",
"value": "91",
"label": "CYQ2",
"children": []
}, {
"name": "TRANSIENT_CYQ3",
"code": "TRANSIENT_CYQ3",
"parent": "TRANSIENT_POP",
"value": "222",
"label": "CYQ3",
"children": []
}, {
"name": "TRANSIENT_CYQ4",
"code": "TRANSIENT_CYQ4",
"parent": "TRANSIENT_POP",
"value": "186",
"label": "CYQ4",
"children": []
}]
}, {
"name": "Seasonal Pop",
"code": "SEASONAL_POP",
"parent": "POP_BY_QUAT",
"label": "Seasonal Pop",
"children": [{
"name": "SEASONAL_LYQ1",
"code": "SEASONAL_LYQ1",
"parent": "SEASONAL_POP",
"value": "2",
"label": "LYQ1",
"children": []
}, {
"name": "SEASONAL_LYQ2",
"code": "SEASONAL_LYQ2",
"parent": "SEASONAL_POP",
"value": "24",
"label": "LYQ2",
"children": []
}, {
"name": "SEASONAL_LYQ3",
"code": "SEASONAL_LYQ3",
"parent": "SEASONAL_POP",
"value": "152",
"label": "LYQ3",
"children": []
}, {
"name": "SEASONAL_LYQ4",
"code": "SEASONAL_LYQ4",
"parent": "SEASONAL_POP",
"value": "55",
"label": "LYQ4",
"children": []
}, {
"name": "SEASONAL_CYQ1",
"code": "SEASONAL_CYQ1",
"parent": "SEASONAL_POP",
"value": "2",
"label": "CYQ1",
"children": []
}, {
"name": "SEASONAL_CYQ2",
"code": "SEASONAL_CYQ2",
"parent": "SEASONAL_POP",
"value": "22",
"label": "CYQ2",
"children": []
}, {
"name": "SEASONAL_CYQ3",
"code": "SEASONAL_CYQ3",
"parent": "SEASONAL_POP",
"value": "161",
"label": "CYQ3",
"children": []
}, {
"name": "SEASONAL_CYQ4",
"code": "SEASONAL_CYQ4",
"parent": "SEASONAL_POP",
"value": "55",
"label": "CYQ4",
"children": []
}]
}];
var width = 460,
height = 300,
cwidth = 25;
var color = d3.scale.category20();
var pie = d3.layout.pie()
.sort(null).value(function(d) {
return d.value; //since score is the parameter for the pie
});
var arc = d3.svg.arc();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var gs = svg.selectAll("g")
.data(dataset)
.enter()
.append("g");
var path = gs.selectAll("path")
.data(function(d) {
return pie(d.children);
})
.enter().append("path")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", function(d, i, j) {
return arc.innerRadius(10 + cwidth * j).outerRadius(cwidth * (j + 1))(d);
});
<script src="https://d3js.org/d3.v3.min.js"></script>

Related

D3 pack: setting same radius for the nodes that include the different number of children

I am trying to make the same radius for all child nodes using d3.pack().
In my experience, the problem is that d3 pack generates the radius according to child nodes count or some other value.
Here is data structure sample.
{
"id": "CoC-home",
"name": "HOME",
"type": "circle",
"value": 1,
"children": [
{
"id": "CT-home-1",
"name": "Sales Systems, Digital & Omnichannel",
"type": "circle",
"value": 1,
"children": [
{
"id": "ET-1-home",
"name": "Omnichannel",
"type": "circle",
"value": 0.25,
"children": [
{
"id": "EG-1-home",
"name": "CRM",
"type": "circle",
"value": 1
},
{
"id": "EG-2-home",
"name": "New Business Models",
"type": "circle",
"value": 1
},
{
"id": "EG-3-home",
"name": "Business Development Stores",
"type": "circle",
"value": 1
},
{
"id": "EG-4-home",
"name": "Business Development Customer & Advisor Service",
"type": "circle",
"value": 1
}
]
},
{
"id": "ET-2-home",
"name": "Business Development Advisor Sales",
"type": "circle",
"value": 0.2,
"children": [
{
"id": "EG-5-home",
"name": "Business Development Advisor Sales Kobold",
"type": "circle",
"value": 1
},
{
"id": "EG-6-home",
"name": "Business Development Advisor Sales Temial",
"type": "circle",
"value": 1
},
{
"id": "EG-7-home",
"name": "Recruitment and Training & Learning",
"type": "circle",
"value": 1
},
{
"id": "EG-8-home",
"name": "Income System",
"type": "circle",
"value": 1
}
]
},
{
"id": "ET-3-home",
"name": "Advisor Solutions",
"type": "circle",
"value": 0.25,
"children": [
{
"id": "EG-9-home",
"name": "Commission Engine",
"type": "circle",
"value": 1
},
{
"id": "EG-10-home",
"name": "Advisor Lifecycle & LMS",
"type": "circle",
"value": 1
},
{
"id": "EG-11-home",
"name": "Solutions Small Countries",
"type": "circle",
"value": 1
}
]
},
{
"id": "ET-4-home",
"name": "Digital",
"type": "circle",
"value": 0.2,
"children": [
{
"id": "EG-12-home",
"name": "eBusiness",
"type": "circle",
"value": 1
},
{
"id": "EG-13-home",
"name": "Cleaning",
"type": "circle",
"value": 1
},
{
"id": "EG-14-home",
"name": "Cookidoo",
"type": "circle",
"value": 1
},
{
"id": "EG-15-home",
"name": "Digital Experience Design",
"type": "circle",
"value": 1
},
{
"id": "EG-16-home",
"name": "Community",
"type": "circle",
"value": 1
},
{
"id": "EG-17-home",
"name": "Big Data & Analytics",
"type": "circle",
"value": 1
},
{
"id": "EG-18-home",
"name": "Insights Engine",
"type": "circle",
"value": 1
},
{
"id": "EG-19-home",
"name": "Digital Marketing & Lead Management",
"type": "circle",
"value": 1
},
{
"id": "EG-20-home",
"name": "Recipe Business",
"type": "circle",
"value": 1
}
]
},
{
"id": "ET-5-home",
"name": "Program Management",
"type": "circle",
"value": 0.2,
"children": [
{
"id": "EG-22-home",
"name": "Program Mgmt. Customer Service",
"type": "circle",
"value": 1
},
{
"id": "EG-23-home",
"name": "TBD",
"type": "circle",
"value": 1
}
]
}
]
},
{
"id": "CT-home-2",
"name": "Marketing",
"type": "circle",
"value": 1,
"children": [
{
"id": "ET-6-home",
"name": "Brand Marketing",
"type": "circle",
"value": 0.25
},
{
"id": "ET-7-home",
"name": "Communication",
"type": "circle",
"value": 0.25
},
{
"id": "ET-8-home",
"name": "Market Research & Insights",
"type": "circle",
"value": 0.25
},
{
"id": "ET-9-home",
"name": "Operative Marketing Coordination",
"type": "circle",
"value": 0.25
}
]
},
{
"id": "CT-home-4",
"name": "Sales",
"type": "circle",
"value": 1,
"children": [
{
"id": "ET-15-home",
"name": "IDB",
"type": "circle",
"value": 1
},
{
"id": "ET-16-home",
"name": "KS/TM Country xxx",
"type": "circle",
"value": 1
},
{
"id": "ET-17-home",
"name": "KS/TM Country xxx",
"type": "circle",
"value": 1
}
]
},
{
"id": "CT-home-5",
"name": "Complementary Product Portfolio",
"type": "circle",
"value": 1
},
{
"id": "CT-home-6",
"name": "Recognition & Events",
"type": "circle",
"value": 1
},
{
"id": "CT-home-7",
"name": "Finance Markets & Business Partnering",
"type": "circle",
"value": 1
},
{
"id": "CT-home-8",
"name": "Operations",
"type": "circle",
"value": 1,
"children": [
{
"id": "ET-20-home",
"name": "Intl. Trade",
"type": "circle",
"value": 1
},
{
"id": "ET-21-home",
"name": "Master Data",
"type": "circle",
"value": 1
},
{
"id": "ET-21-home",
"name": "Purchasing",
"type": "circle",
"value": 1
},
{
"id": "ET-21-home",
"name": "Operational Logistics",
"type": "circle",
"value": 1
},
{
"id": "ET-21-home",
"name": "Performance Management",
"type": "circle",
"value": 1
},
{
"id": "ET-21-home",
"name": "Repair",
"type": "circle",
"value": 1
},
{
"id": "ET-21-home",
"name": "Planning",
"type": "circle",
"value": 1
},
{
"id": "ET-21-home",
"name": "Projects",
"type": "circle",
"value": 1
}
]
}
]
},
There are all 4 levels in the json data and each level node has the different count of children nodes.
If the number of child nodes for each level is same, then its radius is same.
Here's what I'm getting:
h
Here is my code snippet
nodeG.append('g')
.filter(d => d.type === 'circle' | d.type === 'inner-circle')
.each(function (d) {
drawHexagons(
d3.select(this),
d,
{
width: radiusAccessor(d) * 2,
height: radiusAccessor(d) * 2
}
)
})
const radiusAccessor = (d) => {
return d.id === 'exec' ?
50 :
d.type === 'circle' ?
110 :
d.type === 'inner-circle' ?
60 : 50;
}
function drawHexagons(nodeElement, data, options) {
const width = options.width
const height = options.height
const pack = data => d3.pack()
.size([width, height])
.padding(3)
(d3.hierarchy(data)
.sum(d => d.value)
.sort((a, b) => b.value - a.value))
const root = pack(data);
let focus = root;
const node = nodeElement.append("g")
.selectAll("circle")
.data(root.descendants().slice(1))
.join("circle")
.attr("id", d => d.data.id)
.attr("class", d => {
return d.data.groupId
})
.attr("fill", d => (d.data.groupId === "corporate_governance" | d.data.groupId === "communications") ? color(d.depth + 1) : color(d.depth))
.attr("transform", d => `translate(${(d.x - root.x)},${(d.y - root.y)})`)
.attr("r", d => {
return d.r;
})
.style("visibility", d => {
return d.depth > 0 ? "hidden" : "visible"
})
}
I just want to make all child node to take the same radius regardless of its child nodes number.
For clarity: I just want to take the same radius for each level nodes regardless each node has children or not. For example, all node's radius for level 1 is 50, radius for level 2 is 30 and etc.
Do you have any idea?
Thank for your reading.
I just want to take the same radius for each level nodes regardless each node has children or not. For example, all node's radius for level 1 is 50, radius for level 2 is 30 and etc
This cannot be achieved with circle packing. The goal of circle packing is to child circles into the smallest bounding circle. You could make all of one generation have the same size regardless of child count, but to specify each generation/level's won't work.
If parent A has one child of radius r and parent A's sibling, parent, B another has two children of radius r, then naturally, the smallest bounding circle for parent A will not be the same as parent B. For each additional child of fixed radius r, the minimum bounding circle's radius will increase.
Consequently, any circle packing algorithm won't work - you cannot optimally pack a different number of children with the same radius into larger parent circles sharing some larger radius: there will be wasted space in the parent with less children.
I'm not aware of any alternative algorithm to achieve this, using rectangles would likely be the easiest to implement a solution manually - as rectangles are easily stacked making overlap prevention easy. A circular solution without math could be a nested d3-force layout, but could be cumbersome from a code and overhead perspective.

Data Structures in D3

A group project of mine are struggling with a data structure, after having been told that it was initially wrong.
Alcohol consumption is the percentage of those who are on the mental health register in that particular city, so it should be a child element of mental health. To me, this looks right, but is producing no output in d3, only England, North England, Bradford City, Mental Health, and Alcohol Consumption produce an output, but not for Leeds. More data will be added, we just needed to get the structure correct.
var data = {
"name": "England",
"children": [
{
"name": "North England",
"children": [
{
"name": "Bradford City",
"children": [
{
"name": "Mental Health",
"value": 1.22,
"children": [
{
"name": "Alcohol Consumption",
"value": 70.23,
}
]
}
],
"name": "Leeds",
"children": [
{
"name": "Mental Health",
"value": 1.22,
"children": [
{
"name": "Alcohol Consumption",
"value": 70.23,
}
]
}
]
}
]
}
]
};
This is the right structure:
var data = {
"name": "England",
"children": [{
"name": "North England",
"children": [{
"name": "Bradford City",
"children": [{
"name": "Mental Health",
"value": 1.22,
"children": [{
"name": "Alcohol Consumption",
"value": 70.23,
}]
}]
}, {
"name": "Leeds",
"children": [{
"name": "Mental Health",
"value": 1.22,
"children": [{
"name": "Alcohol Consumption",
"value": 70.23,
}]
}]
}]
}]
};
The children for North England should be a list of objects.

Tooltip in multiple ring charts d3js

While trying to use the tooltip for each ring in a multiple ring donut chart using d3js , while hovering on the ring it just shows the values for the first child . Below is the code which shows the rings as well as the tooltip . What would I be doing in order to get all the correct item on hover.How do I iterate through the json to get the correct tooltip.
var dataset = [{
"name": "Population Quater",
"code": "POP_QUATER",
"parent": "POP_BY_QUAT",
"children": [{
"name": "POP_CYQ1",
"code": "POP_CYQ1",
"parent": "POP_QUATER",
"value": "6772",
"label": "CYQ1",
"children": []
}, {
"name": "POP_CYQ2",
"code": "POP_CYQ2",
"parent": "POP_QUATER",
"value": "6716",
"label": "CYQ2",
"children": []
}, {
"name": "POP_CYQ3",
"code": "POP_CYQ3",
"parent": "POP_QUATER",
"value": "6714",
"label": "CYQ3",
"children": []
}, {
"name": "POP_CYQ4",
"code": "POP_CYQ4",
"parent": "POP_QUATER",
"value": "6703",
"label": "CYQ4",
"children": []
}, {
"name": "POP_LYQ1",
"code": "POP_LYQ1",
"parent": "POP_QUATER",
"value": "6721",
"label": "LYQ1",
"children": []
}, {
"name": "POP_LYQ2",
"code": "POP_LYQ2",
"parent": "POP_QUATER",
"value": "6671",
"label": "LYQ2",
"children": []
}, {
"name": "POP_LYQ3",
"code": "POP_LYQ3",
"parent": "POP_QUATER",
"value": "6708",
"label": "LYQ3",
"children": []
}, {
"name": "POP_LYQ4",
"code": "POP_LYQ4",
"parent": "POP_QUATER",
"value": "6734",
"label": "LYQ4",
"children": []
}]
}, {
"name": "Transient Pop",
"code": "TRANSIENT_POP",
"parent": "POP_BY_QUAT",
"label": "Transient Pop",
"children": [{
"name": "TRANSIENT_LYQ1",
"code": "TRANSIENT_LYQ1",
"parent": "TRANSIENT_POP",
"value": "54",
"label": "LYQ1",
"children": []
}, {
"name": "TRANSIENT_LYQ2",
"code": "TRANSIENT_LYQ2",
"parent": "TRANSIENT_POP",
"value": "86",
"label": "LYQ2",
"children": []
}, {
"name": "TRANSIENT_LYQ3",
"code": "TRANSIENT_LYQ3",
"parent": "TRANSIENT_POP",
"value": "219",
"label": "LYQ3",
"children": []
}, {
"name": "TRANSIENT_LYQ4",
"code": "TRANSIENT_LYQ4",
"parent": "TRANSIENT_POP",
"value": "191",
"label": "LYQ4",
"children": []
}, {
"name": "TRANSIENT_CYQ1",
"code": "TRANSIENT_CYQ1",
"parent": "TRANSIENT_POP",
"value": "52",
"label": "CYQ1",
"children": []
}, {
"name": "TRANSIENT_CYQ2",
"code": "TRANSIENT_CYQ2",
"parent": "TRANSIENT_POP",
"value": "91",
"label": "CYQ2",
"children": []
}, {
"name": "TRANSIENT_CYQ3",
"code": "TRANSIENT_CYQ3",
"parent": "TRANSIENT_POP",
"value": "222",
"label": "CYQ3",
"children": []
}, {
"name": "TRANSIENT_CYQ4",
"code": "TRANSIENT_CYQ4",
"parent": "TRANSIENT_POP",
"value": "186",
"label": "CYQ4",
"children": []
}]
}, {
"name": "Seasonal Pop",
"code": "SEASONAL_POP",
"parent": "POP_BY_QUAT",
"label": "Seasonal Pop",
"children": [{
"name": "SEASONAL_LYQ1",
"code": "SEASONAL_LYQ1",
"parent": "SEASONAL_POP",
"value": "2",
"label": "LYQ1",
"children": []
}, {
"name": "SEASONAL_LYQ2",
"code": "SEASONAL_LYQ2",
"parent": "SEASONAL_POP",
"value": "24",
"label": "LYQ2",
"children": []
}, {
"name": "SEASONAL_LYQ3",
"code": "SEASONAL_LYQ3",
"parent": "SEASONAL_POP",
"value": "152",
"label": "LYQ3",
"children": []
}, {
"name": "SEASONAL_LYQ4",
"code": "SEASONAL_LYQ4",
"parent": "SEASONAL_POP",
"value": "55",
"label": "LYQ4",
"children": []
}, {
"name": "SEASONAL_CYQ1",
"code": "SEASONAL_CYQ1",
"parent": "SEASONAL_POP",
"value": "2",
"label": "CYQ1",
"children": []
}, {
"name": "SEASONAL_CYQ2",
"code": "SEASONAL_CYQ2",
"parent": "SEASONAL_POP",
"value": "22",
"label": "CYQ2",
"children": []
}, {
"name": "SEASONAL_CYQ3",
"code": "SEASONAL_CYQ3",
"parent": "SEASONAL_POP",
"value": "161",
"label": "CYQ3",
"children": []
}, {
"name": "SEASONAL_CYQ4",
"code": "SEASONAL_CYQ4",
"parent": "SEASONAL_POP",
"value": "55",
"label": "CYQ4",
"children": []
}]
}];
var width = 460,
height = 300,
cwidth = 25;
var color = d3.scaleOrdinal(d3.schemeCategory20);
var pie = d3.pie()
.sort(null).value(function(d) {
return d.value; //since score is the parameter for the pie
});
var arc = d3.arc();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var gs = svg.selectAll("g")
.data(dataset)
.enter()
.append("g")
.attr("class", "arc").on("mouseover", function() {
tooltip.style("display", null);
})
.on("mouseout", function() {
tooltip.style("display", "none");
})
.on("mousemove", function(d, i) {
tooltip.transition().duration(200)
.style("opacity", 0.9);
tooltip.select("div").html(d.children[i].name + ":" + " <strong>" + d.children[i].value + "</strong>")
.style("position", "fixed")
.style("text-align", "center")
.style("width", "120px")
.style("height", "45px")
.style("padding", "2px")
.style("font", "12px sans-serif")
.style("background", "lightsteelblue")
.style("border", "0px")
.style("border-radius", "8px")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
});
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0.5);
tooltip.append("rect")
.attr("width", 30)
.attr("height", 20)
.attr("fill", "#ffffff")
.style("opacity", 0.5);
tooltip.append("div")
.attr("x", 15)
.attr("dy", "1.2em")
.style("text-anchor", "middle")
.attr("font-size", "1.5em")
.attr("font-weight", "bold");
var path = gs.selectAll("path")
.data(function(d, i) {
return pie(d.children).map(function(payload) {
return {
payload: payload,
parentIndex: i
}
})
})
.enter().append("path")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", function(d, i, j) {
return arc.innerRadius(10 + cwidth * d.parentIndex).outerRadius(cwidth * (d.parentIndex + 1))(d.payload);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>
var dataset = [{
"name": "Population Quater",
"code": "POP_QUATER",
"parent": "POP_BY_QUAT",
"children": [{
"name": "POP_CYQ1",
"code": "POP_CYQ1",
"parent": "POP_QUATER",
"value": "6772",
"label": "CYQ1",
"children": []
}, {
"name": "POP_CYQ2",
"code": "POP_CYQ2",
"parent": "POP_QUATER",
"value": "6716",
"label": "CYQ2",
"children": []
}, {
"name": "POP_CYQ3",
"code": "POP_CYQ3",
"parent": "POP_QUATER",
"value": "6714",
"label": "CYQ3",
"children": []
}, {
"name": "POP_CYQ4",
"code": "POP_CYQ4",
"parent": "POP_QUATER",
"value": "6703",
"label": "CYQ4",
"children": []
}, {
"name": "POP_LYQ1",
"code": "POP_LYQ1",
"parent": "POP_QUATER",
"value": "6721",
"label": "LYQ1",
"children": []
}, {
"name": "POP_LYQ2",
"code": "POP_LYQ2",
"parent": "POP_QUATER",
"value": "6671",
"label": "LYQ2",
"children": []
}, {
"name": "POP_LYQ3",
"code": "POP_LYQ3",
"parent": "POP_QUATER",
"value": "6708",
"label": "LYQ3",
"children": []
}, {
"name": "POP_LYQ4",
"code": "POP_LYQ4",
"parent": "POP_QUATER",
"value": "6734",
"label": "LYQ4",
"children": []
}]
}, {
"name": "Transient Pop",
"code": "TRANSIENT_POP",
"parent": "POP_BY_QUAT",
"label": "Transient Pop",
"children": [{
"name": "TRANSIENT_LYQ1",
"code": "TRANSIENT_LYQ1",
"parent": "TRANSIENT_POP",
"value": "54",
"label": "LYQ1",
"children": []
}, {
"name": "TRANSIENT_LYQ2",
"code": "TRANSIENT_LYQ2",
"parent": "TRANSIENT_POP",
"value": "86",
"label": "LYQ2",
"children": []
}, {
"name": "TRANSIENT_LYQ3",
"code": "TRANSIENT_LYQ3",
"parent": "TRANSIENT_POP",
"value": "219",
"label": "LYQ3",
"children": []
}, {
"name": "TRANSIENT_LYQ4",
"code": "TRANSIENT_LYQ4",
"parent": "TRANSIENT_POP",
"value": "191",
"label": "LYQ4",
"children": []
}, {
"name": "TRANSIENT_CYQ1",
"code": "TRANSIENT_CYQ1",
"parent": "TRANSIENT_POP",
"value": "52",
"label": "CYQ1",
"children": []
}, {
"name": "TRANSIENT_CYQ2",
"code": "TRANSIENT_CYQ2",
"parent": "TRANSIENT_POP",
"value": "91",
"label": "CYQ2",
"children": []
}, {
"name": "TRANSIENT_CYQ3",
"code": "TRANSIENT_CYQ3",
"parent": "TRANSIENT_POP",
"value": "222",
"label": "CYQ3",
"children": []
}, {
"name": "TRANSIENT_CYQ4",
"code": "TRANSIENT_CYQ4",
"parent": "TRANSIENT_POP",
"value": "186",
"label": "CYQ4",
"children": []
}]
}, {
"name": "Seasonal Pop",
"code": "SEASONAL_POP",
"parent": "POP_BY_QUAT",
"label": "Seasonal Pop",
"children": [{
"name": "SEASONAL_LYQ1",
"code": "SEASONAL_LYQ1",
"parent": "SEASONAL_POP",
"value": "2",
"label": "LYQ1",
"children": []
}, {
"name": "SEASONAL_LYQ2",
"code": "SEASONAL_LYQ2",
"parent": "SEASONAL_POP",
"value": "24",
"label": "LYQ2",
"children": []
}, {
"name": "SEASONAL_LYQ3",
"code": "SEASONAL_LYQ3",
"parent": "SEASONAL_POP",
"value": "152",
"label": "LYQ3",
"children": []
}, {
"name": "SEASONAL_LYQ4",
"code": "SEASONAL_LYQ4",
"parent": "SEASONAL_POP",
"value": "55",
"label": "LYQ4",
"children": []
}, {
"name": "SEASONAL_CYQ1",
"code": "SEASONAL_CYQ1",
"parent": "SEASONAL_POP",
"value": "2",
"label": "CYQ1",
"children": []
}, {
"name": "SEASONAL_CYQ2",
"code": "SEASONAL_CYQ2",
"parent": "SEASONAL_POP",
"value": "22",
"label": "CYQ2",
"children": []
}, {
"name": "SEASONAL_CYQ3",
"code": "SEASONAL_CYQ3",
"parent": "SEASONAL_POP",
"value": "161",
"label": "CYQ3",
"children": []
}, {
"name": "SEASONAL_CYQ4",
"code": "SEASONAL_CYQ4",
"parent": "SEASONAL_POP",
"value": "55",
"label": "CYQ4",
"children": []
}]
}];
var width = 460,
height = 300,
cwidth = 25;
var color = d3.scaleOrdinal(d3.schemeCategory20);
var pie = d3.pie()
.sort(null).value(function(d) {
return d.value; //since score is the parameter for the pie
});
var arc = d3.arc();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var gs = svg.selectAll("g")
.data(dataset)
.enter()
.append("g")
.attr("class", "arc").on("mouseover", function() {
tooltip.style("display", null);
});
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0.5);
tooltip.append("rect")
.attr("width", 30)
.attr("height", 20)
.attr("fill", "#ffffff")
.style("opacity", 0.5);
tooltip.append("div")
.attr("x", 15)
.attr("dy", "1.2em")
.style("text-anchor", "middle")
.attr("font-size", "1.5em")
.attr("font-weight", "bold");
var path = gs.selectAll("path")
.data(function(d, i) {
return pie(d.children).map(function(payload) {
return {
payload: payload,
parentIndex: i
}
})
})
.enter().append("path")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", function(d, i, j) {
return arc.innerRadius(10 + cwidth * d.parentIndex).outerRadius(cwidth * (d.parentIndex + 1))(d.payload);
})
.on("mouseout", function() {
tooltip.style("display", "none");
})
.on("mousemove", function(d, i) {
console.log(d)
tooltip.transition().duration(200)
.style("opacity", 0.9);
tooltip.select("div").html(d.payload.data.name + ":" + " <strong>" + d.payload.data.value + "</strong>")
.style("position", "fixed")
.style("text-align", "center")
.style("width", "120px")
.style("height", "45px")
.style("padding", "2px")
.style("font", "12px sans-serif")
.style("background", "lightsteelblue")
.style("border", "0px")
.style("border-radius", "8px")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>
The event handlers were bound to the g tags instead of the path tags :)
try this

REQL to match string expression

I have the following json:
{
"release": {
"genres": {
"genre": "Electronic"
},
"identifiers": {
"identifier": [
{
"description": "Text",
"value": "5 709498 101026",
"type": "Barcode"
},
{
"description": "String",
"value": 5709498101026,
"type": "Barcode"
}
]
},
"status": "Accepted",
"videos": {
"video": [
{
"title": "Future 3 - Renaldo",
"duration": 446,
"description": "Future 3 - Renaldo",
"src": "http://www.youtube.com/watch?v=hpc9aQpnUjc",
"embed": true
},
{
"title": "Future 3 - Silver M from album We are the Future / 1995 Denmark / Archivos de Kraftwerkmusik",
"duration": 461,
"description": "Future 3 - Silver M from album We are the Future / 1995 Denmark / Archivos de Kraftwerkmusik",
"src": "http://www.youtube.com/watch?v=nlcHRI8iV4g",
"embed": true
},
{
"title": "Future 3 - Bubbles At Dawn",
"duration": 710,
"description": "Future 3 - Bubbles At Dawn",
"src": "http://www.youtube.com/watch?v=ABBCyvGMOFw",
"embed": true
}
]
},
"labels": {
"label": {
"catno": "APR 010CD",
"name": "April Records"
}
},
"companies": {
"company": {
"id": 26184,
"catno": "",
"name": "Voices Of Wonder",
"entity_type_name": "Published By",
"resource_url": "http://api.discogs.com/labels/26184",
"entity_type": 21
}
},
"styles": {
"style": [
"Abstract",
"IDM",
"Downtempo"
]
},
"formats": {
"format": {
"text": "",
"name": "CD",
"qty": 1,
"descriptions": {
"description": "Album"
}
}
},
"country": "Denmark",
"id": 5375,
"released": "1995-00-00",
"artists": {
"artist": {
"id": 5139,
"anv": "",
"name": "Future 3",
"role": "",
"tracks": "",
"join": ""
}
},
"title": "We Are The Future 3",
"master_id": 638422,
"tracklist": {
"track": [
{
"position": 1,
"duration": "8:04",
"title": "Future 3"
},
{
"position": 2,
"duration": "7:38",
"title": "Silver M"
},
{
"position": 3,
"duration": "7:27",
"title": "Renaldo"
},
{
"position": 4,
"duration": "6:04",
"title": "B.O.Y.D."
},
{
"position": 5,
"duration": "6:12",
"title": "Fumble"
},
{
"position": 6,
"duration": "6:12",
"title": "Dawn"
},
{
"position": 7,
"duration": "11:54",
"title": "Bubbles At Dawn"
},
{
"position": 8,
"duration": "6:03",
"title": "D.A.W.N. At 6"
},
{
"position": 9,
"duration": "8:50",
"title": 4684351684651
}
]
},
"data_quality": "Needs Vote",
"extraartists": {
"artist": [
{
"id": 2647642,
"anv": "",
"name": "Danesadwork",
"role": "Cover",
"tracks": "",
"join": ""
},
{
"id": 2647647,
"anv": "",
"name": "Djon Edvard Petersen",
"role": "Photography By",
"tracks": "",
"join": ""
},
{
"id": 114164,
"anv": "",
"name": "Anders Remmer",
"role": "Written-By",
"tracks": "",
"join": ""
},
{
"id": 435979,
"anv": "",
"name": "Jesper Skaaning",
"role": "Written-By",
"tracks": "",
"join": ""
},
{
"id": 15691,
"anv": "",
"name": "Thomas Knak",
"role": "Written-By",
"tracks": "",
"join": ""
}
]
},
"notes": "© 1995 April Records APS ℗ 1995 April Records APS"
}
}
I am trying to get those titles which end with 'At Dawn'.
I am using the following command
r.db("discogs1").table("releases").filter(function(doc){ return doc('release')('title').match('At Dawn$')})
But I get errors as follows:
RqlRuntimeError: Expected type STRING but found NUMBER in:r.db("discogs1").table("releases").filter(function(var_24) { return var_24("release")("title").match("At Dawn$"); })
I tried different combinations but I can't seem to get it to work
It seems that some of your documents don't have a row('release')('title') property that is a string. Some of them are numbers, so when you try to call .match on them, they throw an error because .match only works on strings.
To see if this is true, try the following:
r.db("discogs1").table("releases")
.filter(r.row('release')('title').typeOf().ne('STRING'))
.count()
Ideally, the result of this should be 0, since no document should have a title property that's not a string. If it's higher than 0, that's why you're getting an error.
If you want to only get documents where the title is a string, you can do the following:
r.db("discogs1").table("releases")
.filter(r.row('release')('title').typeOf().eq('STRING'))
.filter(function(doc){ return doc('release')('title').match('At Dawn$')})
This query will work, because it will filter our all documents where the title is not a string.
If you want to coerce all title into strings, you can do the following:
r.db("discogs1").table("releases")
.filter(r.row('release')('title').typeOf().ne('STRING'))
.merge(function (row) {
return {
'title': row('title').coerceTo('string')
}
})
If you want to delete all documents where the title is not a string, you can do this:
r.db("discogs1").table("releases")
.filter(r.row('release')('title').typeOf().ne('STRING'))
.delete()

Count Repeated Values in Json String and store value and label in another String

I need to count the number of repeating items in the json array , and show the repeating items as single item and count should be shown how many tiems it has repeated..
please check the below code and Output so that you can understand:
[{
"Name": "Jacob",
"Gender": "Male",
"City": "Newyork",
"State": "Newyork"
}, {
"Name": "Mason",
"Gender": "Male",
"City": "Los Angeles",
"State": "California"
}, {
"Name": "Ethan",
"Gender": "Male",
"City": "Chicago",
"State": "Illinois"
}, {
"Name": "Noah",
"Gender": "Male",
"City": "Newyork",
"State": "NewYork"
}, {
"Name": "Sophia",
"Gender": "Female",
"City": "Los Angeles",
"State": "California"
}, {
"Name": "Emma",
"Gender": "Female",
"City": "Los Angeles",
"State": "California"
}, {
"Name": "Isabella",
"Gender": "Female",
"City": "Chicago",
"State": "Illinois"
}, {
"Name": "Olivia",
"Gender": "Female",
"City": "Chicago",
"State": "Illinois"
}, {
"Name": "Elizabeth",
"Gender": "Female",
"City": "Newyork",
"State": "Newyork"
}, {
"Name": "zoey",
"Gender": "Female",
"City": "Newyork",
"State": "Newyork"
}]
The desired output from json is
Newyork : 4Times,
chicago:3 times,
Please find the fiddle :
http://jsfiddle.net/vamsikrishna981/dMrNv/
Try this http://jsfiddle.net/RHYFC/
See LONG VERSION and SHORT VERSION on fiddle
Javascript
var result = {};
for(var i = 0; i < data.length; i++){
for(var item in data[i]){
if(!result[item]){
result[item] = {};
}
if(!result[item][data[i][item]]){
result[item][data[i][item]] = 0;
}
result[item][data[i][item]]++;
}
}

Resources