Related
Need help with converting this df to exact JSON as an example using R. Already tried a lot of approaches but cant succeed. Please help.
Code for generating sample:
df <- data.frame(month = c(1, 1, 1, 2, 2, 2),
station = c('AE', 'DС', 'CL', 'AE', 'DC', 'CL'),
persons = c(3, 12, 21, 12, 10, 9),
results = c(10, 34, 57, 19, 16, 5)
)
Its needed to drop column "station" and add level "summary" which gather results to pairs "person" and "results" just as like example shows.
Needed JSON output.
[
{
"month": "1",
"summary": [
{
"persons": 3,
"results": 10
},
{
"persons": 12,
"results": 34
},
{
"persons": 21,
"results": 57
}
]
},
{
"month": "2",
"summary": [
{
"persons": 12,
"results": 19
},
{
"persons": 10,
"results": 16
},
{
"persons": 9,
"results": 5
}
]
}
]
You could use tidyr::nest and jsonlite::toJson like so:
library(tidyr)
library(dplyr)
library(jsonslite)
df |>
select(-station) |>
group_by(month) |>
nest() |>
rename(summary = data) |>
jsonlite::toJSON()
#> [{"month":1,"summary":[{"persons":3,"results":10},{"persons":12,"results":34},{"persons":21,"results":57}]},{"month":2,"summary":[{"persons":12,"results":19},{"persons":10,"results":16},{"persons":9,"results":5}]}]
I'm trying to align axis labels in HighCharts
Labels should not be trimed, so ellipsis is not allowed
How it looks now:
How I want it to be:
Code: https://jsfiddle.net/9xw6dL3f/25/
{
"chart": {
"width": 500,
"height": 300,
"type": "column"
},
"title": {
"text": null
},
"xAxis": {
"type": "category",
"labels": {
"rotation": -90,
"style": {
"textOverflow": "none"
}
}
},
"series": [
{
"name": "",
"data": [
{ "name": "Follow me into my theatre of lunacy", "y": -10, "color": "#ABC" },
{ "name": "1", "y": 1, "color": "#000" },
{ "name": "2", "y": 2, "color": "#000" },
{ "name": "3", "y": 3, "color": "#000" },
{ "name": "4", "y": 4, "color": "#000" },
{ "name": "5", "y": 5, "color": "#000" },
]
}
]
}
It is possible to move label depending on it's rows count
Add render function to the chart object
{
"chart": {
...
events: {
render() {
for (let i = 0; i < this.xAxis[0].names.length; i++) {
const label = this.xAxis[0].ticks[i].label;
const rows = (label.element.innerHTML.match(/<\/tspan>/g) || []).length;
label.translate(-8 * rows, 0);
}
}
}
where 8 is half of row size in px
https://jsfiddle.net/kLz1uoga/5/
I'm trying to produce a plot of a directed graph. Hence, I'd like to plot an arrow from one node
to another. Is it possible to do this on Vega-Lite? And if yes, then how so?
There is no support for arrows on line segments in Vega-Lite. You can see the open feature request here: https://github.com/vega/vega-lite/issues/4270
For some applications, it might be suitable to annotate charts with unicode arrows; here is a brief example (open in editor):
{
"data": {
"values": [{"x": 1, "y": 2}, {"x": 2, "y": 4}]
},
"mark": {"type": "text", "angle": -45, "dx": -20, "fontSize": 35},
"encoding": {
"text": {"value": "➟"},
"x": {"field": "x", "type": "quantitative"},
"y": {"field": "y", "type": "quantitative"}
}
}
I need to convert a dataframe to JSON. There are several nested dataframes as variables in the dataframe to convert to JSON.
But, when converting to JSON, I need the data for Values1 described below to be an object (enclosed in {} only) instead of an array (enclosed in []).
The code below is a reprex to show my current workflow and problem.
library(dplyr)
library(tidyr)
library(jsonlite)
df1 <- data.frame(name = c("a", "b", "c"),
v = c(1, 2, 3),
w = c(10, 20, 30)) %>%
group_by(name) %>%
nest_legacy(.key = "Values1")
df2 <- data.frame(name = c("a", "b", "c"),
x = c(5, 10, 15),
y = c(100, 200, 300),
z = c(1000, 2000, 3000)) %>%
group_by(name) %>%
nest_legacy(.key = "Values2")
df3 <- df1 %>%
left_join(df2)
json <- toJSON(df3, dataframe = "rows", pretty = TRUE)
json
This is what the json from the above looks like:
> json
[
{
"name": "a",
"Values1": [
{
"v": 1,
"w": 10
}
],
"Values2": [
{
"x": 5,
"y": 100,
"z": 1000
}
]
},
{
"name": "b",
"Values1": [
{
"v": 2,
"w": 20
}
],
"Values2": [
{
"x": 10,
"y": 200,
"z": 2000
}
]
},
{
"name": "c",
"Values1": [
{
"v": 3,
"w": 30
}
],
"Values2": [
{
"x": 15,
"y": 300,
"z": 3000
}
]
}
]
But, this is what I need it to look like:
> json
[
{
"name": "a",
"Values1": {
"v": 1,
"w": 10
},
"Values2": [
{
"x": 5,
"y": 100,
"z": 1000
}
]
},
{
"name": "b",
"Values1": {
"v": 2,
"w": 20
},
"Values2": [
{
"x": 10,
"y": 200,
"z": 2000
}
]
},
{
"name": "c",
"Values1": {
"v": 3,
"w": 30
},
"Values2": [
{
"x": 15,
"y": 300,
"z": 3000
}
]
}
]
Any ideas how to convert Values1 from arrays to objects? They cannot be in arrays as the API does not accept the [.
I have looked at using unbox() from jsonlite but this only works on singletons. I have also tried to construct my final dataframe in various ways.
Any tips/ideas greatly appreciated!
This should return what you desire:
...
df3 <- left_join(df1, df2, by = "name")
json <- mutate(df3, Values1 = purrr::map(Values1, as.list)) %>%
jsonlite::toJSON(auto_unbox = TRUE, pretty = TRUE)
Can you confirm?
I need to add labels with difference of 10 in both axis( one each between the grid ), WITHOUT compromising the present number of grids.So the number of grid lines should stay 11 and number of labels will go up to 21. Hope that clears my query.Above is my chart, and this is the code -
var chart = AmCharts.makeChart("chartdiv", {
"type": "xy",
"dataProvider": json,
"valueAxes":
[
{
"id":"my_y",
"autoGridCount": false,
"position": "right",
"tickLength":0,
"gridThickness":0.25,
"minimum":-100,
"maximum":100,
"gridCount": 11,
"labelFrequency" : 0.5,
"gridColor":"black",
"gridAlpha":0.50,
"labelOffset": -356,
"axisAlpha":0,
"strictGridCount" : true,
},
{
"id":"my_x",
"autoGridCount": false,
"position": "bottom",
"tickLength":0,
"gridThickness": 0.25,
"minimum":-100,
"maximum":100,
"gridCount": 11,
"labelFrequency" : 0.5,
"gridColor":"black",
"gridAlpha":0.50,
"labelOffset": -320,
"axisAlpha":0,
},
],
"borderAlpha" : 0,
"startDuration": 0,
"legend":[{
"useGraphSettings": false,
"verticalGap":0,
}],
"guides":[
{
"fillAlpha": 0.10,
"value": -100,
"toValue": 100,
}
],
"graphs":
[
{
"id":"g1",
"lineColor": "#FF6600",
"bulletBorderThickness": 1,
"hideBulletsCount": 30,
"animationDuration":0,
"balloonText": "[[value]]",
"bullet": "circle",
"lineAlpha": 0,
"valueField": "value",
"xField": "x",
"yField": "y",
"fillAlphas": 0,
"bulletBorderAlpha": 0,
"minBulletSize": 30,
"maxBulletSize": 30,
"labelText":"[[x]]",
"labelPosition":"inside",
"markerType" : "none",
"switchable":false,
},
],
"marginLeft": 20,
"marginBottom": 20,
"export": {
"enabled": true,
"menu" : [],
},
});
PS : I tried to change the labelFrequency value but I don't think it takes values below 1.
You're right to assume that labelFrequency can't be set to anything lower than 1, or a non-integer for that matter.
The only workaround I can think of is to increase gridCount to the number which displays labels in increments that you want. I.e. 21.
Then disable grid lines altogether. (gridAlpha: 0)
And finally use guides to display lines at values that you need lines displayed at. I.e.:
{
"id": "my_y",
"autoGridCount": false,
"position": "right",
"tickLength": 0,
"gridThickness": 0.25,
"minimum": -100,
"maximum": 100,
"gridCount": 21,
"labelFrequency": 0.5,
"gridColor": "black",
"gridAlpha": 0,
"labelOffset": -356,
"axisAlpha": 0,
"strictGridCount": true,
"guides": [
{ "value": 80, "lineAlpha": 0.5 },
{ "value": 60, "lineAlpha": 0.5 },
{ "value": 40, "lineAlpha": 0.5 },
{ "value": 20, "lineAlpha": 0.5 },
{ "value": 0, "lineAlpha": 0.5 },
{ "value": -20, "lineAlpha": 0.5 },
{ "value": -40, "lineAlpha": 0.5 },
{ "value": -60, "lineAlpha": 0.5 },
{ "value": -80, "lineAlpha": 0.5 }
]
}