Loading Laravel Chart consoletvs/charts:7.* - javascript

I am new to laravel charts.I thought following the documentation to make a sample chart will be a stepping stone. Having followed the documentation form adding the package into my project using composer require consoletvs/charts:7.* and publishing the configuration file by running php artisan vendor:publish --tag=charts and then creating a new chart with the command: php artisan make:chart SampleChart a SampleChart was made under App\Chart
In the SampleChart class i made the following chart configuration
public ?string $name = 'SampleChart';
public ?string $routeName = 'SampleChart';
public ?array $middlewares = ['auth'];
I then manually register using the App\Providers\AppServiceProvider with the code as stated from the documentation
public function boot(Charts $charts)
{
$charts->register([
\App\Charts\SampleChart::class
]);
}
On rendering the chart in my views; I put in the following code
<div id="chart" style="height: 300px;"> </div>
<!-- Charting library -->
<script src="{{ asset('js/Chart.min.js') }}"></script>//downloaded from https://unpkg.com/echarts/dist/echarts.min.js
<!-- Chartisan -->
<script src="{{ asset('js/chartisan_chartjs.js') }}">
</script> //downloaded from https://unpkg.com/#chartisan/echarts/dist/chartisan_echarts.js
<!-- Your application script -->
<script>
const chart = new Chartisan({
el: '#chart',
url: "#chart('SampleChart')",
loader: {
color: '#222',
size: [30, 30],
type: 'bar',
textColor: '#000',
text: 'Loading some chart data...',
},
});
</script>
the output is a flex item with a caption "Loading some chart data... " and nothing shows. Am Stucked
I used the tutorial form https://dev.to/arielmejiadev/use-laravel-charts-in-laravel-5bbm and https://izwebtechnologies.com/2019/06/03/how-to-create-charts-in-laravel/ but none was able to made me accomplish having a chart. though the two tutorial links are for chart6.* i later read the two have different approaches to chart design.
I am Usning Laravel7 and charts:7.*

i am the author.
Some of the issues may be releated to laravel charts, and others to chartisan. I am doing my best to keep everybody happy here but seems people are not happy with the docs.
I am creating an example page with all sorts of examples on chartisan's page.
Remember laravel charts now only acts as a wrapper around chartisan's php package.
Its such a big project for a single person and i like to see constructive feedback.
What exacly isn't clear from the chartisan docs?

try to run without public ?array $middlewares = ['auth']; set.
just public ?array $middlewares = [];
^^^^^^^^^^ this is how I used with Laravel package ^^^^^^^^^^
vvvvvvvvvvvvvvvvvvvv This is how I use now vvvvvvvvvvvvvvvvvvvv
After some time using the ConsoleTV/Charts I decided not to use it like Laravel package.
I get rid of any use of it and use the javascript version only.
To get the data I did this:
Create a controller named whatever you want and put a function like this:
public function chartSample1()
{
$data = array(
"chart" => array(
"labels" => ["First", "Second", "Third"]
),
"datasets" => array(
array("name" => "Sample 1", "values" => array(10, 3, 7)),
array("name" => "Sample 2", "values" => array(1, 6, 2)),
)
);
return $data;
}
On the "routes/web.php" added:
Route::get('/chartSample1', 'MyChartController#chartSample1')->name('chartSample1');
And on the page:
#extends('layouts.app')
#section('content')
<div class="row justify-content-center">
<div class="col-sm-12 align-self-center">
<div class="row">
<div class="col-lg-3">
<div class="card shadow p-3 mb-5 bg-white rounded">
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<div id="chart" style="height: 300px;"></div>
Go somewhere
</div>
</div>
</div>
<div class="col-lg-3">
<div class="card shadow p-3 mb-5 bg-white rounded">
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<div id="chart2" style="height: 300px;"></div>
Go somewhere
</div>
</div>
</div>
<div class="col-lg-3">
<div class="card shadow p-3 mb-5 bg-white rounded">
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<div id="chart3" style="height: 300px;"></div>
Go somewhere
</div>
</div>
</div>
<div class="col-lg-3">
<div class="card shadow p-3 mb-5 bg-white rounded">
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
Go somewhere
</div>
</div>
</div>
</div>
</div>
</div>
{{-- This script has more features --}}
<script src="https://unpkg.com/chart.js/dist/Chart.min.js"></script>
<script src="https://unpkg.com/#chartisan/chartjs/dist/chartisan_chartjs.js"></script>
{{--
<script src="https://unpkg.com/echarts/dist/echarts.min.js"></script>
<script src="https://unpkg.com/#chartisan/echarts/dist/chartisan_echarts.js"></script>
--}}
</script>
<script>
const chart = new Chartisan({
el: '#chart',
url: "{{ route('chartSample1') }}",
hooks: new ChartisanHooks()
.colors(['#ECC94B', '#4299E1'])
.legend()
loader: {
color: '#ff00ff',
size: [30, 30],
type: 'bar',
textColor: '#11ff00',
text: 'Loading some chart data...',
}
});
const chart2 = new Chartisan({
el: '#chart2',
data: {
chart: { "labels": ["First", "Second", "Third"] },
datasets: [
{ "name": "Sample 1", "values": [10, 3, 7] },
{ "name": "Sample 2", "values": [5, 6, 2] }
],
},
hooks: new ChartisanHooks()
.colors(['#ECC94B', '#4299E1', '#AAEE11'])
.legend({ position: 'left' })
.beginAtZero()
.datasets([{ type: 'line', fill: false }, 'bar']),
});
const chart3 = new Chartisan({
el: '#chart3',
data: {
chart: { "labels": ["First", "Second", "Third"] },
datasets: [
{ "name": "Sample 1", "values": [10, 3, 7] },
],
},
hooks: new ChartisanHooks()
.colors(['#ECC94B', '#4299E1', '#AAEE11'])
.datasets([{ type: 'pie', fill: true }, 'pie']),
});
</script>

