I am trying to merge several arrays into a single object that I can then iterate to use in chart.js datasets. I have a set of data that looks like this:
export const data = [
{
'name': 'Flow',
'values': {
'sent': 410,
'responded': 253,
'secured': 65
}
}
]
(I limited this to just one, but the dataset is much larger)
Then I have several arrays that I've built based on this data:
this.labels = data.map(item => item.name);
this.colors = ['#439ff4', '#5ec3d5', '#a068e5'];
this.responded = data.map(item => item.values.responded);
this.sent = data.map(item => item.values.sent);
this.secured = data.map(item => item.values.secured);
What I need to do is this:
get the key names (responded, sent, secured) as another array
merge the keys, colors, responded, sent, and secured, arrays into an object called datasets.
this.datasets = [ /* not sure what to do here! */];
Ultimately my chart in chart js is looking for something like this (I have partially hard-coded values at the moment:
datasets: [
{
label: 'Sent',
data: this.sent,
backgroundColor: '#439ff4'
},
{
label: 'Responded',
data: this.responded,
backgroundColor: '#5ec3d5'
},
{
label: 'Secured',
data: this.secured,
backgroundColor: '#a068e5'
}
],
that I would ultimately like to just express as
datasets: this.datasets,
I hope I explained this well enough as to what I am trying to do.
Assuming that the key names in data.values stays in lowercase and otherwise it is same as datasets[*].label, you can do something like below.
// the custom type is just for making it more manageable, omit it if you want
type DatasetItem = { label: string, data: number[], backgroundColor: string };
let datasets: Array<Partial<DatasetItem>> = [
{
label: 'Sent',
backgroundColor: '#439ff4'
},
{
label: 'Responded',
backgroundColor: '#5ec3d5'
},
{
label: 'Secured',
backgroundColor: '#a068e5'
}
];
const data = [
{
'name': 'Flow1',
'values': {
'sent': 410,
'responded': 253,
'secured': 65
}
},
{
'name': 'Flow2',
'values': {
'sent': 411,
'responded': 254,
'secured': 66
}
}
];
datasets.forEach((item) => item.data = data.map((d) => d.values[item.label.toLowerCase()]));
console.log(datasets);
Related
I have two Arrayes that has been sourced from two different URIs. I am trying to create a form of code that extracts specific data from one Array and connects it to related data from the other Array. Here's an example:
let coursesData = ['teachers': 'CHCH'];
let teacherData = [
{
'id': {'name': 'CHCH'},
'name':{
'jobtitle': 'Professor',
'firt':'Charie',
'last': Chaplin
},
}];
function renderCourseTeachersList () {
teacherData
.filter(object => {
return object.id.includes(parseInt(coursesData.teachers));
})
.forEach((item, i) => {
console.log(`Lärare: ${item.name.jobtitle} ${item.name.first} ${item.name.last}`);
});
}
I was hoping this would give me a list of the values: jobtitle, first and last in the console log, in order of the matching value: CHCH.
The two arrays are just snippets of a larger source.
Thank you in advance!
As you put a snippet of your source data, I guess coursesData is an array of objects. So I defined multiple objects in coursesData. If your structure is different, Snippet will provide you idea to get the expected result.
let coursesData = [
{
'teachers': 'CHCH'
},
{
'teachers': 'xyz'
},
];
let teacherData = [
{
'id': {
'name': 'CHCH'
},
'name': {
'jobtitle': 'Professor',
'first': 'Charie',
'last': 'Chaplin',
},
},
{
'id': {
'name': 'xyz'
},
'name': {
'jobtitle': 'Lecturer',
'first': 'John',
'last': 'Doe',
},
}
];
function renderCourseTeachersList (){
teacherData.filter(object => coursesData.some(subItem => subItem.teachers == object.id.name))
.forEach((item, i) => {
console.log(`Lärare: ${item.name.jobtitle} ${item.name.first} ${item.name.last}`);
});
}
renderCourseTeachersList();
I am pulling data from an API that looks like this:
[{
id: "62ff4289163f2d1ec1d54ff16bd8d731",
sport_key: "americanfootball_ncaaf",
commence_time: "2021-08-28T17:00:00Z",
home_team: "Illinois Fighting Illini",
away_team: "Nebraska Cornhuskers",
bookmakers: [{
key: "unibet",
title: "Unibet",
last_update: "2021-07-16T23:33:36Z",
markets: [{
key: "spreads",
outcomes: [{
name: "Illinois Fighting Illini",
price: 1.89,
point: 8
},
{
name: "Nebraska Cornhuskers",
price: 1.89,
point: -8
}
]
}]
},
{
key: "barstool",
title: "Barstool Sportsbook",
last_update: "2021-07-16T23:28:36Z",
markets: [{
key: "spreads",
outcomes: [{
name: "Illinois Fighting Illini",
price: 1.91,
point: 8
},
{
name: "Nebraska Cornhuskers",
price: 1.91,
point: -8
}
]
}]
}
]
The relevant section of my code looks like this (the (data) is the JSON posted above):
response.on("end", () => {
const oddsData = JSON.parse(data);
let games = oddsData.length;
for(let i=0; i<games; i++){
let bookies = oddsData[i].bookmakers.length;
for(let b=0; b<bookies; b++){
console.log(oddsData[i].bookmakers[b]);
}
}
})
How can I filter to only show results for the bookmaker with the key "barstool"? I have been googling different array filters and reduce functions all week and I cannot get this figured out. Any help is appreciated.
As I can see you have an array which is containing first level objects and inside the first level objects you have bookmakers array which is an array of objects.
if you are looking to filter the bookmarks array, which is what I think what you should be looking for
dataArr.forEach(item => {
item.bookmakers = item.bookmakers.filter(bookmaker => bookmaker.key == "barstool")
})
if you are looking to filter the array containing first level objects, you can do something like below
dataArr = dataArr.filter(item => {
let keep = false;
item.bookmakers.forEach(bookmaker => {
if(bookmaker.key == "barstool"){
keep = true;
}
})
return keep;
})
I would guess something like that:
gamesWithBarstool = oddsData.filter(game => game.bookmakers.some(bookmaker => bookmaker.key === 'barstool'))
With that you should only get the list of games that have odds for your named bookmaker.
filter:
Will return the subset of the array that matches the test.
some:
Will return true if any item in the array matches the test.
I have a simple JS "enum" like this
const MyEnum = {
Aaa: 1,
Bbb: 84,
};
And I have a simple story:
import MyEnum from 'models/my-enum';
import HotSpot from 'hot-spot/hot-spot.vue';
import hotSpotProp from './hot-spot.stories.defaults';
export default {
title: 'components/catalog/images/HotSpot',
args: {
hotspotProp: hotSpotProp,
currentWidth: 360,
selectedCallouts: [],
calloutMode: true,
originalWidth: 2100,
title: 'Example tooltip',
},
argTypes: {
oemId: {
options: Object.keys(MyEnum), // an array of serializable values
mapping: MyEnum, // maps serializable option values to complex arg values
control: {
type: 'select', // type 'select' is automatically inferred when 'options' is defined
// labels: MyEnum,
},
},
},
};
const Template = (args, { argTypes }) => ({
components: { HotSpot },
template: `<HotSpot v-bind="$props" />`,
props: Object.keys(argTypes),
});
export const Default = Template.bind({});
Example from docs is not working.
I have a select dropdown working, but it returns a String instead of a Number from mapping.
I get an error in my storybook in the console:
[Vue warn]: Invalid prop: type check failed for prop "oemId". Expected Number with value NaN, got String with value "Aaa".
How to map enum to select dropdown in Storybook?
That storybook doc example is absolute horror.
Here's an example that will instantly show you what to do.
myValueList: {
options: [0, 1, 2], // iterator
mapping: [12, 13, 14], // values
control: {
type: 'select',
labels: ['twelve', 'thirteen', 'fourteen'],
},
}
Enums end up as Objects, so:
enum Nums {
Zero,
One,
Two,
Three,
}
Seems to become an Object that looks like:
{
0: "Zero",
1: "One",
2: "Two",
3: "Three",
One: 1,
Three: 3,
Two: 2,
Zero: 0,
}
Since all object keys are strings or symbols in JavaScript, the only way I've been able to guarantee I only get the string values from an Enum is to use Object.values and filter strings:
oemId: {
options: Object.values(MyEnum).filter(x => typeof x === "string"),
mapping: MyEnum,
control: {
type: 'select',
},
},
Or, filter out the keys and retain an Object - this way Storybook can still default the value without issues:
options: Object.entries(MyEnum)
.filter(([, value]) => typeof value !== "string")
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
You are looking for Object.values not the .keys.
const MyEnum = {
Aaa: 1,
Bbb: 84,
};
Object.values(MyEnum); // -> [ 1, 84 ]
Object.keys(MyEnum); // -> [ "Aaa", "Bbb" ]
"Easy" (with this little helper):
function enumOptions(someEnum) {
return {
options: Object.keys(someEnum)
.filter((key) => !isNaN(parseInt(key)))
.map((key) => parseInt(key)),
mapping: someEnum,
control: {
type: 'select',
labels: Object.values(someEnum).filter(
(value) => typeof value === 'string'
),
},
}
}
This can the be used in the OP's example code as follows:
export default {
title: 'components/catalog/images/HotSpot',
args: {
oemId: MyEnum.MyValue // default value for all stories can be used,
// here "MyValue" will be preselected in dropdown
// (or individual `story.args` oemId value from MyEnum)
},
argTypes: {
oemId: enumOptions(MyEnum)
},
};
It is indeed surprising that this is not an out-of-the-box feature in storybook, requiring such a rather contrived workaround.
Thanks to #Anthony's and #Lee Chase's answers pointing in the right direction.
The easiest way without any helper for me was:
export default {
title: 'One/SingleBarItem',
component: SingleBarItem,
// 👇 Creates drowdown to select Phase enum values
argTypes: {
phase: {
options: Object.values(NodeExecutionPhase),
mapping: Object.values(NodeExecutionPhase),
control: {
type: 'select',
labels: Object.keys(NodeExecutionPhase),
},
},
},
} as ComponentMeta<typeof SingleBarItem>;
Where NodeExecutionPhase defined as:
enum Phase {
UNDEFINED = 0,
QUEUED = 1,
}
I have given up on mapping for now and use a computed value, it pollutes the template a bit but a utility function or two can make it look a little tidier.
argTypes: {
myValueList: {
options: [0, 1, 2], // iterator
control: {
type: 'select',
labels: ['twelve', 'thirteen', 'fourteen'],
},
}
}
// .
// .
// .
const mappingMyValueList = [12, 13, 14];
// .
// .
// .
computed() {
computedMyValueList() {
return () => mappingMyValueList[this.$props.myValueList];
}
}
// .
// .
// .
<div>{{computedMyValueList}}</div>
i'm new to vuejs and i am not getting how to insert data and label from API data into data set and label to display multi line chart,
i have given data model below that's my API output data.
I searched on the internet and I have tried so many ways and I didn't find the solution. Here goes my codes:..................................................................................................................................................
<script>
data() {
return {
labels: [ ],
result:'',
datasets: [
{
label: "Data One",
data: [ ]
},
{
label: "Data Two",
data: [ ]
}
]
};
},
methods: {
updateChart() {
var self=this;
axios
.get("http://localhost:5000/api/" )
.then(res => {
// proccess the response
// this.datasets[0].data = res.data[0];
// self.result = res.data;
// console.log(self.result )
this.renderChart(
{
labels: [],
datasets: this.datasets
},
{ responsive: true, maintainAspectRatio: false }
);
})
.catch(function(error) {
console.log("Error:", error);
});
}
}
</script>
//below is my api data
[
[
"2014-01-01",
"2014-01-01",
"2014-01-02",
"2014-01-03",
"2014-01-04"
],
[
10002200,
10379971,
10123749,
10712250,
13923904
],
[
14412854,
12412854,
14415554,
12415554,
16412854
]
]
You can do the following given your API response:
axios
.get("http://localhost:5000/api/" )
.then(res => {
//labels are the first element in the array
this.labels = res.data[0]
//remove the first element from the array so we don't pollute our datasets
res.data.shift()
//destructure the array and reduce it
this.datasets = [...res.data].reduce((carry, arr) => {
//push our dataset object into the carry
carry.push({
label: '',
data: arr
})
return carry
},[])
//build the chart
this.renderChart({
labels: this.labels,
datasets: this.datasets
})
})
I've annotated the above code for clarity. I don't see any way to give you the label for the individual datasets, though.
I am using highchart to create a graph. I have a javsascript object like this
test1:38
test2:2
test3:160
I want to create a piechart with the values of this object something like this
series: [{
name: 'Success',
data: [
{name:"test1", y:1},
{name:"test2", y:38},
{name:"test3", y:k},]
}]
How can I create the data array like this using my javascript object.I am new to javascript so any help would be appreciated.
You could map the entries of the object to get the data array
const input = {
test1: 38,
test2: 2,
test3: 160
}
const data = Object.entries(input)
.map(([name, y]) => ({ name, y }))
console.log(data)
const chart = {
series: [{
name: 'Success',
data
}]
}
console.log(chart)