Custom label on d3plus-react Treemap - reactjs

I have to customize the label of a d3plus-react series, the customization will be pretty close to the original one with the label and the percentage but instead of taking the name from the id as the original does I will take it from another field of the object (name).
The object has this structure:
id: string
name: string
value: number
parent: string
and that's my Treemap config:
const methods = {
data: propsData,
groupBy: ['parent', 'id'],
size: 'value',
tooltipConfig: {
title: (d) => `${d.parent} - <span>${d.name}</span>`,
},
legend: true,
shapeConfig: {
label: (d) => {
console.log(d);
return [d.name];
},
},
};
The problem is that I don't know how to modify the label of the tile without touching the shared percentage, I've searched through the docs but I haven't found nothing relevant.
Does anyone know if there are some official methods for doing this or I'll have to do it myself?
Desired result

I've found out that you have access also to the percentage, the code will be as following
const methods = {
data: propsData,
groupBy: ['parent', 'id'],
size: 'value',
tooltipConfig: {
title: (d) => `${d.parent} - <span>${d.name}</span>`,
},
legend: true,
shapeConfig: {
label: (d) => {
return [d.customProperty, d.percentage];
},
},
}
Instead of the name I've used a custom property previously added to the data object so the series have the desired name

Related

update one element of array inside object and return immutable state - redux [duplicate]

In React's this.state I have a property called formErrors containing the following dynamic array of objects.
[
{fieldName: 'title', valid: false},
{fieldName: 'description', valid: true},
{fieldName: 'cityId', valid: false},
{fieldName: 'hostDescription', valid: false},
]
Let's say I would need to update state's object having the fieldName cityId to the valid value of true.
What's the easiest or most common way to solve this?
I'm OK to use any of the libraries immutability-helper, immutable-js etc or ES6. I've tried and googled this for over 4 hours, and still cannot wrap my head around it. Would be extremely grateful for some help.
You can use map to iterate the data and check for the fieldName, if fieldName is cityId then you need to change the value and return a new object otherwise just return the same object.
Write it like this:
var data = [
{fieldName: 'title', valid: false},
{fieldName: 'description', valid: true},
{fieldName: 'cityId', valid: false},
{fieldName: 'hostDescription', valid: false},
]
var newData = data.map(el => {
if(el.fieldName == 'cityId')
return Object.assign({}, el, {valid:true})
return el
});
this.setState({ data: newData });
Here is a sample example - ES6
The left is the code, and the right is the output
Here is the code below
const data = [
{ fieldName: 'title', valid: false },
{ fieldName: 'description', valid: true },
{ fieldName: 'cityId', valid: false }, // old data
{ fieldName: 'hostDescription', valid: false },
]
const newData = data.map(obj => {
if(obj.fieldName === 'cityId') // check if fieldName equals to cityId
return {
...obj,
valid: true,
description: 'You can also add more values here' // Example of data extra fields
}
return obj
});
const result = { data: newData };
console.log(result);
this.setState({ data: newData });
Hope this helps,
Happy Coding!
How about immutability-helper? Works very well. You're looking for the $merge command I think.
#FellowStranger: I have one (and only one) section of my redux state that is an array of objects. I use the index in the reducer to update the correct entry:
case EMIT_DATA_TYPE_SELECT_CHANGE:
return state.map( (sigmap, index) => {
if ( index !== action.payload.index ) {
return sigmap;
} else {
return update(sigmap, {$merge: {
data_type: action.payload.value
}})
}
})
Frankly, this is kind of greasy, and I intend to change that part of my state object, but it does work... It doesn't sound like you're using redux but the tactic should be similar.
Instead of storing your values in an array, I strongly suggest using an object instead so you can easily specify which element you want to update. In the example below the key is the fieldName but it can be any unique identifier:
var fields = {
title: {
valid: false
},
description: {
valid: true
}
}
then you can use immutability-helper's update function:
var newFields = update(fields, {title: {valid: {$set: true}}})