I had a similar problem and I've been able to solve it. The configuration in your chart class is not compulsory. You can choose to ignore them.
Your render url is also wrong. It is supposed to be in snake case:
//SampleChart will be
#chart('sample_chart')
//PostData will be
#chart('post_data')
If you specified the route in your Chart class, you will have to use that: #chart('your_route'). If you don't know your route, use the php artisan route:list -c command to check.
If you want to specify the type of chart, you have to use hooks.
I ran into a bit of an issue myself. Everything Works for line chart and bar chart, but i can't present a pie chart. The Doughnut is also not working.

Related

Defining shorthand object props on Vue 3

I'm creating a Vue component library, and I'm having some issues defining properties.
Right now, on a component I have the following setup:
<a-div
:classes="{ default: '', sm: '', md: '' }"
:colors="{ dark: '', light: '' }"
></a-div>
Where you define classes depending on the viewport, and colors depending on the current theme.
This is working fine, but I was wondering if there is an easier way (more developer friendly) to define object props. Something like this:
<a-div
classes.default="'col-12'"
classes.md="'col-6'"
classes.lg="'col-2'"
colors.dark="'white'"
colors.light="'black'"
></a-div>
Or perhaps some way of customize props so that the component accepts any prop that the developer previously defined. Something like this:
<a-div
dark="white"
light="black"
randomTheme="green"
></a-div>
My suggestion is to pass whole object as :classes and :colors to the child component instead of passing as a separate property for each color and layout and I think you are already doing that correctly.
Live Demo :
Vue.component('aDiv', {
props: ['classes', 'colors'],
template: `<div class="container">
<div class="row">
<div :class="classes.sm" :style="{'color': colors.dark}">
<p>
This is a rectangle box using col-sm-4
</p>
</div>
<div :class="classes.sm" :style="{'color': colors.light}">
<p>
This is a rectangle box using col-sm-4
</p>
</div>
<div :class="classes.sm" :style="{'color': colors.dark}">
<p>
This is a rectangle box using col-sm-4
</p>
</div>
</div>
</div>`
});
var app = new Vue({
el: '#app',
data: {
layoutClasses: {
default: 'col-lg-12',
md: 'col-md-6',
sm: 'col-sm-4'
},
colors: {
dark: 'gray',
light: 'green'
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css"/>
<div id="app">
<a-div
:classes="layoutClasses"
:colors="colors">
</a-div>
</div>

How to show and hide the data when the condition is true

In my angular application I have created the dashboard page. In that page I have created some conditions based on the condition it has to show on the view if the condition is false it will remove from the view page.
Dashboard.component.ts
var insidecirclespace1 = (lat,long) => {
for (var i=0; i< this.sensors.length;i++){
if (getDistanceFromLatLonInKm(this.sensors[i].latitude, this.sensors[i].longitude, lat,long) <= 5.0) {
circlemark[i].setStyle({ color: 'red', weight: 1, opacity: 7.0 });
"model": "1001",
"sensorname": "Sensor 1",
"rf": "1",
"Idref": "1"
});
}
}
outsidespace(latlngs[latlngidx1].lat,latlngs[latlngidx1].lon,latlngs02[latlngidx2].lat,latlngs02[latlngidx2].lon);
}
var insidecirclespace2 = (lat,long) => {
for (var i=0; i< this.sensors.length;i++){
if (getDistanceFromLatLonInKm(this.sensors[i].latitude, this.sensors[i].longitude, lat,long) <= 5.0) {
circlemark[i].setStyle({ color: 'red', weight: 1, opacity: 7.0 });
this.wifiDrones.push({
"model": "1002",
"sensorname": "Sensor 2",
"rf": "1",
"Idref": "1"
});
}
}
outsidespace(latlngs[latlngidx1].lat,latlngs[latlngidx1].lon,latlngs02[latlngidx2].lat,latlngs02[latlngidx2].lon);
}
var outsidespace = (lat1,long1,lat2,long2)=>{
for (var i=0; i< this.sensors.length;i++){
if (getDistanceFromLatLonInKm(this.sensors[i].latitude, this.sensors[i].longitude, lat1,long1) > 5.0 && getDistanceFromLatLonInKm(this.sensors[i].latitude, this.sensors[i].longitude, lat2,long2) > 5.0) {
circlemark[i].setStyle({ color: 'blue', weight: 1, opacity: 7.0 });
}
}
}
Based on the above condition the html page will show as
.component.html
<div class="col-sm-4">
<div class="card-body">
<h5 class="card-text " style="color: white;"> {{x.model}}
</h5>
<!--some code -->
</div>
</div>
Now my requirement is if the getdistanceInKm is less than 5 km It has to show the data on html page view if the distance is more than 5 km it has to remove (It will continuous for moving marker <5km or >5km)
It is coming for <5km for removing in >5km is not working can anyone please help me regarding this.
Using *ngIf will do the trick, you can use by providing your function inside the *ngIf or any property as follows:
using a propery:
in your ts file you could create a property for e.g. distance:
distance: number = 0;
and update your distance propery in your functions and using binding you could show and hide your HTML element as follows:
<div class="col-sm-4" *ngIf="distance < 5">
<div class="card-body">
<h5 class="card-text " style="color: white;"> {{x.model}}
</h5>
<!--some code -->
</div>
</div>
using a function, if the getdistanceInKm function will return a number this will do the job also:
<div class="col-sm-4" *ngIf="getdistanceInKm()< 5">
<div class="card-body">
<!--some code -->
</div>
</div>
Updated
Also you can use ViewChild as follows for changing the HTML element from ts file:
HTML file:
<div #distanceElement class="col-sm-4">
<div class="card-body">
<!--some code -->
</div>
</div>
ts file:
#ViewChild('distanceElement ') el:ElementRef;
and when changes occurs you can use:
this.el.nativeElement.style.display='none';
HTML
<div *ngIf="validation()">
<h5 class="card-text " style="color: white;"> {{x.model}}</h5>
</div>
.TS
validation() {
// logic if less than 5 km return
return true;
}
P.s This is just an overview, the syntax or the approach may not be perfect

How vue know which image to display and being reactive from method

Recently I have signed up for VueMstery and I am lost. In order to understand code I have a habit of visualizing code and can't move if I cannot make sense of code. What I do not understand in the following code is
how function named updateProduct is updating the DOM with the passed in image and
how it know which image to display. (this point confuses me a lot)
Following is the code
<body>
<div class="nav-bar"></div>
<div id="app">
<div class="product">
<div class="product-image">
<img :src="image" alt="">
</div>
<div class="product-info">
<h1>{{products}}</h1>
<p v-if='inStock'>In Stock</p>
<p v-else>Out of stock</p>
<p v-if='inventory <= 10'>Low on stock</p>
<ul>
<li v-for='detail in details'>{{detail}}</li>
</ul>
<div v-for='variant in variants'
class='color-box'
:style="{backgroundColor: variant.variantColor}"
#mouseover='updateProduct(variant.variantImage)'>
</div>
cart {{cart}}
<button #click='addToCart'>
Add to cart
</button>
</div>
</div>
</div>
<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="main.js"></script>
and main.js
var app = new Vue({
el: '#app',
data: {
products: 'socks',
image: './assets/vmSocks-green.jpg',
inStock: true,
inventory: 10,
details: ["80% cotton", "20% polyester", "Gender-Neutral"],
variants: [
{
variantId: 2234,
variantColor: "green",
variantImage: "./assets/vmSocks-green.jpg"
},
{
variantId: 2235,
variantColor: "blue",
variantImage: "./assets/vmSocks-blue.jpg"
},
],
cart: 0
},
methods: {
addToCart: function(){
this.cart +=1
},
updateProduct: function(image){
this.image = image;
}
}
})
Look at the event handler which you've registered in the template:
#mouseover='updateProduct(variant.variantImage)'
Vue will run the function automatically when events fire. The function updateProduct just updates the value image in your data object. Vue detects any changes for that data and updates DOM when nessesary.
Also because your img tag depends on image property of data object:
<img :src="image" alt="">
you will see that image changes.

Automated id increment for bootstrap collapse component

Bootstrap's Collapse components require sections (or cards) with unique id to enable collapsing / decollapsing each section independently. I am trying to create multiple sections equal to the amount of data points using "v-for" from vue.js. However, I don't know how to automatically generate unique ids for the cards. this is what I tried:
<div id = "story-content" class="content">
<div v-for="(subchapter, chapter) in story" class="card">
<div class="card-header">
<a href = "'collapse' + generateNewId" class="card-link" data-toggle="collapse" >
[[chapter]]
</a>
</div>
<div id = "'collapse' + getCurrentId" class="collapse show" data-parent="#story-content" >
<div class="card-body">
[[subchapter]]
</div>
</div>
</div>
</div>
<script>
var story = {{story | safe}};
var app = new Vue({
delimiters: [ '[[', ']]'],
el: '#portofolio',
data: {
story: story,
uniqueId: 0,
},
methods: {
generateNewId: function() {
return uniqueId + 1;
},
getCurrentId: function() {
return uniqueId;
}
}
})
</script>
Example of the story data structure:
{
"Chapter1": {
"Subchapter1": {
"side_note": "January - June 2019",
"desc": "description here"
},
"Subchapter2": {
"side_note": "January - June 2019",
"desc": "description here"
}
},
"Chapter2": {
"Subchapter1": {
"side_note": "",
"desc": ""
}
}
}
P.S I am not using bootstrap-vue since I did not know its existence until in the middle of my learning. I'm a beginner in web development. Hopefully there is a way to solve this issue without the need of bootstrap-vue as I will need to modify other components as well.
Bootstrap 4 uses jQuery for the Collapse component. So, one way to solve it is to simply use the Chapter keys as the unique id's...
<div id="story-content" class="content">
<div v-for="(subchapter, chapter) in story" class="card">
<div class="card-header">
<a :href="'#collapse' + chapter" :data-target="'#collapse' + chapter" class="card-link"
data-toggle="collapse"> [[chapter]] </a>
</div>
<div :id="'collapse' + chapter"
class="collapse show" data-parent="#story-content">
<div class="card-body"> [[subchapter]] </div>
</div>
</div>
</div>
Demo: https://codeply.com/p/0DEYVY4HUA
However, using jQuery with Vue isn't desirable, so a better way would be to recreate the collapse behavior in Vue as explained here

how to filter post by title using Vue js 2.x directives instead of vue js 1.x

I am learning to use vue js with wprest api by following watch-learn tutorials on the same topic. the problem is that the vue js version used in the tutorial seems to be v 1.x and i started using vue js 2.x. I was able to figure out the initial stages on how to display all the post using vue js 2.x.. I have an input field using which I search for a specific title it should filter and show the post. The issue is unable to workout exactly how it needs to be computed using vuejs 2.x.. I have included a codepen link containing the json data as well as my working code.
the following is the input field to be used to filter the posts by title
<div class="row">
<h4>Filter by name:</h4>
<input type="text" name="" v-model="nameFilter">
</div>
<div class="row">
<div class="col-md-4" v-for="post in posts">
<div class="card post">
<img class="card-img-top" v-bind:src="post.fi_300x180" >
<div class="card-body">
<h2 class="card-text">{{ post.title.rendered }}</h2>
<small class="tags" v-for="category in post.cats">{{ category.name }}</small>
</div>
</div> <!-- .post -->
</div> <!-- .col-md-4 -->
</div> <!-- .row -->
https://codepen.io/dhivyasolomon/pen/LdZKJY
I would appreciate any help in figuring out the next step. thanks.
You don't need directives, achieve this using the power of Computed properties
So you will have to itarate over the computed property which filter the posts by the input value and return a new array of posts.
Little example:
new Vue({
el: '#example',
computed: {
filteredPosts () {
return this.posts.filter(p => p.title.toLowerCase().includes(this.filterText.toLowerCase()))
}
},
data () {
return {
filterText: '',
posts: [
{
title: 'My first post title',
body: 'foo'
},
{
title: 'Another post title',
body: 'foo'
},
{
title: 'This will work fine',
body: 'foo'
},
{
title: 'Omg it\'s working!',
body: 'foo'
}
]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.15/vue.js"></script>
<div id="example">
<input type="text" v-model="filterText" />
<ul>
<li v-for="post in filteredPosts">{{ post.title }}</li>
</ul>
</div>

Categories