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

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
]
};

Related

Attach correct data format to draw a chart

I'm new to Vuejs, vue-Chartkick, and Chartjs. I was trying to insert the restructured data into an object to draw a multiple-series chart. But it did not work.
<template>
<line-chart :data="data"></line-chart>
</template>
<script>
import axios from "axios";
export default {
name: 'SummaryGraph',
data () {
return {
data: [
{name: 'A', data: {}},
{name: 'B', data: {}}
]
}
},
created() {
let apiURL_1 = axios.get('http://localhost:3000/MyfirstData');
let apiURL_2 = axios.get('http://localhost:3000/MysecondData');
axios.all([apiURL_1, apiURL_2]).then(axios.spread((first_response, second_response) => {
this.data[0]['data'] = first_response.data.reduce(function(result, current) {return Object.assign(result, current);}, {});
this.data[1]['data'] = second_response.data.reduce(function(result, current) {return Object.assign(result, current);}, {});
})).catch(error => {
console.log(error)
});
}
}
</script>
The 1st original returned data:
[{"A":6},{"B":6},{"C":4}]
The 2nd original returned data:
[{"A":1},{"B":2},{"C":2}]
The 1st data after restructured by using reduce method.
{"A": 6,"B": 6,"C": 4}
The 2nd data after restructured by using reduce method.
{"A": 1,"B": 2,"C": 2}
If I directly insert the 1st and 2nd restructured data into the Vue instance
Like this:
<script>
export default {
name: 'SummaryGraph',
data () {
return {
data: [
{name: 'A', data: {"A": 6,"B": 6,"C": 4}},
{name: 'B', data: {"A": 1,"B": 2,"C": 2}}
]
}
}
}
</script>
It worked. The graph showed up. I don't know why.

Custom label on d3plus-react Treemap

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

Insert list data over the iteration(map)

Here I am trying to modify my data over the iteration and send some result to API call.
The API Call receives a request with a structured data format which is
{ list: [{ id: "1", name: "Hello" }, ... ] }
Somehow I managed to call the API with single data ( const params in my current code, it only accepts single data).
But now it has to be done with multiple data something like this:
{ list: [{ id: "1", name: "Hello" }, { id: "22", name: "Ed" }, { id: "36", name: "Jason" } ... ] }
Here is my current code
const [table, setTalbe] = useState(..); // assume, we have some table data here
const processNow = () => {
let id = 0;
let name = '';
// if table length is greater than 1, we go for the loop.
if (table.length >= 1) {
table.map(data => {
id = data.userId;
name = data.userName;
});
//insert table data to params, here I want to add whole table data into "list"
//the final result of this list should be something like this
//ex ) list: [{ id: '123', name: 'Josh' }, { id: '125', name: 'Sue' }, { id: '2222', name: 'Paker' } ...],
// but how??
const params: any = {
list: [
{
id: id,
name: name
},
],
};
//send PUT reqeust with params
axios
.put(
'/api/v1/tosent',
params,
)
.then(res => {
console.log('The response', res);
})
.catch(err => {
console.log('The error: ', err);
});
}
};
but I'm stuck with it, please help me to finish this code to work properly.
need your kind advice.
Array.prototype.map returns a new array with the function you pass applied to every element. You should study the MDN documentation on map to understand its use.
Your current code does nothing with the map return value:
table.map(data => {
id = data.userId;
name = data.userName;
});
You probably assumed .map would mutate the data, as in change it in place. Instead, the whole operation returns a new array.
It looks like you want to do:
const list = table.map(data => {
return {
id: data.userId,
name: data.userName
}
});
This is applying a function to every element in the array that will map each element to a new object, matching your question, with an id and name key. Then it looks like you want to pass the returned value of map (which we named list above) to your call:
const params: any = {
list: list
};

Mongodb - Create entry to a extisting collection field array

So I have a problem with my var array to add a new chapter, how would I go about this would I have to do this:
array.push({
chapter: [
{
id: 2,
title: 'adsf',
content: '',
authorNotes: 'asdf'
}
]
});
RiTest.ts
import * as mongoose from 'mongoose';
const Scheme = mongoose.Schema;
export const RiTestScheme = new Scheme({
novelName: String,
novelAuthor: String,
novelCoverArt: String,
novelTags: Array,
chapters: [
{
id: Number,
title: String,
content: String,
authorNotes: String
}
]
});
export class RiTestController {
public addChapter(callback: (data) => void) {
var chapterInfoModel = mongoose.model('ChaptersTest', RiTestScheme);
var array = [
{
chapter: [
{
id: 0,
title: 'prolog',
content: 'conetntt is empty',
authorNotes: 'nothing is said by author'
},
{
id: 1,
title: 'making a sword',
content: 'mine craft end chapter',
authorNotes: 'nothing'
}
]
}
];
let newChapterInfo = new chapterInfoModel(array);
newChapterInfo.save((err, book) => {
if (err) {
return callback(err);
} else if (!err) {
return callback(book);
}
});
}
}
This doesn't work, var array doesn't get saved into let newChapterInfo = new chapterInfoModel(array); what I am trying to do add another chapter to array.chapter but the array doesn't get recognized in the chapterInfoModel() how would I fix this array and add an item to the array to create a new entry into this existing collection
thank for taking your time to answer my question.
You are trying to insert array of document to your collections, That the reason its not inserting into your collection.
Document.prototype.save() will insert only one document to your collection depends on your definition. So to insert chapter here is the code below,
//array as Object
var array = {
chapter: [
{
id: 0,
title: 'prolog',
content: 'conetntt is empty',
authorNotes: 'nothing is said by author'
},
{
id: 1,
title: 'making a sword',
content: 'mine craft end chapter',
authorNotes: 'nothing'
}
]
};
//Push to your chapter array
array.chapter.push({
id: 2,
title: 'adsf',
content: '',
authorNotes: 'asdf'
});
let newChapterInfo = new chapterInfoModel(array);

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