Im trying to create a vega chart in an ember octane app but in doing so im able to render the chart once, but from then on, even if the values change, the chart doesn't get rerendered
the code im using is
component.ts
#tracked
model!: any;
get chartData() {
const data = this.model.data;
return {
table: data.map((datum: any) => {
return {
...datum
};
})
};
}
chart.hbs
{{vega-vis spec=this.spec data=this.chartData}}
why isn't it not working, but at the same time
doing set(this,"dataSource",this.model.data) works
dataSource: computed(function() {
return emberArray([
{"category": "A", "amount": 28},
{"category": "B", "amount": 55},
{"category": "C", "amount": 43},
{"category": "D", "amount": 91},
{"category": "E", "amount": 81},
{"category": "F", "amount": 53},
{"category": "G", "amount": 19},
{"category": "H", "amount": 87}
]);
}),
data: computed('dataSource.{[],#each.amount}', function () {
const dataSource = get(this, 'dataSource');
return {
table: dataSource.map((datum) => {
// return a copy because Vega Vis will mutate the dataset.
return {
...datum
};
})
};
})
Related
I am having trouble with reactivity Chartjs in Svelte. I wish that chart update eminently when the data for energy changes. What is missing in this code ?
<script lang="ts">
import { Line } from "svelte-chartjs";
import { onMount } from "svelte";
let labels = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
let energy =[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let data = {
labels,
datasets: [
{
label: "Dataset",
data: energy,
borderColor: "rgb(255, 99, 132)",
backgroundColor: "rgba(255, 99, 132, 0.5)"
},
]
};
$:labels,energy,data
onMount(() => {
const interval = setInterval(() => {
rendom();
console.log(energy)
}, 1000);
return () => {
clearInterval(1);
};
})
function rendom() {
let index=Math.round(Math.random()*9);
energy[index]=Math.round(Math.random()*100)
}
</script>
<Line data={data}/>
Answers for my problem.
Looking at the Line Chart Example some imports from chart.js and ChartJS.register() seem to be necessary
The Line component from svelte-chartjs exports a reference to the chart on which .update() can be called after changing the data. The reference can be accessed via a local variable and bind:
Notice that clearInterval() takes the reference to the interval (and maybe change rendom to random as in Math.random())
REPL
<script>
import {
Chart as ChartJS,
Title,
Tooltip,
Legend,
LineElement,
LinearScale,
PointElement,
CategoryScale,
} from 'chart.js';
ChartJS.register(
Title,
Tooltip,
Legend,
LineElement,
LinearScale,
PointElement,
CategoryScale
);
import { Line } from "svelte-chartjs";
import { onMount } from "svelte";
let labels = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
let energy =[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let chartRef
let data = {
labels,
datasets: [
{
label: "Dataset",
data: energy,
borderColor: "rgb(255, 99, 132)",
backgroundColor: "rgba(255, 99, 132, 0.5)"
},
]
};
onMount(() => {
const interval = setInterval(() => {
rendom();
}, 1000);
return () => {
clearInterval(interval);
};
})
function rendom() {
let index=Math.round(Math.random()*9);
energy[index]=Math.round(Math.random()*100)
chartRef.update()
}
</script>
<Line bind:chart={chartRef} data={data}/>
I have data in an index in JSON format, and I want to use a Vega visualization to display this (full Vega, not Vega-Lite). I've found however that every example out there is for Vega-Lite and all they're trying to do it stick their data into a time series graph. I'd like to do something different, and thus I find myself at a dead-end.
A sample doc in my index:
{
"_index": "myindex",
"_type": "doc",
"_id": "abc123",
"_version": 1,
"_score": null,
"timestamp": "2022-05-23T07:43:21.123Z",
"_source": {
"fruit": [{
"amount": 15,
"type": {
"grower_id": 47,
"grower_country": "US",
"name": "apple"
}
},
{
"amount": 43,
"type": {
"grower_id": 47,
"grower_country": "CAN",
"name": "apple"
}
},
{
"amount": 7,
"type": {
"grower_id": 23,
"grower_country": "US",
"name": "orange"
}
},
{
"amount": 14,
"type": {
"grower_id": 23,
"grower_country": "CAN",
"name": "orange"
}
}
]
}
}
What I want to do is create 2 text marks on the visualization that will display the sum of the values as follows.
Symbol1 = sum of all apples (i.e. all apples grown in the US and CAN combined)
Symbol2 = sum of all oranges (i.e. all oranges grown in the US and CAN combined)
I tried the following data element with no success:
"data": [{
"name": "mydata",
"url": {
"index": "myindex",
"body": {
"query": "fruit.type.name:'apple'",
},
}
}
]
However obviously this query isn't even correct. What I want to be able to do is return a table of values and then be able to use those values in my marks as values to drive the mark behaviour or color. I'm comfortable with doing the latter in Vega, but getting the data queried is where I'm stuck.
I've read and watched so many tutorials which cover Vega-Lite, but I'm yet to find a single working example for Vega on AWS OpenSearch.
Can anyone please help?
Sorry for my poor explanation, I just started learning dart.
With a mock service and a json file I created a set amount of items
Example:
{
"items": [
{
"id": "01",
"type": "a"
},
{
"id": "02",
"type": "b"
},
{
"id": "03",
"type": "c"
}
]
}
when creating the list on the service it creates a single list like this:
if (json['items'] != null) {
final itemList = <ItemList>[];
json['items'].forEach((v) {
itemlistList.add(ItemList.fromJson(v));
});
return ItemList;
} else {
return [];
}
is there a way to, form the create list step to already separate them into 3 different lists for the type a, b, and c items? and if now, where and how would I divide this itemlist into 3 based on the type characteristic of each item?
Using groupBy, as suggested in this extremely similar question: Flutter/Dart how to groupBy list of maps?
import "package:collection/collection.dart";
main(List<String> args) {
var data = [
{"id": "01", "type": "a"},
{"id": "02", "type": "b"},
{"id": "03", "type": "c"},
{"id": "04", "type": "a"},
{"id": "05", "type": "a"},
{"id": "06", "type": "b"},
];
var newMap = groupBy(data, (Map obj) => obj["type"]);
print(newMap);
}
I just started testing the api using the postman. I have come across one problem with the json path..
in json file I have code which looks like this
{
"users": [
{
"firstName": "UserOne",
"lastName": "One",
"subjectId": 1,
"id": 1
},
{
"firstName": "UserTwo",
"lastName": "Two",
"subjectId": 2,
"id": 2
},
{
"firstName": "UserThree",
"lastName": "Three",
"subjectId": 3,
"id": 3
}
],
"subjects": [
{
"id": 1,
"name": "SubOne"
},
{
"id": 2,
"name": "SubTwo"
},
{
"id": 3,
"name": "SubThree"
}
]
}
I start the json server with json-server --watch db.json
After that I send GET request using postman
Request URL http://localhost:3000/users
this is the body I get
[
{
"firstName": "UserOne",
"lastName": "One",
"subjectId": 1,
"id": 1
},
{
"firstName": "UserTwo",
"lastName": "Two",
"subjectId": 2,
"id": 2
},
{
"firstName": "UserThree",
"lastName": "Three",
"subjectId": 3,
"id": 3
}
]
I was trying to verify the firstName from the id 1 using the snippet code below
pm.test("Your test name", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.users[0].firstName).to.eql('UserOne');
});
But the output was
FAIL Your test name | TypeError: Cannot read property '0' of undefined
I need help here because the json path users[0].firstName should give me the first index..
There is no key users in your response, so when you try to access the non-existed key, you will get error Cannot read property 'xxx' of undefined. To fix that, you just need:
pm.test("Your test name", function () {
var jsonData = pm.response.json();
pm.expect(jsonData[0].firstName).to.eql('UserOne');
});
I am trying to pass the data to a serializer like the following:
myDict = {
"invoice_date": "2021-02-24T11:44:13+05:30",
"invoice_number": "12",
"vendor": "4",
"amount": "12",
"gst": "12",
"total_amount": "14",
"transaction_type": "Allot",
"status": "Hold",
"transactions": [
{
"t_no": 47,
"f_mile": "45",
"long_haul": "45",
"l_mile": "45",
"labour": "45",
"others": "54",
"a_t_no": 47,
},
{
"t_no": 102,
"f_mile": "12",
"long_haul": "12",
"l_mile": "21",
"labour": "21",
"others": "21",
"a_t_no": 102,
},
],
"owner": 2,
}
But when I check the validated data in the serialzer it shows it without the transactions data:
{'invoice_date': datetime.datetime(2021, 2, 24, 6, 14, 13, tzinfo=<UTC>), 'invoice_number': '12', 'amount': 12, 'gst': 12, 'total_amount': 14, 'status': 'Hold', 'transaction_type': 'Allot', 'vendor': <Vendor: Vendor object (4)>, 'owner': <User: yantraksh>}
so I tried to check the initial data that is being passed to the serializer :
<QueryDict: {
"invoice_date": ["2021-02-24T11:44:13+05:30"],
"invoice_number": ["12"],
"vendor": ["4"],
"amount": ["12"],
"gst": ["12"],
"total_amount": ["14"],
"transaction_type": ["Allot"],
"status": ["Hold"],
"transactions": [
'[{"t_no":47,"f_mile":"45","long_haul":"45","l_mile":"45","labour":"45","others":"54","a_t_no":47},{"t_no":102,"f_mile":"12","long_haul":"12","l_mile":"21","labour":"21","others": "21","a_t_no":102}]'
],
"owner": [2],
}>
It shows that the transaction data is being passed as a string, what should I change it to in order to get it as validated data ?
Based on the "evidence" in that QueryDict (namely strings wrapped in lists) it sounds like you're not submitting the data as JSON.
You can't use regular HTML form data to submit structured data, you'll need to post JSON data.