I have an array of objects that I am using as a dataset in an interactive data dashboard. I want to add a new feature that displays data from only one object at a time, rather than pulling data from all objects (which I am already doing and it works well). As a test case, I have created a simple array:
var test1 = [
[{
"name": "Piece One",
"amount": 5
}, {
"name": "Piece Two",
"amount": 5
}, {
"name": "Piece Three",
"amount": 5
}],
[{
"name": "Piece One",
"amount": 1
}, {
"name": "Piece Two",
"amount": 1
}, {
"name": "Piece Three",
"amount": 5
}]
];
and the Vega-lite javascript:
var pieCreate = {
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"title": "A pie chart",
"description": "A simple pie chart with embedded data.",
"width": "container",
"height": "container",
"data": {
"values": test1[0]
},
"mark": "arc",
"encoding": {
"theta": {
"field": "amount",
"type": "quantitative"
},
"color": {
"field": "name",
"type": "nominal",
"legend": null
}
}
};
This works, but I want the user to be able to choose which object to display (in the dashboard, each object contains data on different schools, and I want the user to be able to choose which school's data to display using a dropdown menu). My first thought was to set up a signal in the "data": {"values": field that would change the number in brackets to the array I want, but after a lot of trial and error, I think that may be a dead end. Signals should work to modify "field": "amount" and "field": "name" but I've tried every iteration of [0].amount that I can think of, while dropping the brackets from test1[0] and nothing has worked. If I can manage to access the object by directly referencing it in "field": I believe I can figure out the process using a signal and html form, but I'm starting to doubt if I'm even on the right track here.
I also tried the process outlined here in the vega-lite documentation: https://vega.github.io/vega-lite/tutorials/streaming.html, but it's doing something much more complicated than what I'm trying to do, and my javascript knowledge isn't sufficient to break it down to something usable. Does anyone have any ideas on how to make this work, using any of the above approaches (or a new, better one)?
You can use the vega Api's to change the data. On your selection, add a change event and on some conditions you can toggle between your data using those API's.
Refer the below snippet or fiddle:
var test1 = [
[{
"name": "Piece One",
"amount": 5
}, {
"name": "Piece Two",
"amount": 5
}, {
"name": "Piece Three",
"amount": 5
}],
[{
"name": "Piece One",
"amount": 1
}, {
"name": "Piece Two",
"amount": 1
}, {
"name": "Piece Three",
"amount": 5
}]
];
var yourVlSpec = {
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"title": "A pie chart",
"description": "A simple pie chart with embedded data.",
"width": "350",
"height": "400",
"data": {
"values": test1[0]
},
"mark": "arc",
"encoding": {
"theta": {
"field": "amount",
"type": "quantitative"
},
"color": {
"field": "name",
"type": "nominal",
"legend": null
}
}
}
var view;
vegaEmbed("#vis", yourVlSpec).then(res => {
view = res.view;
});
function handleChange(a, b) {
var selectValue = document.getElementById("myselect").value;
if (selectValue == 'A') {
view.data('source_0', test1[0]);
} else {
view.data('source_0', test1[1]);
}
view.runAsync();
}
<script src="https://cdn.jsdelivr.net/npm/vega#5.20.2/build/vega.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-lite#5.0.0/build/vega-lite.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed#6.17.0/build/vega-embed.min.js"></script>
<select id="myselect" style="width:100px;" onchange="handleChange()">
<option>A</option>
<option>B</option>
</select>
<br>
<div id="vis"></div>
I am using vega-lite to create a pie chart (on Airtable). I have a single data point, which is a target set by me, and the percentage complete for that target. For example, as below:
{
"Target": "Get 10 customers",
"Percentage complete": "60"
}
I would like to make a pie chart that is 60% complete, and the rest empty. Similar to the interactive single arc pie chart displayed https://vega.github.io/vega-lite/docs/arc.html.
My code currently looks like this
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"title": "Customer Acquired",
"width": "container",
"height": "container",
"data": {
"values": [
{
"Target": "Get 10 customers",
"Percentage complete": "60"
}
]},
"mark": {
"type": "arc",
"tooltip": true
},
"encoding": {
"theta": {
"field": "Percentage complete",
"type": "quantitative"
}
}
}
And my pie chart currently just looks like this:
I realise I could force the pie chart to appear the way I want it by manually setting the theta2 property like so
"mark": {
"type": "arc",
"tooltip": true,
"theta2": 3.5
}
However I don't know what the "Percentage complete" field will be and this value may change often, so I would rather not have to do it manually. Is this at all possible with vega-lite?
The domain for the theta encoding will automatically be set to the minimum and maximum of your input data. To show the correct portion of the chart, you need to set the domain to [0, 100]:
"encoding": {
"theta": {
"field": "Percentage complete",
"type": "quantitative",
"scale": {"domain": [0, 100]}
}
}
You can view the resulting chart in the vega editor:
Currently working with this highcharts code:
https://jsfiddle.net/umL154cd/
It works with external data source like shown below:
$.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=activity.json&callback=?', function (activity) {
$.each(activity.datasets, function (i, dataset) { ///
But I'd like to truncate the data and put it inside the code itself by simply anouncing json.variable:
var datafromjson =
{
"xData": [0.001567,0.011765,0.022194],
"datasets": [{
"name": "Speed",
"data": [13.833,12.524,11.441,10.651],
"unit": "km/h",
"type": "line",
"valueDecimals": 1
}, {
"name": "Elevation",
"data": [26.857,27,27.111,27.2,27.272],
"unit": "m",
"type": "area",
"valueDecimals": 0
}, {
"name": "Heart rate",
"data": [101,98,103],
"unit": "bpm",
"type": "area",
"valueDecimals": 0
}]
};
How do I replace $.getJSON request so the script will take the turncated in-script data insted of accessing external data?
Thank you!
I'm trying to aggregate the color encoding in a vega-lite Choropleth map, using JavaScript.
I have made a working example to make it easier to help and understand
The minimal code is:
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"width": 600,
"height": 500,
"mark": "geoshape",
"data": {
"url": "https://gist.githubusercontent.com/benooghe/95c8b4d63f67f1856fdd81e6303c654e/raw/8ec1fdd91bfbf4973f97ffb8a5daacb8f431908e/geo_belgium.json",
"format": {"type": "topojson", "feature": "data"}
},
"encoding": {
"color": {
"field": "properties.nis_code",
"type": "quantitative",
// "aggregate":"sum" // <-- THIS BREAKS THE MAP
}
}
}
This is a simplified version, it works, but if you add , "aggregate: "sum" in the encoding.color then it doesn't work anymore.
In case I oversimplified, my complete map is just a little bit more complicated: it has a transform.lookup.
let yourVlSpec = {
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"width": 600,
"height": 500,
"mark": "geoshape",
"data": { // TOPOJSON DATA -----
"url": 'geo_belgium.json',
"format": {
"type": "topojson",
"feature": "data"
}
},
"transform": [{ // LEFT JOIN DATA -----
"lookup": "properties.nis_code",
"from": {
"data": {
"url": "data.csv"
},
"key": "NIS5",
"fields": ["Cases", "Deaths"]
}
}],
"encoding": {
"color": {
"field": "Cases",
"type": "quantitative",
// "aggregate": "sum" // <-- THIS BREAKS THE MAP
}
}
};
vegaEmbed('#vis', yourVlSpec);
EDIT: I also tried this : in the transform
"aggregate": [{"op": "sum", "field": 'Cases', "as": 'sum_cases'}],
EDIT2: The data in data.csv looks like this:
Date,PostCode,Cases,Deaths,NIS5
2020-04-08,2470,1,,13036
2020-04-08,2430,1,,13053
2020-04-08,1457,1,,25124
2020-04-08,3212,1,,24066
2020-04-08,2400,1,,13025
2020-04-08,1651,1,,23003
2020-04-08,2360,1,,13031
2020-04-07,1070,22,12,21004
2020-04-07,1070,22,12,21001
2020-04-07,4000,24,11,62093
2020-04-07,4000,24,11,62063
2020-04-01,9320,1,,41002
2020-04-01,7380,1,,53068
2020-04-01,9308,1,,41002
2020-03-31,1070,34,7,21004
2020-03-31,1070,34,7,21001
2020-03-31,3500,7,7,71022
2020-03-31,3800,10,5,71053
2020-03-31,4000,28,4,62063
2020-03-31,4000,28,4,62093
I'm looking to plot the sum of "Cases" per "NIS5", summing up all Dates
When you express a sum as part of an encoding, it groups by all other encoding fields. In your case there are no other encoding fields, so it aggregates everything and throws-out the geometry.
One way to work around this is to add relevant fields to a detail encoding, so that the aggregation does not drop them from the data (vega editor):
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"width": 600,
"height": 500,
"mark": "geoshape",
"data": {
"url": "https://gist.githubusercontent.com/benooghe/95c8b4d63f67f1856fdd81e6303c654e/raw/8ec1fdd91bfbf4973f97ffb8a5daacb8f431908e/geo_belgium.json",
"format": {"type": "topojson", "feature": "data"}
},
"encoding": {
"color": {"field": "properties.nis_code", "type": "quantitative", "aggregate": "sum"},
"detail": [{"field": "geometry", "type": "nominal"}, {"field": "properties.id", "type": "nominal"}, {"field": "type", "type": "nominal"}]
}
}
In your case, however, this is the same as the original unaggregated chart because there is a single nis_code per geographic area.
If you want to group by something other than geometric region, the best way to do that is to use a joinaggregate transform (which does not drop unnamed fields) and group by the particular data you're interested in grouping by. For example, here's the sum of nis_code grouped by the level_2 feature (vega editor):
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"width": 600,
"height": 500,
"mark": "geoshape",
"data": {
"url": "https://gist.githubusercontent.com/benooghe/95c8b4d63f67f1856fdd81e6303c654e/raw/8ec1fdd91bfbf4973f97ffb8a5daacb8f431908e/geo_belgium.json",
"format": {"type": "topojson", "feature": "data"}
},
"transform" : [{
"joinaggregate": [{"field": "properties.nis_code", "op": "sum", "as": "sum_nis_code"}],
"groupby": ["properties.level_2"]
}],
"encoding": {
"color": {"field": "sum_nis_code", "type": "quantitative"}
}
}
Check this fiddle to get an idea of what I am talking about
This is my xAxis configuration:
"xAxis": {
"categories": ["Category ONE", "Category TWO"],
"allowDecimals": false,
"title": {
"text": " ",
"align": "middle",
"style": {
"color": "steelblue"
}
},
"labels": {
"y": 12,
"style": {
"color": "steelblue"
}
}
},
I need category one and category two to be separated by a few pixels (50,100, whatever amount I want) but cannot find the solution for this issue. I know there is a way to do it for series but there is no equivalent for when you only want to separate the categories.
Thanks in advance
plotOptions have some options which can control series. Padding is possible to get by changing value of groupPadding:
"plotOptions": {
"column": {
"groupPadding": 0.1
}
}
And see it live: http://jsfiddle.net/JEGGf/42/