How to mapping variable data for pie chart (react.js)

I want make pie chart using state value in react with '#toast-ui/react-chart'.
I tried this and that after looking at the examples, but it's hard to me.
This is a example.
//chart data
var data = {
categories: ['June, 2015'],
series: [
{
name: 'Budget',
data: [5000]
},
{
name: 'Income',
data: [8000]
},
{
name: 'Expenses',
data: [4000]
},
{
name: 'Debt',
data: [6000]
}
]
};
var options = {
chart: {
width: 660,
height: 560,
title: 'Today's Channel & Value.'
}
tooltip: {
suffix: 'value'
}
},
};
var theme = {
series: {
colors: [
'#83b14e', '#458a3f', '#295ba0', '#2a4175', '#289399',
'#289399', '#617178', '#8a9a9a', '#516f7d', '#dddddd'
]
}
};
//render part
render()
{
return(
<div>
<PieChart
data={data}
options={options}
/>
</div>
}
and document is here.
https://github.com/nhn/toast-ui.react-chart#props
https://nhn.github.io/tui.chart/latest/tutorial-example07-01-pie-chart-basic
What's in the document is how to make a chart with a fixed number, but I want to change it using the state.
So, How can I mapping series data like this and how to add data length flexible?
I have list of object like ...
this.state.list =[{"channel_name":"A","channel_number":17,"VALUE":3,"num":1},
{"channel_name":"B","channel_number":23,"VALUE":1,"num":2},
{"channel_name":"C","channel_number":20,"VALUE":1,"num":3},
{"channel_name":"D","channel_number":1,"VALUE":1,"num":4}]
The length of the list is between 1 and 7 depending on the results of the query.
I want to do like this.
series:[
{
name: this.state.list[0].channel_name+this.state.list[0].channel_num
data: this.state.list[0].VALUE
},
{
name: this.state.list[1].channel_name+this.state.list[1].channel_num
data: this.state.list[1].VALUE
},
{
name: this.state.list[2].channel_name+this.state.list[2].channel_num
data: this.state.list[2].VALUE
},
{
name: this.state.list[3].channel_name+this.state.list[3].channel_num
data: this.state.list[3].VALUE
}
]
How can I implement it however I want?
Since this.state.list is a list of objects, so you can simply use map method to loop through each object https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map. Then create new object with custom value.
let new_series = [];
this.state.list.map((obj) => {
let info = {
name: obj.channel_name + obj.channel_number, //from your code
data: obj.VALUE //from your code
}
new_series.push(info)
});
Then assign new list to your chart.
//chart data
var data = {
categories: ['June, 2015'],
series: new_series
]
};

Format formly form field

I want to format a field when the data finally updates the model. The number usually comes back with a decimal point so what I want to be able to do is format it to no decimal point number (parseNumber function does that).
e.g. vm.model.total = 34.54
I want to format this number to 34 on the fly.
I can't make it work...
vm.fields = [
{
className: 'row',
fieldGroup: [
{
className: 'col-xs-12',
key: 'total',
type: 'input',
templateOptions: {
wrapperClass: 'row',
labelClass: 'col-xs-9 col-sm-3',
dataClass: 'col-xs-3 col-sm-2 col-sm-offset-right-7',
label: 'Total',
disabled: true
},
formatters: [parseNumber(vm.model.total, 0)]
}
]
}
];
Your example does not match the examples in the documentation
Your argument to formatters field is incorrect. That field is expecting a function, NOT THE RESULT of the function, which is what you have defined here.
You should either use an anonymous function or a named function:
formatters: [function(value){ return parseNumber(value, 0); }]
or
formatters: [removeDecimal]
//...
function removeDecimal(value) {
return parseNumber(value, 0)
}
This is a working example from their own documentation which I have added a formatter to the first name field: https://jsbin.com/hapuyefico/1/edit?html,js,output

How can I access all elements with a particular attribute in graphQL?

