Is it possible to get the data table column names in Vega-lite as an array? - pandas

Is there a Vega/Vega-lite equivalent of pandas' df.columns?
I would like to get an array with all column names in Vega-lite. For this dataset:
{"data": { "values" : [{"a":4, "b":5},{"a":6, "b":7}] }}
I would like to get an array ["a","b"]. This would be extremely helpful when using the fold transform with large datasets.

Here is one way to get a Vega dataset fieldnames using Vega API.
In Vega spec, add signal declaration, e.g.:
"signals":[
{"name": "signal_data_table_fieldnames"
}
In javacript, use Vega view API methods signal and data to retrieve the first record of the dataset table and obtain the fieldnames as an array with javascript Object.keys()
When using the view.signal, the Vega API method can both get and set the internal Vega signal value. The updated signal value can be used anywhere within the Vega spec.
Vega API docs for signal and data methods:
https://vega.github.io/vega/docs/signals/
https://vega.github.io/vega/docs/api/view/#signals
https://vega.github.io/vega/docs/api/view/#data-and-scales
Example code using
https://vega.github.io/vega/usage/
with bar chart example
https://vega.github.io/vega/examples/bar-chart/ :
var view;
fetch('https://vega.github.io/vega/examples/bar-chart.vg.json')
.then(res => res.json())
.then(spec => render(spec))
.catch(err => console.error(err));
function render(spec) {
view = new vega.View(vega.parse(spec), {
renderer: 'canvas', // renderer (canvas or svg)
container: '#view', // parent DOM container
hover: true // enable hover processing
});
return view.runAsync();
}
// Vega API
view.signal("signal_data_table_fieldnames", Object.keys(view.data("table")[0]));
console.log(view.signal("signal_data_table_fieldnames"));

Related

Vue ApexCharts is not smooth

I'm using apex charts to create a graph of real-time data coming in from the back-end.
I have used the demo as a guide and implemented my own real-time chart (https://apexcharts.com/vue-chart-demos/line-charts/realtime/)
I want the data to scroll like in the linked example, currently, mine appears to redraw the line each time it's updated (https://imgur.com/a/1aTc1JV)
I use this function to update the series data with a fixed-length queue which is updated every second (queue.append(newData) and then queue.pop(0))
updateChart: function () {
var me = this;
this.intervalid1 = setInterval(() => {
me.$refs.chart.updateSeries([
{
data: this.temperature,
},
]);
}, 1000);
},
Insted of doing queue.pop(0) set range in xaxis to length - 1 of your initial data (if type: "numeric").
https://apexcharts.com/docs/options/xaxis/#range

Can't set array of features in vectorSource openlayers

I'm having an issue where I try to set my VectorSource with my features array from my state but I get "feature.getId is not a function".
What I would like is the have my feature displayed depending on my state, because i'll have filter and I need to fave feature on map reacting with filters.
How can i set my features list in the feature in my VectorSource ?
I'm getting my state array like this :
getAllFeature() {
return this.$store.getters.GET_ALLFEATURES;
},
then i'm trying to passe the array in the vectorSource
source: new VectorSource({
format: new GeoJSON(),
features: this.getAllFeatures,
}),
Notice that I modified the form of my array comparing to the native geojson file I have
getGeoJSONData() {
axios
.all([
axios.get("http://localhost:8080/germany.geojson"),
axios.get("http://localhost:8080/france.geojson"),
])
.then(
axios.spread((...responses) => {
const features = [];
responses.forEach((res) => {
features.push(res.data.features.flat());
});
this.$store.dispatch("LOAD_FEATURES", features.flat());
})
);
},
},
Even if I try to set the strict same array that I receive from one of the Geojson, i have this error.
Any help would be appreciated
Thanks in advance

Vue computed property not updating object literal

I'm building a GeoJSON editor which displays a preview in vue2-google-maps. One of the challenges is converting the GeoJSON's coordinates into LatLngLiteral's to be used as props in <GmapMarker>, <GmapPolygon>, or <GmapPolyline>. My solution is to use computed properties. So when the GeoJSON's changed, the map objects get changed too. Like so:
computed: {
mapObject() {
// If the geometry is a point, just assign geometry.coordinates into `lat` and `lng`
if (this.$data.geometry.type === "Point") return ({
lat: this.$data.geometry.coordinates[1],
lng: this.$data.geometry.coordinates[0],
});
// If it's a polygon, grab the first set of coordinates (we aren't supporting polygons with holes for now).
// then splice off the last element (Google Maps' polygon automatically loop the shape, unlike GeoJSON's convention),
// then we map the values into an array of LatLngLiterals.
if (this.$data.geometry.type === "Polygon") return this.$data.geometry.coordinates[0].splice(-1, 1).map(e => ({lat: e[1], lng: e[0]}));
// If it's a LineString, do as above, without the splicing.
if (this.$data.geometry.type === "LineString") return this.$data.geometry.coordinates.map(e => ({lat: e[1], lng: e[0]}));
}
},
Problem is, this won't update for Point types. This seems to be working fine for Polygon and LineString types, though. Any help would be appreciated.

Updating a chart with new data in App SDK 2.0

I am using a chart to visualize data in a TimeboxScopedApp, and I want to update the data when scope changes. The more brute-force approach of using remove() then redrawing the chart as described here leaves me with an overlaid "Loading..." mask, but otherwise works. The natural approach of using the Highchart native redraw() method would be my preference, only I don't know how to access the actual Highchart object and not the App SDK wrapper.
Here's the relevant part of the code:
var chart = Ext.getCmp('componentQualityChart');
if (chart) {
var chartCfg = chart.getChartConfig();
chartCfg.xAxis.categories = components;
chart.setChartConfig(chartCfg);
chart.setChartData(data);
chart.redraw(); // this doesn't work with the wrapper object
} else { // draw chart for the first time
How do I go about redrawing the chart with the new data?
Assuming chart (componentQualityChart) is an instance of Rally.ui.chart.Chart, you can access the HighCharts instance like this:
var highcharts = chart.down('highchart').chart;
// Now you have access to the normal highcharts interface, so
// you could change the xAxis
highcharts.xAxis[0].setCategories([...], true);
// Or you could change the series data
highcharts.series[0].data.push({ ... }); //Add a new data point
// Or pretty much anything else highcharts lets you do
Using _unmask() removes the overlaid "Loading.." mask
if (this.down('#myChart')) {
this.remove('myChart');
}
this.add(
{
xtype: 'rallychart',
height: 400,
itemId: 'myChart',
chartConfig: {
//....
},
chartData: {
categories: scheduleStateGroups,
series: [
{
//...
}
]
}
}
);
this.down('#myChart')._unmask();

Simple store connected list for dojo

Is there a simpler list type than DataGrid that can be connected to a store for Dojo?
I would like the data abstraction of the store, but I don't need the header and cell stucture. I would like to be more flexible in the representation of the datalines, where maybe each line calls an function to get laid out...
You ask a really good question. I actually have a blog post that is still in draft form called "The DataGrid should not be your first option".
I have done a couple thing using the store to display data from a store in a repeated form.
I have manually built an html table using dom-construct and for each.
var table = dojo.create('table', {}, parentNode);
var tbody = dojo.create('tbody', {}, table); // a version of IE needs this or it won't render the table
store.fetch({ // this is a dojo.data.ItemFileReadStore, but you cana dapt to the dojo.Store API
query: {},
onComplete: function(itms) {
dojo.forEach(itms, function(itm, idx) {
var tr = dojo.create('tr', {}, tbody);
// use idx to set odd/even css class
// create tds and the data that goes in them
});
}
});
I have also created a repeater, where I have an html template in a string form and use that to instantiate html for each row.
var htmlTemplate = '<div>${name}</div>'; // assumes name is in the data item
store.fetch({ // this is a dojo.data.ItemFileReadStore, but you cana dapt to the dojo.Store API
query: {},
onComplete: function(itms) {
dojo.forEach(itms, function(itm, idx) {
var expandedHtml = dojo.replace(htmlTemplate, itm);
// use dojo.place to put the html where you want it
});
}
});
You could also have a widget that you instantiate for each item.