Highcharts interactive spline - charts

I have a question about highcharts data. I want to make a draggable chart to control a led. But I don't know how to store the entire data series after dragging the line.
$(function () {
$('#container').highcharts({
chart: {
renderTo: 'chart-container',
animation: false
},
xAxis: {
categories: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23']
},
plotOptions: {
series: {
cursor: 'ns-resize',
point: {
events: {
drop: function() {
$('#drop').html(
'In <b>' + this.series.name + '</b>, <b>' +
this.category + '</b> was set to <b>' +
this.data + '</b>'
);
}
},
},
stickyTracking: false
},
column: {
stacking: 'normal'
}
},
tooltip: {
yDecimals: 2
},
series: [{
data: [71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4, 194.1, 95.6],
//draggableX: true,
draggableY: true,
dragMaxY: 250,
dragMinY: 0,
type: 'spline',
minPointLength: 2
}]
});
});

Related

How can I query all when using Pymongo, group? not using accumulation?

I am making a restful api based on flask and Pymongo. Been trying to query data in a specific shape but having a hard time querying it. Below is my query code.
def track_route(from_time, to_time):
doc = myCol.aggregate([
{"$match":{
"MessageTime":{"$gt": from_time},
"MessageTime":{"$lt": to_time}
}},
{"$group":{
"_id":'$MMSI',
"$MMSI":{"accumulator1":"$ROT"}
}},
{"$project":{"_id":0}}
])
doc_list = [i for i in doc]
return doc_list
It returns this.
pymongo.errors.OperationFailure: The field '$MMSI' must be an accumulator object, full error: {'ok': 0.0, 'errmsg': "The field '$MMSI' must be an accumulator object", 'code': 40234, 'codeName': 'Location40234'}
This is the shape that I want to return.
[
{
123456789: [
{
MessageTime: '2021-05-28 17:29:22',
BaseStationID: '999999',
MsgType: '11',
mode: '3',
ROT: '0',
SOG: '0.0',
PosAcc: '0',
lon: '99.32404166666667',
lat: '93.47150833333333',
COG: '99.9',
Heading: '68',
MessageTimeU: '1622190562',
},
{
MessageTime: '2021-05-28 17:48:57',
BaseStationID: '4999314',
MsgType: '11',
mode: '1',
ROT: '0',
SOG: '17.7',
PosAcc: '1',
lon: '99.48246666666667',
lat: '9.980546666666667',
COG: '999.0',
Heading: '341',
MessageTimeU: '1622191737',
},
{
MessageTime: '2021-05-28 13:16:50',
BaseStationID: '999914',
MsgType: '11',
mode: '1',
ROT: '-128',
SOG: '0.1',
PosAcc: '1',
lon: '999.531585',
lat: '99.52044166666666',
COG: '998.2',
Heading: '511',
MessageTimeU: '1622175410',
},
{
MessageTime: '2021-05-28 11:45:43',
BaseStationID: '9903702',
MsgType: '11',
mode: '4',
ROT: '0',
SOG: '9.4',
PosAcc: '0',
lon: '99.51709333333334',
lat: '9.952831833333333',
COG: '00.9',
Heading: '511',
MessageTimeU: '1622169943',
},
],
},
{
234567890: [
{
MessageTime: '2021-05-28 20:59:52',
BaseStationID: '000702',
MsgType: '11',
mode: '1',
ROT: '-128',
SOG: '0.0',
PosAcc: '1',
lon: '00.46612166666667',
lat: '00.507135',
COG: '360.0',
Heading: '511',
MessageTimeU: '1622203192',
},
{
MessageTime: '2021-05-28 09:41:51',
BaseStationID: '0003702',
MsgType: '11',
mode: '1',
ROT: '-128',
SOG: '4.5',
PosAcc: '1',
lon: '00.26525833333334',
lat: '00.44930333333333',
COG: '238.7',
Heading: '511',
MessageTimeU: '1622162511',
},
{
MessageTime: '2021-05-28 17:48:50',
BaseStationID: '0003702',
MsgType: '11',
mode: '3',
ROT: '-128',
SOG: '0.0',
PosAcc: '0',
lon: '00.258005',
lat: '00.41504833333333',
COG: '00.4',
Heading: '511',
MessageTimeU: '1622191730',
},
{
MessageTime: '2021-05-28 14:27:42',
BaseStationID: '0003702',
MsgType: '11',
mode: '4',
ROT: '0',
SOG: '7.1',
PosAcc: '1',
lon: '00.260425',
lat: '00.418685',
COG: '65.0',
Heading: '511',
MessageTimeU: '1622179662',
},
],
},
];
123456789 and 234567890 are the MMSI value and are the key value for sub documents. How can I query in the shape above? It's nested. If cannot, at least the most similar way.
You have some mistakes in your aggregation, you cannot reference a field as a key, you should put a static field name.
This a correct way to group.
db.collection.aggregate({
"$group": {
"_id": "$MMSI",
"a": { //replace that "a" with any field name you want but not for a $ref
"$push": "$$ROOT" // you need to use an accumulator like $push, and the correct form to reference the whole doc is $$ROOT
}
}
}
Then you can map your info as you wanted. You can test the code here
{
"$replaceRoot": {
"newRoot": {
$arrayToObject: {
$map: {
input: [
"$$ROOT"
],
as: "el",
in: {
"k": {
$toString: "$$el._id"
},
"v": "$$el.a"
}
}
}
}
}
}

Material-UI Datagrid Styling

I'm so confused about how to change the complete row header background color of the DataGrid in the new MUI 5 styling. I think the doc didn't get updated for the new Emotion styling system. Could anyone help me out?
UPDATE:
Ok so I figured out how to actually make a change but I'm using the old makeStyles from Mui 4 is there an alternative to that ?
Here's the code :
import * as React from 'react';
import { DataGrid, frFR } from '#mui/x-data-grid';
import { IconButton } from '#mui/material';
import { Home } from '#mui/icons-material';
import { createTheme, ThemeProvider } from '#mui/material/styles';
import { makeStyles } from '#mui/styles';
const rows = [
{
id: 1,
col1: '12345 SEIGNEURS, BOULEVARD DES',
col2: 'TERREBONNE',
col3: '1',
col4: '2',
col5: '3',
col6: '4',
},
{
id: 2,
col1: '12345 SEIGNEURS, BOULEVARD DES',
col2: 'TERREBONNE',
col3: '5',
col4: '6',
col5: '7',
col6: '8',
},
{
id: 3,
col1: '12345 SEIGNEURS, BOULEVARD DES',
col2: 'TERREBONNE',
col3: '9',
col4: '10',
col5: '11',
col6: '12',
},
];
const columns = [
{
field: 'col1',
headerClassName: 'Test',
headerName: 'Adresse',
sortable: false,
width: 375,
},
{ field: 'col2', headerName: 'Secteur', sortable: false, width: 235 },
{ field: 'col3', flex: 1, headerName: 'Nombre de logement', sortable: false },
{ field: 'col4', flex: 0.5, headerName: 'Déchets', sortable: false },
{ field: 'col5', flex: 0.5, headerName: 'Recyclage', sortable: false },
{ field: 'col6', flex: 0.5, headerName: 'Organique', sortable: false },
];
const theme = createTheme();
const styles = makeStyles((theme) => ({
root: {
borderLeft: 0,
borderRight: 0,
borderBottom: 0,
'& .cold': {
backgroundColor: '#b9d5ff91',
color: '#1a3e72',
},
'& .hot': {
backgroundColor: '#ff943975',
color: '#1a3e72',
},
},
}));
export default function DataTable() {
const handleClick = (params, event) => {};
const classes = styles();
return (
<ThemeProvider theme={theme}>
<div sx={{ height: 300, width: '100%' }}>
<DataGrid
autoHeight
className={classes.root}
getCellClassName={(params) => {
if (
params.field === 'col3' ||
params.field === 'col4' ||
params.field === 'col5' ||
params.field === 'col6'
) {
return params.value >= 3 ? 'hot' : 'cold';
}
return '';
}}
columns={columns}
disableColumnMenu
localeText={frFR.components.MuiDataGrid.defaultProps.localeText}
rows={rows}
onRowClick={(params, event) => handleClick(params, event)}
/>
</div>
</ThemeProvider>
);
}

How to display multiple lines in eCharts using encode?

In eCharts, how do I modify the following option to show multiple lines in the chart? What I want is one line for product "Matcha Latte" and one line for "Cheese Cocao"? I would like to keep the dataset unchanged if possible.
option = {
legend: {},
tooltip: {},
dataset: {
dimensions: [{name:'product', type:'ordinal'}, {name:'date'},
{name:'value'}],
source: [
{product: 'Matcha Latte', 'date': 2016, 'value': 85.8},
{product: 'Matcha Latte', 'date': 2017, 'value': 73.4},
{product: 'Cheese Cocoa', 'date': 2016, 'value': 65.2},
{product: 'Cheese Cocoa', 'date': 2017, 'value': 53.9}
]
},
xAxis: {type: 'category', name: 'date'},
yAxis: {type: 'value', name: 'value'},
series: [
{type: 'line', encode: {x: 'date', y:'value'}},
]
};
you can you transform the dataset by using a filter:
option = {
legend: {},
tooltip: {},
dataset: [
{
dimensions: [
{ name: 'product', type: 'ordinal' },
{ name: 'date' },
{ name: 'value' }
],
source: [
{ product: 'Matcha Latte', date: 2016, value: 85.8 },
{ product: 'Matcha Latte', date: 2017, value: 73.4 },
{ product: 'Cheese Cocoa', date: 2016, value: 65.2 },
{ product: 'Cheese Cocoa', date: 2017, value: 53.9 }
]
},
{
fromDatasetIndex: 0,
transform: [
{
type: 'filter',
config: {
dimension: 'product',
value: 'Matcha Latte'
}
}
]
},
{
fromDatasetIndex: 0,
transform: [
{
type: 'filter',
config: {
dimension: 'product',
value: 'Cheese Cocoa'
}
}
]
}
],
xAxis: { type: 'category', name: 'date' },
yAxis: { type: 'value', name: 'value' },
series: [
{ datasetIndex: 1, type: 'line', encode: { x: 'date', y: 'value' } },
{ datasetIndex: 2, type: 'line', encode: { x: 'date', y: 'value' } }
]
};

Echarts show additional info in tooltip

I am using echarts for a scatter plot. Upon hover of a point, I want to show some more data in the tooltip, such as a date and unique ID - this data is not an axis in the plot. So far I have the following below, however I cannot figure out how to display the extra info
option = {
xAxis: {
type: 'value',
name: 'X axis title',
nameLocation: 'middle',
nameGap: 50,
nameTextStyle: {
fontSize: 12
}
},
yAxis: {
type: 'value',
name: 'Y axis title',
nameLocation: 'middle',
nameGap: 70,
nameTextStyle: {
fontSize: 12
}
},
dataZoom: [{
type: 'inside'
}],
legend: {
orient: 'vertical',
left: 10
},
grid: {
top: 80,
containLabel: true,
},
tooltip: {
trigger: "item"
},
series: [{
name: 'Outliers (Forensic Cases)',
type: 'scatter',
data: [[161.2, 51.6], [167.5, 59.0], [159.5, 49.2], [157.0, 63.0], [155.8, 53.6]
]],
}, {
name: 'Inliers (Regular Transaction)',
type: 'scatter',
data: [[172.7, 105.2], [153.4, 42]]
}]
};
;
Thanks for config, it saves time.
The tooltip component has method formatter and you can pass to it function-callback where to make request to addition data store to get and show on tooltip necessary information.
Suppose you have an object that stored additional information that needs to be shown in the tooltip:
var store = {
outliers: ['A', 'B', 'C', 'D', 'E', 'F'],
inliers: ['A', 'B', 'C', 'D', 'E', 'F']
}
Let's add id to the each data series, which will simplify data fetching.
{
id: 'outliers', // <--- this
name: 'Outliers (Forensic Cases)',
...
},
{
id: 'inliers', // <--- this
name: 'Inliers (Regular Transaction)',
...
}
In the callback you will have this default args:
{
$vars: ["seriesName", "name", "value"],
borderColor: undefined,
color: "#c23531",
componentIndex: 0,
componentSubType: "scatter",
componentType: "series",
data: [159.5, 49.2],
dataIndex: 2,
dataType: undefined,
dimensionNames: ["x", "y"],
encode: {
x: [0],
y: [1]
},
marker: "<span style=\"display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#c23531;\"></span>",
name: "",
seriesId: "outliers",
seriesIndex: 0,
seriesName: "Outliers (Forensic Cases)",
seriesType: "scatter",
value: [circular object Array]
}
Let's make the callback handler for the process series data and shown it on the tooltip:
var callback = (args) => {
var data = store[args.seriesId][args.dataIndex]
return args.marker + ' ' + args.value[1] + '<br />' + args.seriesId + ': ' + data
}
Now you can pass callback to formatter. It's all. See example below:
var myChart = echarts.init(document.getElementById('main'));
var store = {
outliers: ['A', 'B', 'C', 'D', 'E', 'F'],
inliers: ['A', 'B', 'C', 'D', 'E', 'F']
}
var callback = (args) => {
var data = store[args.seriesId][args.dataIndex]
return args.marker + ' ' + args.value[1] + '<br />' + args.seriesId + ': ' + data
}
var option = {
xAxis: {
type: 'value',
name: 'X axis title',
nameLocation: 'middle',
nameGap: 50,
nameTextStyle: {
fontSize: 12
}
},
yAxis: {
type: 'value',
name: 'Y axis title',
nameLocation: 'middle',
nameGap: 70,
nameTextStyle: {
fontSize: 12
}
},
dataZoom: [{
type: 'inside'
}],
legend: {
orient: 'vertical',
left: 10
},
grid: {
top: 80,
containLabel: true,
},
tooltip: {
trigger: "item",
formatter: callback,
},
series: [{
id: 'outliers',
name: 'Outliers (Forensic Cases)',
type: 'scatter',
data: [
[161.2, 51.6],
[167.5, 59.0],
[159.5, 49.2],
[157.0, 63.0],
[155.8, 53.6]
],
},
{
id: 'inliers',
name: 'Inliers (Regular Transaction)',
type: 'scatter',
data: [
[172.7, 105.2],
[153.4, 42]
]
}
]
}
myChart.setOption(option);
<script src="https://cdn.jsdelivr.net/npm/echarts#4.9.0/dist/echarts.min.js"></script>
<div id="main" style="width: 600px;height:400px;"></div>