I have some json data in file called countryData.json structured as so:
{
"info":"success",
"stats":
[{
"id":"1",
"name":"USA",
"type":"WEST"
},
//...
I'm using graphQL to access this data. I have created an object type in the schema for countries using the following:
const CountryType = new GraphQLObjectType({
name: "Country",
fields: () => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
type: { type: GraphQLString },
})
});
I want to write a query that will allow me to access all of the elements of this array that have a certain "name" value(There can be multiple with the same name). I've written the following query, but it only returns the first match in the array:
const RootQuery = new GraphQLObjectType({
name:"RootQueryType",
fields:{
country: {
type: CountryType,
args: { type: { name: GraphQLString } },
resolve(parent, args){
return _.find(countryData.stats, {name: args.name});
}
}
}
});
The "_" comes from const _ = require('lodash');
Also, how can I just get every single item in the array?
I have not recreated the code, therefore I can not check if it would be executed correctly. This is code, that should work in my opinion (without trying). If you want to return array of elements you need to implement https://lodash.com/docs/#filter. Filter will return all objects from stats, which match the argument name. This will return correctly inside resolver function, however, your schema needs adjustments to be able to return array of countries.
You need probably rewrite the arguments as follows as this is probably not correct. You can check out how queries or mutation arguments can be defined https://github.com/atherosai/express-graphql-demo/blob/feature/2-json-as-an-argument-for-graphql-mutations-and-queries/server/graphql/users/userMutations.js. I would rewrite it as follows to have argument "name"
args: { name: { type: GraphQLString } }
You need to add GraphQLList modifier, which defines, that you want to return array of CountryTypes from this query. The correct code should look something like this
const RootQuery = new GraphQLObjectType({
name:"RootQueryType",
fields:{
country: {
type: CountryType,
args: { name: { type: GraphQLString } },
resolve(parent, args){
return _.find(countryData.stats, {name: args.name});
}
},
countries: {
type: new GraphQLList(CountryType),
args: { name: { type: GraphQLString } },
resolve(parent, args){
return _.filter(countryData.stats, {name: args.name});
}
}
}
});
Now if you call query countries, you should be able to retrieve what you are expecting. I hope that it helps. If you need some further explanation, I made the article on implementing lists/arrays in GraphQL schema as I saw that many people struggle with similar issues. You can check it out here https://graphqlmastery.com/blog/graphql-list-how-to-use-arrays-in-graphql-schema
Edit: As for the question "how to retrieve every object". You can modify the code in resolver function in a way, that if the name argument is not specified you would not filter countries at all. This way you can have both cases in single query "countries".

How can I Add and Delete nested Object in array in Angularjs

heres my output Image html How can I delete Object in array and push when adding some Data
angular.module('myApp.Tree_Service', [])
.factory('TreeService', function() {
var svc = {};
var treeDirectories = [
{
name: 'Project1',
id: "1",
type: 'folder',
collapse: true,
children: [
{
name: 'CSS',
id: "1-1",
type: 'folder',
collapse: false,
children: [
{
name: 'style1.css',
id: "1-1-1",
type: 'file'
},
{
name: 'style2.css',
id: "1-1-2",
type: 'file'
}
]
}
]
}
];
svc.add = function () {}
svc.delete = function (item, index) { }
svc.getItem = function () { return treeDirectories; }
return svc;
});
})();
I'm Newbee in Angularjs and I don't know how much to play it.
Hopefully someone can help me. Im Stucked.
Well you can delete any object by just usingdelete Objname.property
So for example you want to delete Children in treeDirectories first index object you can use delete treeDirectories[0].children if you want to delete children inside children then delete treeDirectories[0].children[0].children
if you want to remove an index from an array in lowest level children then
treeDirectories[0].children[0].children.splice(index,1)
for pushing data is for object you can directly assign value to the property you want
treeDirectories[0].children[0].newproperty = "check"
And for array you can
treeDirectories[0].children[0].children.push(object)

Resources