I'm using ChartJs.Blazor for chart.js implementation with Blazor.
However, I'm unable to get it working fully due to the following lines
private PieConfig _config;
Options = new PieOptions
PieDataset<int> dataset = new PieDataset<int>(new[] { 6, 5, 3, 7 })
All with the error of
the type or namespace could not be found
Index.Razor
#page "/"
#code{
private PieConfig _config;
protected override void OnInitialized()
{
_config = new PieConfig
{
Options = new PieOptions
{
Responsive = true,
Title = new OptionsTitle
{
Display = true,
Text = "ChartJs.Blazor Pie Chart"
}
}
};
foreach (string color in new[] { "Red", "Yellow", "Green", "Blue" })
{
_config.Data.Labels.Add(color);
}
PieDataset<int> dataset = new PieDataset<int>(new[] { 6, 5, 3, 7 })
{
BackgroundColor = new[]
{
ColorUtil.ColorHexString(255, 99, 132), // Slice 1 aka "Red"
ColorUtil.ColorHexString(255, 205, 86), // Slice 2 aka "Yellow"
ColorUtil.ColorHexString(75, 192, 192), // Slice 3 aka "Green"
ColorUtil.ColorHexString(54, 162, 235), // Slice 4 aka "Blue"
}
};
_config.Data.Datasets.Add(dataset);
}
}
<h1>Ferrari Price</h1>
<div class="container">
<div class="col-12">
<Chart Config="_config"></Chart>
</div>
</div>
_Imports.Razor
#using System.Net.Http
#using Microsoft.AspNetCore.Authorization
#using Microsoft.AspNetCore.Components.Authorization
#using Microsoft.AspNetCore.Components.Forms
#using Microsoft.AspNetCore.Components.Routing
#using Microsoft.AspNetCore.Components.Web
#using Microsoft.JSInterop
#using CryptoPlatform
#using CryptoPlatform.Shared
#using ChartJs.Blazor
#using ChartJs.Blazor.Common
#using ChartJs.Blazor.Common.Axes
#using ChartJs.Blazor.Common.Axes.Ticks
#using ChartJs.Blazor.Common.Enums
#using ChartJs.Blazor.Common.Handlers
#using ChartJs.Blazor.Common.Time
#using ChartJs.Blazor.Util
#using ChartJs.Blazor.Interop
Based on the docs, this should be working. Because I'm so inexperienced in Blazor, debugging the issue is near impossible.
It should be noted the following scripts are also implemented on my _Host.cshtml page
<script src="_framework/blazor.server.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.9.4/dist/Chart.min.js"></script>
<script src="_content/ChartJs.Blazor.Fork/ChartJsBlazorInterop.js"></script>
Related
I am trying to remove a single component from an object in gridstack.js using index and keys. Components are created by v-for directive.
I already have the index and key but components.splice(index,1) and grid.removeWidget(key, false); functions don't achieve this as shown in the documentation. What I am i doing wrong.
Thanks
<template>
<div class="right">
<button class="ds" #click="addNewWidget()">Add Widget</button>
//works okay
<button class="ds" #click="deleteWidget()">Clear</button>
</div>
<section class="grid-stack">
<div v-for="(component, key, index) in components" :key="'component' + index" :gs-id="key"
class="grid-stack-item" :gs-x="component.gridPos.x" :gs-y="component.gridPos.y" :gs-h="component.gridPos.h"
:gs-w="component.gridPos.w" gs-auto-position="true">
<div class="grid-stack-item-content">
<component :is="component.name" v-bind="component.props" />
//Uncaught TypeError: Cannot read properties of undefined (reading 'splice')
<button #click="remove(index, key, component)">remove</button>
</div>
</div>
</section>
</template>
<script>
import { ref, onMounted, reactive, nextTick } from 'vue';
import "gridstack/dist/h5/gridstack-dd-native";
import 'gridstack/dist/gridstack.min.css';
import { GridStack } from 'gridstack';
import BarChart from './BarChart.vue';
import PieChart from './PieChart.vue';
import LineChart from './LineChart.vue';
import Widget from './HalfDoughnut.vue';
export default {
name: "Dashboard",
setup() {
let info = ref("");
let grid = null;
let components = reactive({
yourRandomComponent1: {
name: "BarChart", props: {}, gridPos: { x: 0, y: 1, w: 6, h: 7 }
},
yourRandomComponent2: {
name: "PieChart", props: {}, gridPos: { x: 0, y: 1, w: 6, h: 7 }
},
});
onMounted(() => {
grid = GridStack.init({
float: true,
cellHeight: "70px",
minRow: 1,
});
grid.on("dragstop", (event, element) => {
console.log("move event!", event, element);
const node = element.gridstackNode;
info.value = `you just dragged node #${node.id} to ${node.x},${node.y} – good job!`;
});
});
// this will of course only work once because of the object-key
function addNewWidget() {
components.yourRandomComponent3 = {
name: "Widget", props: {}, gridPos: { x: 0, y: 1, w: 6, h: 7 }
};
// we have to wait for vue to update v-for,
// until then the querySelector wont find the element
nextTick(() => {
console.log(grid);
let compEl = document.querySelector('[gs-id="yourRandomComponent3"]');
console.log(compEl);
grid.makeWidget(compEl);
});
console.warn("i will only work once, fix my inputs to reuse me");
}
function remove(index, key) {
console.log(key)
//Uncaught TypeError: Cannot read properties of undefined (reading 'splice')
components.splice(index, 1);
grid.removeWidget(key, false);
}
function deleteWidget(){
grid.removeAll(true);
}
return {
info,
components,
addNewWidget,
deleteWidget,
remove
};
},
components: {
// eslint-disable-next-line vue/no-unused-components
BarChart, PieChart, LineChart, Widget
}
}
</script>
you are declaring components as a reactive which means you don't need to use .value use delete componennts[key] but a regular object
also use const to declare ref, reactive... to avoid errors
I made a dashboard on my website that has 3 different visualization charts, the data is from my database, and the problem that I'm encountering is that the other two are not showing eventhough the first one shows itself. moreover, if I hide or remove the first chart, the second one appears, but the third one still doesn't show. refer to images below:
First Chart Shows the following two are not.
The second chart only shows itself when I delete the code of the first chart.
The 3rd chart is the same case as 2nd, needed to remove the first and second charts just to see the third one.
here is my code:
<!--CHARTS-->
<!--BAR CHART-->
<div class="container-fluid px-4">
<?php
// Attempt select query execution
try{
$barsql = "SELECT * FROM castro_rentals.unit";
$barresult = $pdo->query($barsql);
if($barresult->rowCount() > 0) {
$price = array();
$unit_no = array();
while($row = $barresult->fetch()) {
$price[] = $row["price"];
$unit_no[] = $row["unit_no"];
}
unset($barresult);
} else {
echo "No records matching your query were found.";
}
} catch(PDOException $e){
die("ERROR: Could not able to execute $barsql. " . $e->getMessage());
}
// Close connection
unset($pdo);
?>
<div class="card mb-4">
<!--BAR CHART-->
<div class="card-header">
<i class="fas fa-chart-bar me-1"></i>
Unit Prices
</div>
<div class="card-body">
<canvas id="myBarChart" width="100%" height="50"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
//SETUP BLOCK
const price = <?php echo json_encode($price); ?>;
const unit_no = <?php echo json_encode($unit_no); ?>;
const data = {
labels: unit_no,
datasets: [{
label: 'Price',
data: price,
backgroundColor: ['rgba(57, 43, 90, .6)'],
borderColor:'rgb(57, 43, 90)',
borderWidth: 2
}]
};
//CONFIG BLOCK
const config = {
type: 'bar',
data,
options: {
scales: {
y: {
beginAtZero: true
}
}
}
};
//RENDER BLOCK
const myBarChart = new Chart(
document.getElementById('myBarChart'),
config
);
</script>
<div class="card-footer small text-muted">Updated yesterday at 11:59 PM</div>
</div>
<div class="row">
<div class="col-lg-6">
<!--LINE CHART-->
<?php
include('config/dbcon.php');
// Attempt select query execution
try{
$linesql = "SELECT * FROM castro_rentals.payment";
$lineresult = $pdo->query($linesql);
if($lineresult->rowCount() > 0) {
$amount = array();
$paymentdate = array();
while($row = $lineresult->fetch()) {
$amount[] = $row["amount"];
$paymentdate[] = $row["paymentdate"];
}
unset($lineresult);
} else {
echo "No records matching your query were found.";
}
} catch(PDOException $e){
die("ERROR: Could not able to execute $linesql. " . $e->getMessage());
}
// Close connection
unset($pdo);
?>
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-chart-line me-1"></i>
Monthly Income
</div>
<div class="card-body">
<canvas id="myLineChart" width="100%" height="50"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
//SETUP BLOCK
const amount = <?php echo json_encode($amount); ?>;
const paymentdate = <?php echo json_encode($paymentdate); ?>;
const data = {
labels: paymentdate,
datasets: [{
label: 'Amount',
data: amount,
backgroundColor: ['rgba(57, 43, 90, .6)'],
borderColor:'rgb(57, 43, 90)',
borderWidth: 2
}]
};
//CONFIG BLOCK
const config = {
type: 'line',
data,
options: {
scales: {
y: {
beginAtZero: true
}
}
}
};
//RENDER BLOCK
const myLineChart = new Chart(
document.getElementById('myLineChart'),
config
);
</script>
<div class="card-footer small text-muted">Updated yesterday at 11:59 PM</div>
</div>
</div>
<!--PIE CHART-->
<div class="col-lg-6">
<!--PIE CHART-->
<?php
include('config/dbcon.php');
// Attempt select query execution
try{
$piesql = "SELECT * FROM castro_rentals.property";
$pieresult = $pdo->query($piesql);
if($pieresult->rowCount() > 0) {
$propertyname = array();
$paymentdate = array();
while($row = $pieresult->fetch()) {
$propertyname[] = $row["propertyname"];
$propertytype[] = $row["propertytype"];
}
unset($pieresult);
} else {
echo "No records matching your query were found.";
}
} catch(PDOException $e){
die("ERROR: Could not able to execute $piesql. " . $e->getMessage());
}
// Close connection
unset($pdo);
?>
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-chart-pie me-1"></i>
# of Property Type
</div>
<div class="card-body">
<canvas id="myPieChart" width="100%" height="50"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
//SETUP BLOCK
const propertyname = <?php echo json_encode($propertyname); ?>;
const propertytype = <?php echo json_encode($propertytype); ?>;
const data = {
labels: propertytype,
datasets: [{
label: 'propertyname',
data: propertyname,
backgroundColor: ['rgba(57, 43, 90, .6)'],
borderColor:'rgb(57, 43, 90)',
borderWidth: 2
}]
};
//CONFIG BLOCK
const config = {
type: 'pie',
data,
options: {
scales: {
y: {
beginAtZero: true
}
}
}
};
//RENDER BLOCK
const myPieChart = new Chart(
document.getElementById('myPieChart'),
config
);
</script>
<div class="card-footer small text-muted">Updated yesterday at 11:59 PM</div>
</div>
</div>
</div>
The only thing I tried to do is to play with the <div> before the <canvas> I thought it wouldn't show because of spacing and size problems but I tried modifying, removing, resizing them, it still didn't show.
I am using ember.js and handlebars. I need to pass a string to a component and that string needs to have line breaks. I am struggling trying to get the line breaks to work. I have tried using
\n, \ , + `' + none of these seem to work
Here is my computed property where the string is getting returned:
scoreMessage: Ember.computed(function scoreMessage () {
const model = this.get('model')
return Ember.String.htmlSafe(`Advocacy Post: ${model.total_advocacy_posts_count}\n
Assets Submitted: ${model.total_assets_submitted_count}\n Engagement from asset:
${model.total_engagement_from_assets_count}`);
}),
Here is the handlebars file where the scoreMessage is passed into the ui-tooltip-on-mouseover component
<li class="item-cell flex-end score">
{{#ui-tooltip-on-mouseover
message=scoreMessage
tooltipLocation="top"
class="action"
}}
Score
{{/ui-tooltip-on-mouseover}}
</li>
Hmm, can you try white-space: pre-line; CSS to the tooltip? with this approach, you don't need to specify \n, you just press enter.
i.e.
scoreMessage: Ember.computed(function scoreMessage () {
const model = this.get('model')
return Ember.String.htmlSafe(
`Advocacy Post: ${model.total_advocacy_posts_count}
Assets Submitted: ${model.total_assets_submitted_count}
Engagement from asset: ${model.total_engagement_from_assets_count}`
);
}),
var model = { total_advocacy_posts_count: 3, total_assets_submitted_count: 4, total_engagement_from_assets_count: 7 }
var text = `Advocacy Post: ${model.total_advocacy_posts_count}
Assets Submitted: ${model.total_assets_submitted_count}
Engagement from asset: ${model.total_engagement_from_assets_count}`
window.onload = function() {
document.querySelector('.tooltip.other').innerHTML = text;
}
.tooltip {
white-space: pre-line;
padding: 20px;
}
body {
background: white;
}
<div class="tooltip">
Some
Text that does take
line breaks without specifying them
</div>
<div class="tooltip other"></div>
`
I use HighChart library in the Segment, my segment have 2 tab DASHBOARD and NEW, my Chart in the DASHBOARD tab. First run: My Chart run, but i click to New tab and come back DASHBOARD tab => My chart not run ?
[sorry, i'm not good english]
-- My code html:
<div class="segment-chart">
<ion-segment [(ngModel)]="pet">
<ion-segment-button value="dashboard" (ionSelect)="selectedFriends()">
DASHBOARD
</ion-segment-button>
<ion-segment-button value="new">
NEW
</ion-segment-button>
</ion-segment>
</div>
<div [ngSwitch]="pet">
<div class="chart" *ngSwitchCase="'dashboard'">
<!--View Chart-->
<div #chart>
<chart type="StockChart" [options]="options"></chart>
</div>
</div>
<ul *ngSwitchCase="'new'" style="list-style-type:none" class="div-new-body">
<li class="div-new-li" *ngFor="let new of lsNews">
<div class="div-new-detail">
<div class="div-new-title">
{{new.date}}
</div>
<div class="div-new-content">
{{new.title}}
</div>
</div>
<div class="div-new-nav">></div>
</li>
</ul>
</div>
My code file ts:
export class ChartPage implements AfterViewInit, OnDestroy {
private _chart: any;
lastData: any
lstData: any = []
pet : any
lsNews : any = []
opts : any;
#ViewChild('chart') public chartEl: ElementRef;
//chartOption: any
// Destroy Chart
ngOnDestroy(): void {
// throw new Error("Method not implemented.");
console.log("OnDestroy run")
var chart = this._chart
chart.destroy();
}
// option Chart
ngAfterViewInit() {
if (this.chartEl && this.chartEl.nativeElement) {
this.opts.chart = {
// type: 'area',
renderTo: this.chartEl.nativeElement,
backgroundColor: {
linearGradient: [0, 0, 500, 500],
stops: [
[0, '#3d4d64'],
[1, '#3d4d64']
]
},
height: '90%',
spacingBottom: 15,
spacingTop: 10,
spacingLeft: 10,
spacingRight: 10,
};
console.log('chart create ss')
this._chart = new Highcharts.StockChart(this.opts);
}
}
constructor(public navCtrl: NavController, public navParams: NavParams, public service: Service) {
const me = this;
this.pet= 'dashboard';
setInterval(function () {
if (me._chart) {
me._chart['series'][0].addPoint([
(new Date()).getTime(), // gia tri truc x
//5// gia tri truc y
me.getData()
],
true,
true);
}
}, 3000);
this.opts = {
credits: {
enabled: false
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150,
labels: {
style: {
color: '#705f43' // color time
}
},
lineColor: '#705f43' // 2 line cuoi mau trang
},
yAxis: {
gridLineColor: '#705f43', //line gach ngang
labels: {
style: {
color: '#fff'
}
},
lineColor: '#ff0000',
minorGridLineColor: '#ff0000',
tickColor: '#fff',
tickWidth: 1,
title: {
style: {
color: '#ff0000'
}
}
},
navigator: {
enabled: false
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 0,
},
series: [{
name: 'Random data',
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -50; i <= 0; i += 1) {
data.push([
time + i * 1000,
Math.round(Math.random() * 100)
]);
}
return data;
}()),
zones: [{
color: '#f8ad40'
}]
}]
};
//end contructor
}
In case you have not been able to resolve this issue, I had the same issue using ion-segment and I was able to resolve it when I replaced ngSwitch with the [hidden] property.
The problem is that the canvas only get rendered once. The canvas is also lost once you switch between your segments, the only solution is to hide you segment when switching between segments
Edit your HTML code to the one below and you should be okay
<div class="segment-chart">
<ion-segment [(ngModel)]="pet">
<ion-segment-button value="dashboard" (ionSelect)="selectedFriends()">
DASHBOARD
</ion-segment-button>
<ion-segment-button value="new">
NEW
</ion-segment-button>
</ion-segment>
</div>
<div >
<div class="chart" [hidden] = "pet != 'dashboard'">
<!--View Chart-->
<div #chart>
<chart type="StockChart" [options]="options"></chart>
</div>
</div>
<ul [hidden] = "pet != 'new'" style="list-style-type:none" class="div-new-body">
<li class="div-new-li" *ngFor="let new of lsNews">
<div class="div-new-detail">
<div class="div-new-title">
{{new.date}}
</div>
<div class="div-new-content">
{{new.title}}
</div>
</div>
<div class="div-new-nav">></div>
</li>
</ul>
</div>
That should solve the issue.
How do I vertically align label in google chart say on y or r axis?
Yes, vertical Align is possible now.
You can do them by
var options = {
title: "Test",
hAxis: {
direction:-1,
slantedText:true,
slantedTextAngle:90 // here you can even use 180
}
};
I am adding full codes for testing
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChartModeldaily);
function drawChartModeldaily() {
var data = google.visualization.arrayToDataTable(
[
['daily', 'Views', 'Likes'],
['Tue', 4, 19],
['Mon', 22, 16],
['Sat', 3, 1],
['Fri', 15, 34],
['Thu', 27, 44],
['Wed', 17, 23],
]
);
var options = {
title: "Test",
hAxis: {
direction:-1,
slantedText:true,
slantedTextAngle:90
}
};
var chart = new google.visualization.LineChart(document.getElementById("chart_div_daily"));
chart.draw(data, options);
}
</script>
<div id="chart_div_daily" style="width: 900px; height: 500px;"></div>
I am working with latest Google Chart. Please check them at https://developers.google.com/chart/
There is a question already asking this - Vertical labels with google charts API? - but it seems that no, you cannot put vertical labels on the charts yet.