here's the code:
HTML
<div echarts [options]="alertsToday$ | async" (chartInit)="onChartInit(todayCharts.line, $event)"
[theme]="(darkMode$ | async) ? 'dark' : 'default'" style="max-height: 200px;"></div>
TS
todayOptions = chartOptions.today;
todayCharts: any = {
line: { options: _.cloneDeep(this.todayOptions) }
};
constructor(private report: ReportService){}
onChartInit(chart: object, instance: any) {
chart['instance'] = instance;
this.todayCharts.line['instance'].setOption(this.todayCharts.line.options);
}
getReports() {
this.report.getStatusReports();
this.report.alertsToday$.subscribe((data) => {
this.alertsToday$.next(data);
if (this.todayCharts.line['instance']) {
this.todayCharts.line['instance'].setOption(data);
}
}
SERVICE.TS
getStatusReports() {
const severities = ['LOW', 'MEDIUM', 'HIGH', 'URGENT'];
const reportModules = [
{ url: '', params: { to: format(TODAY, DATE_FORMAT).toString(), from: format(TODAY, DATE_FORMAT).toString() } },
{
url: 'application-and-severity',
params: { to: format(TODAY, DATE_FORMAT).toString(), from: format(TODAY, DATE_FORMAT).toString() }
},
{
url: 'application-and-severity-and-date',
params: {
to: format(endOfWeek(TODAY), DATE_FORMAT).toString(),
from: format(startOfWeek(TODAY), DATE_FORMAT).toString()
}
},
{
url: 'application-and-status',
params: {
to: format(endOfWeek(TODAY), DATE_FORMAT).toString(),
from: format(startOfWeek(TODAY), DATE_FORMAT).toString()
}
}
];
const promises = reportModules.map(
target =>
new Promise(resolve => {
this.notificationService
.getSummary(target.url, target.params)
.pipe(take(1))
.subscribe(
(result: Response) => {
// console.log(target, result);
resolve({ target, result });
},
(err: Error) => {
// return reject(err);
}
);
})
);
Promise.all(promises).then(results => {
const options = chartOptions;
options.default.today.series[0].itemStyle.normal.label.formatter = function (params: any) { return params.value + '%\n'; };
const week = this.getWeek();
// console.log(options.default);
results.forEach((res: any) => {
if (res.target.url !== '') {
if (res.target.url === 'application-and-severity') {
const todaySummary = { total: 0, data: [] as any };
const groups = _.groupBy(res.result, (data: any) => data.severity);
severities.forEach(severity => {
const total = groups[severity]
? groups[severity].reduce((prev, curr) => ({ total: prev.total + curr.total }))
: {
total: 0
};
todaySummary.data.push({
name: severity,
value: total.total
});
todaySummary.total += total.total;
});
options.default.today.title.text = todaySummary.total;
options.default.today.series[0].data = todaySummary.data;
// this.loading.today = false;
return this.alertsToday$.next(options.default.today);
}
}
});
});
}
What I'm trying to do here is to update the charts of alertsToday. but when I try to use the setOption it doesn't work and I used the onChartInit().
first the data is displaying, but when there's a new update it doesn't reload/refresh or update the chart.
how to update the echarts? cause it load the first data then when I update the data it doesn't update the echarts it still the same.
I have chart.component.html and chart.component.ts and report.service also the acknowledge.component.ts
Related
I have two components: Index and Create. Both of these components are loaded from different blade files. The problem is I cannot pass flash message as a prop since these are in different files. How to redirect after a submitted form has been created and and receive the flash message in component Index from Create?
public function store(Request $request)
{
Service::create([
'name' => $request->get('name'),
'vendor_id' => $request->get('vendor'),
'desc' => $request->get('desc'),
'hours' => $request->get('hours'),
'price_per_hour' => $request->get('price'),
'fixed_price' => $request->get('fixed_price'),
'user_id' => $request->user()->id
]);
if (\request()->wantsJson()) {
return response()->json([
'alert_store' => 'New service added successfully.'
]);
}
}
Create component:
if(ok) {
axios.get('/sanctum/csrf-cookie').then(response => {
axios.post('/api/services', {
name: this.form.name,
vendor: this.form.vendor,
desc: this.form.desc,
hours: this.form.hours,
price: this.form.price,
fixed_price: this.form.fixed_price,
})
.then(response => {
this.alert_store = response.data.alert_store
alert(this.alert_store)
window.location.href = '/admin/services';
})
.catch(function (error) {
console.log(error);
});
});
}
},
index.vue:
import Create from './Create.vue';
import Alert from '../Alert.vue';
export default {
props: ['alert_store'],
components: {
Create,
Alert,
},
data(){
return {
services: [],
alert_success: '',
alert_error: '',
errors: [],
success: [],
form: {
name: '',
desc: '',
hours: '',
price_per_hour: '',
vendor: '',
fixed_price: '',
},
selected: null,
}
},
mounted() {
this.loadServices()
this.getStatus()
},
methods: {
loadServices: function(){
axios.get('/api/getservicedata')
.then(response => {
this.services = response.data;
})
.catch(function(error){
console.log(error);
});
},
// getStatus(){
// axios
// .post('/api/services')
// .then(response => {
// console.log(response.data.alert_store)
// });
// },
isEditable(service)
{
this.form.name = service.name
this.form.desc = service.desc
this.form.hours = service.hours
this.form.price_per_hour = service.price_per_hour
this.form.vendor = service.vendor.id
this.form.fixed_price = service.fixed_price
if(service.isEditing)
{
this.selected = service.id
service.isEditable = false
}
this.$set(service, 'isEditing', true)
},
editService(service)
{
if(confirm('Are you sure?'))
{
axios.post(`/api/services/${service.id}`, {
_method: 'patch',
name: this.form.name,
vendor: this.form.vendor,
desc: this.form.desc,
hours: this.form.hours,
price_per_hour: this.form.price_per_hour,
vendor: this.form.vendor,
fixed_price: this.form.fixed_price
})
.then(response => {
this.alert_success = response.data.alert_update
this.success.push(Alert)
this.loadServices()
})
.catch(response => {
this.errors.push(Alert)
this.alert_error = `Could not edit, ${service.name}, from services!`
})
}
},
deleteService(service)
{
if(confirm('Are you sure?'))
{
axios.get('/sanctum/csrf-cookie').then(response => {
axios.delete(`/api/services/${service.id}`, {
__method: 'DELETE'
})
.then(response => {
this.alert_success = response.data.alert_delete
this.success.push(Alert)
this.loadServices()
})
.catch(response => {
this.errors.push(Alert)
this.alert_error = `Could not delete, ${service.name}, from services!`
})
});
}
}
}
}
You could pass props into index.vue component with different ways.
First and properly (on my mind) way is to use session data.
Like:
public function store(Request $request)
{
Service::create([
'name' => $request->get('name'),
'vendor_id' => $request->get('vendor'),
'desc' => $request->get('desc'),
'hours' => $request->get('hours'),
'price_per_hour' => $request->get('price'),
'fixed_price' => $request->get('fixed_price'),
'user_id' => $request->user()->id
]);
\request()->session()->put('yourawesomekey','value');
if (\request()->wantsJson()) {
return response()->json([
'alert_store' => 'New service added successfully.'
]);
}
}
And when you initialize your component in blade file:
...
<your-component-name alert_store="{{ session('yourawesomekey', 'default-value') }}" />
...
NOTE Don't forgot to cleanup session data \request()->session()->forget('yourawesomekey');
Hope it will work for you.
home.component.ts
<h1>{{ (reportsToday$ | async)}}</h1>
<div echarts [options]="alertsDaily$ | async">
<div echarts [options]="alertsToday$ | async">
<div [onDisplay]="alertsDaily$ | async">
report.component.ts
constructor(private report: ReportService) {}
getReports() {
this.report.getStatusReport();
}
report.service.ts
displayAlert$ = new BehaviorSubject(undefined);
reportsToday$ = new BehaviorSubject(undefined);
alertsToday$ = new BehaviorSubject(undefined);
alertsDaily$ = new BehaviorSubject(undefined);
constructor() {}
getStatusReport() {
loading = {
today: false,
daily: false
};
this.loading.today = true;
this.loading.daily = true;
const severities = ['LOW', 'MEDIUM', 'HIGH', 'URGENT'];
const reportModules = [
{ url: '', params: { to: format(TODAY, DATE_FORMAT).toString(), from: format(TODAY, DATE_FORMAT).toString() } },
{
url: 'application1',
params: { to: format(TODAY, DATE_FORMAT).toString(), from: format(TODAY, DATE_FORMAT).toString() }
},
{
url: 'application2',
params: {
to: format(endOfWeek(TODAY), DATE_FORMAT).toString(),
from: format(startOfWeek(TODAY), DATE_FORMAT).toString()
}
},
{
url: 'application3',
params: {
to: format(endOfWeek(TODAY), DATE_FORMAT).toString(),
from: format(startOfWeek(TODAY), DATE_FORMAT).toString()
}
}
];
const promises = applicationModule.map(
target =>
new Promise(resolve => {
this.notificationService
.getSummary(target.url, target.params)
.pipe(take(1))
.subscribe(
(result: Response) =>
resolve({ target, result });
},
(err: Error) => {
// return reject(err);
}
);
})
);
Promise.all(promises).then(results => {
const options = this.preConfig;
const week = this.getWeek();
results.forEach((res: any) => {
....
if (res.target.url !== '') {
if (res.target.url === 'application1') {
....
this.loading.today = false;
this.alertsToday$.next(options.today);
}else {
if (res.target.url === 'application2') {
...
...
this.loading.daily = false;
this.alertsDaily$.next(options.daily);
} else {
....
....
this.loading.daily = false;
this.alertsDaily$.next(options.daily);
}
}
}else {
this.reportsToday$.next(res.result[0]);
}
}
});
}
The problem here is it doesn't display the observable data. When I run the application there's no error, but it doesn't display the data of displayAlert$, reportsToday$, alertsToday$ and alertsDaily$.
I used service it because, I will use it from the other components.
How to get the observable from service and display it on home component?
In component you can't see the variable directly from service. It should be from component itself.
Also you need to subscribe the values you are firing with .next(). Unless you subscribe them , the value won't be set.
I think new BehaviorSubject(undefined); is causing the problem.
Can you initialize like new BehaviorSubject([]); or if it is string then new BehaviorSubject(''); and if number then new BehaviorSubject(0);
I am assuming that you have correctly called service from components.
i creating a form with React-selec.
When i do a function and pass parameters he returns me
Expected 1 arguments, but got 0.ts(2554)
index.tsx(31, 31): An argument for 'selectRef' was not provided.
useEffect(() => {
function parseSelectValue(selectRef: { state: { value: any } }) {
const selectValue = selectRef.state.value
if (!multiple) {
return selectValue ? selectValue.id : ''
}
return selectValue
? selectValue.map((option: { id: any }) => option.id)
: []
}
registerField({
name: fieldName,
ref: ref.current as any,
path: 'state.value',
parseValue: parseSelectValue,
clearValue: (selectRef: { select: { clearValue: () => void } }) => {
selectRef.select.clearValue()
}
})
parseSelectValue()
}, [fieldName, registerField, multiple])
The function parseSelectValue expects a selectRef; Its a non-optional parameter.
function parseSelectValue(selectRef?: { state: { value: any } }) {
const selectValue = selectRef ? selectRef.state.value : undefined;
Paste this should fix the problem.
I am using classes to build charts and the thing with this one is: I need to return from the server dynamic labels and data every often. With this code I have accomplished to print on the console results I want for each function separately - array of carNames and array of avgSpeeds, but drawing the chart itself by the function drawSpeedChart has been really painful. Could anyone give me a way to pursue in order to get these printed results to render the chart? Thanks!!!
Here is the function that would supposedly render the chart:
drawSpeedChart() {
this.labels;
this.avgData;
this.getAvgData()
.then(avgData => {
this.avgData = avgData
console.log(this.avgData)
this.getCarNames()
}).then(carNames => {
this.carNames = carNames
console.log(this.labels)
}).then(this.createChart(this.labels, this.avgData))
}
Both console.log()return undefined for this snippet.
Main functions to return labels and data are respectively getCarNames and getAvgDataand they at least print in console the right result. Problem is to build the chart after that
Here is the full code.
window.onload = () => { new AvgSpeedChart(); }
class AvgSpeedChart {
constructor() {
this.selectElements()
this.drawSpeedChart()
}
selectElements() {
this.speedChartElement = document.querySelector('#speedChart')
}
createChart(carNames, avgData) {
return new Chart(this.speedChartElement, {
type: 'bar',
data: {
labels: carNames,
datasets: [{
label: "Velocidade média",
data: avgData
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
title: {
display: true,
text: 'Velocidade média'
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
legend: {
display: false
}
}
})
}
drawSpeedChart() {
this.labels;
this.avgData;
this.getAvgData()
.then(avgData => {
console.log(this.avgData)
this.getCarNames()
return this.avgData = avgData
}).then(carNames => {
console.log(this.labels)
return this.labels = carNames
}).then(this.createChart(this.labels, this.avgData))
}
getCarNames() {
return axios({
method: 'get',
url: "xxxxxxxxxxx",
auth: {
username: 'xxxxx',
password: 'xxxxx'
}
}).then(response => {
this.carNames = response.data.map(car => car.name)
console.log(this.carNames)
return this.carNames
}).catch(error => {
console.log(error)
})
}
getAvgData() {
return axios({
method: 'get',
url: "xxxxxx",
auth: {
username: 'xxxxx',
password: 'xxxxx'
}
}).then(response => {
this.devicesId = response.data.map(device => device.id)
return this.devicesId
}).then(devicesId => {
this.getAllSpeed(devicesId.map(e => this.getAvgSpeed(e)))
}).catch(error => {
console.log(error)
})
}
getAllSpeed(arr) {
return axios.all(arr)
.then((avgSpeeds) => {
console.log(avgSpeeds)
return avgSpeeds
})
}
getAvgSpeed(deviceId) {
return axios({
method: 'get',
url: "xxxxxxx",
auth: {
username: 'xxxxx',
password: 'xxxxx'
},
params: {
from: '2018-10-09T00:00:00',
to: '2018-10-09T23:59:59',
deviceId: `${deviceId}`
}
}).then(response => {
this.allSpeeds = response.data.map(pos => pos.speed)
let sumSpeed = this.allSpeeds.reduce(this.sumSpeeds, 0)
let numSpeed = this.allSpeeds.length === 0 ? 1 : this.allSpeeds.length
let avgCalc = ((sumSpeed/numSpeed)*1.852)
return avgCalc
}).catch(error => {
console.log(error)
})
}
sumSpeeds(total, sum) {
return total + sum
}
}
The problem with your drawSpeedChart method is that the properties which you are using with this does not exist on your class. I've made them local variables. And you don't need the third then because you already have all the information to call createChart method.
drawSpeedChart() {
let avgData;
this.getAvgData()
.then((avgDataResponse) => {
console.log(avgDataResponse);
avgData = avgDataResponse;
return this.getCarNames();
}).then((carNames) => {
console.log(carNames)
this.createChart(carNames, avgData)
}).catch((err) => {
console.log('Error', err);
})
}
Checkout this fiddle to see working example
i want to bind the json file to a smart table. How to use the loop function for the iteration.. please help
It only shows the design of smart table.
didn't binding the data from json
this is the json file
[
{
"year": 2013,
"id": "",
"doctor": "Dr. Smith",
"illness": "Flu",
"apptdate": "3/12/2013",
"details":"Patient had flu for 5 days. No medicines prescribed"
}
]
i used to retrieve data using
#Injectable()
export class SmartTablesService {
constructor(private http: Http) {
}
smartTableData = [];
loadData() {
console.log('loadData');
this.http.get('http://192.168.0.100:8000/medical')
.subscribe((data) => {
setTimeout(() => {
var contactData = [];
$.each(data.json(), function (key, value) {
var tempData = value.source;
contactData.push(tempData);
});
this.smartTableData = contactData;
}, 1000);
});
}
getData(): Promise<any> {
console.log("Promise");
this.loadData();
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(this.smartTableData);
resolve(this.smartTableData);
}, 3000);
});
}
}
constructor(private http: Http) { }
getComments() {
return this.http.get('http://192.168.0.100:8000/article' )
.map((res: Response) => res.json())
.catch((error:any) => Observable.throw(error));
}
}*/
this is the component part
#Component({
selector: 'new',
template: '<ng2-smart-table [settings]="settings" [source]="source"></ng2-smart-table>'
})
export class NewComponent {
query: string = '';
settings = {
noDataMessage: 'Loading...',
columns: {
year: {
title: 'YEAR',
type: 'string'
},
id: {
title: 'ID',
type: 'string'
},
doctor: {
title: 'DOCTOR',
type: 'string'
},
illness: {
title: 'ILLNESS',
type: 'string'
},
apptdate: {
title: 'APPTDATE',
type: 'string'
},
details: {
title: 'DETAILS',
type: 'string'
}
}
};
// data
source: LocalDataSource = new LocalDataSource();
constructor(protected service: SmartTablesService){
this.service.getData().then((data) => {
this.source.load(data);
});
}
}
please anyone anyone know how to bind it ..help
simply change the subscribe part in the service page to
var tempData = value;
so .subscriber looks like
.subscribe((data) => {
setTimeout(() => {
var contactData = [];
$.each(data.json(), function (key, value) {
var tempData = value; contactData.push(tempData);
});
this.smartTableData = contactData;
}, 1000);
});
}
it works..!