Highcharts - Stack Chart to Stack Chart in Drilldown

Hope someone can help, I've search examples of this but can't get them to work on my particular setup. I have a stacked column chart in Highcharts representing 5 sets of data for each day of the week.
I then select a day to see an hourly breakdown of the day, I have the data coming through but I can't get the 5 values I have for each hour to stack on top of each other. (in the same way as the first chart) - ideally this second chart would be an area chart)
Here is my code:
$(function () {
Highcharts.setOptions({
lang: {
drillUpText: 'Reset'
}
});
// Create the chart
$('#chart2').highcharts({
chart: {
type: 'column',
height: 300
},
credits: {
enabled: false
},
title: {
text: null
},
subtitle: {
text: 'Select a day to expand to hourly data'
},
legend: {
enabled: false
},
tooltip: {
formatter: function() {
var point = this.point,
s = 'Day: <b>' + point.name + '</b><br/>Utilisation: <b>' + this.y + '% </b><br/>';
if (point.drilldown) {
s = 'Day: <b>' + point.name + '</b><br/>Utilisation: <b>' + this.y + '% </b><br/>Select to view hours';
} else {
s = 'Time: <b>' + point.name + '</b><br/>Utilisation: <b>' + this.y + '% </b><br/>Reset to return';
}
return s;
}
},
xAxis: {
type: 'category',
//categories: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
//categories: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24']
},
yAxis: {
title: false, // {text: 'Utilisation'}, Y axis title - taken text out
tickPositions: [0, 50, 70, 100], // Y axis labels
labels: {
format: '{value}%' // Y axis labels with % suffix
},
min: 0, // Following lines setting the grids to off adding min max
max: 100,
minorGridLineWidth: 0,
gridLineWidth: 0,
alternateGridColor: null,
plotBands: [{ // Below Avg.
from: 0,
to: 50,
color: 'rgba(255,108,96, 0.5)',
label: {
// text: 'Below Average',
style: {
color: 'rgba(153,194,98, 0.8)'
}
}
}, { // Average
from: 50,
to: 70,
color: 'rgba(248,211,71, 0.5)',
label: {
// text: 'Average',
style: {
color: 'rgba(153,194,98, 0.8)'
}
}
}, { // Above Avg.
from: 70,
to: 100,
color: 'rgba(153,194,98, 0.5)',
label: {
text: 'Above Average',
style: {
color: 'rgba(153,194,98, 0.8)'
}
}
}]
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series: [{
type: 'column',
name: 'Status 5',
color: '#86C9F2',
borderWidth: 0,
shadow: true,
data: [<?php echo $data7a5?>]
}, {
type: 'column',
name: 'Status 4',
color: '#6FB2DB',
borderWidth: 0,
shadow: true,
data: [<?php echo $data7a4?>]
}, {
type: 'column',
name: 'Status 3',
color: '#589BC4',
borderWidth: 0,
shadow: true,
data: [<?php echo $data7a3?>]
}, {
type: 'column',
name: 'Status 2',
color: '#4184AD',
borderWidth: 0,
shadow: true,
data: [<?php echo $data7a2?>]
}, {
type: 'column',
name: 'At the Desk',
color: '#2B6E97', //rgb(43, 110, 151)
borderWidth: 0,
shadow: true,
data: [<?php echo $data7a?>]
}],
drilldown: {
drillUpButton: {
//relativeTo: 'spacingBox',
position: {
y: 10,
x: -10
},
theme: {
fill: 'white',
stroke: 'silver',
r: 2,
states: {
hover: {
fill: '#41739D',
style: {
color: 'white'
}
}
}
}
},
series: [{
type: 'column',
id: 'D2',
data: [['8', 13.77],['8', 2.74],['8', 1.27],['8', 2.64],['8', 2.28],['9', 29.30],['9', 6.44],['9', 3.79],['9', 5.11],['9', 5.32],['10', 36.41],['10', 9.01],['10', 5.47],['10', 7.11],['10', 7.06],['11', 34.12],['11', 7.50],['11', 4.48],['11', 10.02],['11', 8.28],['12', 26.82],['12', 5.03],['12', 5.79],['12', 15.00],['12', 10.27],['13', 30.08],['13', 5.40],['13', 5.34],['13', 11.73],['13', 9.57],['14', 33.90],['14', 7.75],['14', 4.78],['14', 6.41],['14', 9.33],['15', 33.27],['15', 7.73],['15', 4.95],['15', 8.11],['15', 7.09],['16', 31.29],['16', 8.53],['16', 4.51],['16', 6.44],['16', 5.81],['17', 17.36],['17', 3.87],['17', 2.06],['17', 4.47],['17', 3.42],['18', 4.79],['18', .38],['18', .79],['18', 1.44],['18', 2.45]]
}, {
type: 'area',
id: 'D3',
data: [<?php echo $data7b2?>]
}, {
type: 'area',
id: 'D4',
data: [<?php echo $data7b3?>]
}, {
type: 'area',
id: 'D5',
data: [<?php echo $data7b4?>]
}, {
type: 'area',
id: 'D6',
data: [<?php echo $data7b5?>]
}]
}
});
});
I've shown the first drilldown data so you can see the structure. Any help would be appreciated.
Thanks
Rob
You can change the type of drill-down data from ['time', data] to [time, data]:
data: [
['8', 13.77],
['8', 2.74],
['8', 1.27],
['8', 2.64],
['8', 2.28],
['9', 29.30],
['9', 6.44],
['9', 3.79],
['9', 5.11],
['9', 5.32],
...
]
to:
data: [
[8, 13.77],
[8, 2.74],
[8, 1.27],
[8, 2.64],
[8, 2.28],
[9, 29.30],
[9, 6.44],
[9, 3.79],
[9, 5.11],
[9, 5.32],
...
]
And I also changed the tooltip.formatter to show the correct tooltip for drill-downs. Here's the DEMO