inject a bar chart into a webpage via content script - google-chrome-extension

I am going to inject a bar chart into a webpage according to the data presented on the page.
I created a Chrome extension for this purpose, which used chartjs to draw the bar chart, but didn't work. The following is a sample, so how to fix ?
One can download my extension here.
manifest.json
{
"name": "JsonAnalysis2",
"description": "Json Analysis",
"version": "1.0",
"permissions": [
"https://*/*",
"nativeMessaging",
"tabs"
],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [
{
"all_frames": true,
"matches": ["https://*/*"],
"js": ["chart.js","contentScript.js"]
}
],
"page_action": {
"default_title": "",
"default_icon": "icon.png"
},
"manifest_version": 2
}
contentScript.js
// var jq = document.createElement('script');
// jq.src = "https://cdn.jsdelivr.net/npm/chart.js#2.8.0";
// document.querySelector('head').appendChild(jq);
analysisResult=`
<canvas id="myChart"></canvas>
<script type="text/javascript">
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '购买记录',
data: [12, 19, 3, 5, 2, 3],
// backgroundColor: 'rgb(255, 99, 132)',
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor:'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
</script>
`
document.body.insertAdjacentHTML('afterBegin',analysisResult)

After changed manifest.json to the following , it worked ! One could download the working sample here.
analysisResult=`
<canvas id="myChart"></canvas>
`
document.body.insertAdjacentHTML('afterBegin',analysisResult)
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '购买记录',
data: [12, 19, 3, 5, 2, 3],
// backgroundColor: 'rgb(255, 99, 132)',
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor:'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});

Related

Issue in implementing ChartJS in my new assignment of ReactJS App, please let me know where I am wrong

I want to upload a chart in my react app but when I use this Barchar.jsx component (have used js nothing changed) it is showing following errors in console(are in image.)
import React from "react";
import { Bar, Chart } from "react-chartjs-2";
import {Chart as ChartJS, BarElement } from 'chart.js';
ChartJS.register(BarElement)
const BarChart = () => {
var data = {
labels: ['RCB', 'MI', 'RR', 'SRH', 'CSK', 'KXIP', 'DD', 'DCH', 'GL', 'RPS', 'KKR'],
datasets: [{
label: '# of toss wins',
data: [70, 85, 63, 35, 66, 68, 72, 43, 15, 6, 78],
backgroungColor: ['red', 'lightblue', 'pink', 'orange', 'yellow', 'gold', 'blue', 'black', 'gold', 'voilet', 'purple' ],
borderWidth: 1
}]
};
var options = {
maintainAspectRatio: false,
scales: {
y:{
beginAtZero: true
}
},
};
return (
<div>
<Bar
data= {data}
height={400}
width={600}
options={options}
/>
</div>
)
};
export default BarChart ;
Its because you try to use treeshaking but import and register only the element of the bar while chart.js needs a lot more.
For ease of use you are best of to change
import {Chart as ChartJS, BarElement } from 'chart.js';
ChartJS.register(BarElement)
into:
import 'chart.js/auto'
If you really want to use treeshaking you should look at the docs and import and register everything you are using:
https://www.chartjs.org/docs/3.7.1/getting-started/integration.html#bundlers-webpack-rollup-etc
SO BASSICALLY MISTAKE WHICH I DID WAS I DIDN'T IMPORT THIS BARCHART IN APPJS.CORRECT CCODE WILL BE LIKE THIS (FOR BARCHART.JSX) YOU CAN CHANGE IN IT MANY THINGS.
import React from "react";
import { Bar } from "react-chartjs-2";
import 'chart.js/auto'
const BarChart =() => {
return <div>
<Bar
options={{
scales: {
y: {
beginAtZero: true
}
}
}}
data ={{
labels: ['RCB', 'MI', 'RR', 'SRH', 'CSK', 'KXIP', 'DD', 'DCH', 'GL', 'RPS', 'KKR'],
datasets: [{
label: '# of toss wins',
data: [70, 85, 63, 35, 66, 68, 72, 43, 15, 6, 78],
backgroundColor: ['red', 'Blue', '#ff64dc', '#fc7404', 'yellow', 'red', '#000080', 'silver', 'gold', '#9400d3', 'purple' ],
borderColor:['black'],
borderWidth: 1
},
{
label: '# of match wins',
data: [73, 92, 63, 42, 79, 70, 62, 29, 13, 10, 77],
backgroundColor: ['#C9920E', 'Blue', '#ff64dc', '#fc7404', 'yellow', 'lightgrey', '#000080', 'silver', 'gold', '#9400d3', 'purple' ],
borderColor:['black'],
borderWidth: 1
}
]
}}
/></div>
};
export default BarChart ;

My data array has null values in chart.js. Is there a way to draw a line between the two segments to maintain visual progress?

As shown in the screenshot, there are days where I have a null value... I would like to connect the dataset with a line regardless of a particular day being null. Is this possible in chart.js 2.x?
You can set spangaps to true:
const options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, null, 2, 3],
borderColor: 'pink',
fill: false,
spanGaps: true
},
{
label: '# of Points',
data: [7, null, null, 8, 3, 7],
borderColor: 'orange',
fill: false,
spanGaps: true
}
]
},
options: {}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
</body>

Determine The Area Of A Point based on Background Color in Chart JS

As shown in the pictures below, I have a chart created with 'Chart JS'. This chart contains linear lines with various curves. I painted the areas between these lines with 'background color' in various colors.
My question is, when I create a random point on this chart, I just want to create an if statement based on colors.
For example,
There is the point called A and the variable called B.
If A point is in the yellow area, then B is 1.
If A point is in the light gray area, then B is 2.
Something like this.
Here is Picture:
Here is sample code:
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0"></script>
<script type="text/javascript">
var x_A = new Array(2, 2, 2.5, 2.5, 2);
var y_A = new Array(2.5 , 3 , 3.5, 2.5 , 2.5);
var c_A = [];
for (var i = 0; i < x_A.length; i++) {
var obj = { x: x_A[i], y: y_A[i] };
c_A.push(obj);
}
var x_B = new Array(0, 1.5, 1.5, 0);
var y_B = new Array(0, 2, 0.5, 0);
var c_B = [];
for (var i = 0; i < x_B.length; i++) {
var obj = { x: x_B[i], y: y_B[i] };
c_B.push(obj);
}
var x_C = new Array(1.5, 1.5, 2, 2, 1.5);
var y_C = new Array(0.5, 2, 3, 2.5, 0.5);
var c_C = [];
for (var i = 0; i < x_C.length; i++) {
var obj = { x: x_C[i], y: y_C[i] };
c_C.push(obj);
}
var r_A = 'rgba(220, 20, 60,1)';
var r_B = 'rgba(255, 255, 56,1)';
var r_C = 'rgba(34, 139, 34,1)';
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [
{
label: 'X',
showLine: true,
fill: true,
pointRadius: 7,
data: [{
x: 1,
y: 0.9
}],
borderWidth: 1,
pointBackgroundColor: "#000000",
lineTension: 0,
},
{
label:'Zone A',
showLine: true,
fill: true,
backgroundColor: r_A,
pointRadius: 0,
data: c_A,
borderWidth: 1,
borderColor: "#000000",
lineTension: 0,
},
{
label: 'Zone B',
showLine: true,
fill: true,
backgroundColor: r_B,
pointRadius: 0,
data: c_B,
borderWidth: 1,
borderColor: "#000000",
lineTension: 0,
},
{
label: 'Zone C',
showLine: true,
fill: true,
backgroundColor: r_C,
pointRadius: 0,
data: c_C,
borderWidth: 1,
borderColor: "#000000",
lineTension: 0,
},
]
},
options: {
title: {
display: false,
},
tooltips: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
type: 'linear',
position: 'bottom',
gridLines:
{
display: false
},
scaleLabel: {
display: true
}
}],
yAxes: [{
gridLines:
{
display: false
},
scaleLabel: {
display: true,
}
}]
}
}
});
</script>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<html>
<body>
<div class="w3-row">
<div class="w3-col s3"><p></p></div>
<div class="w3-col s6" align="center"><canvas id="myChart" height="220"></canvas></div>
</div>
<div class="w3-row" align="center"><h2>Color Zone where the point X is located: </h2></div>
</body>
</html>
Here is CodePen:
My Sample Example: CodePen

Aligning labels in highchart donut

I'm trying to make a highchart donut with a legend on the side,
I'm really struggling to get the data labels to be more centered. At the moment each of them are in a different place,
an image of intended result:
https://codepen.io/mattdavidson/pen/qgqZyV
Highcharts.chart('container', {
credits: { enabled: false },
chart: { height: 300, width: 500, animation: false },
title: {
align: 'center',
verticalAlign: 'middle',
text: 10,
y: 25,
x: 55,
style: { color: '#333333', fontSize: '72px', fontWeight:'bold'},
},
plotOptions: {
pie: {
dataLabels: {
enabled: true,
format: '{point.y}',
distance: -25,
style: { fontSize: '32px', textOutline: 0 },
},
animation: false,
showInLegend: true,
},
},
legend: {
layout: 'vertical',
verticalAlign: 'middle',
align: 'left',
symbolHeight: 25,
symbolRadius: 5,
itemMarginTop: 10,
itemMarginBottom: 10,
},
series: [
{
type: 'pie',
innerSize: '55%',
colors: ['rgb(212,33,71)', 'rgb(250,189,43)', 'rgb(60,168,74)'],
data: [['Category 1', 4], ['Category 2', 5], ['Category 3', 1]],
},
],
});
There is an issue reported on Highcharts github about donut labels position. Check it here: https://github.com/highcharts/highcharts/issues/9005.
I've changed some options and added custom text using Highcharts.SVGRenderer#text (dynamic sum of all values) on the donut center. Perhaps it will help you: https://jsfiddle.net/BlackLabel/2jmqext9/.
Code:
Highcharts.chart('container', {
credits: {
enabled: false
},
chart: {
height: 300,
width: 500,
animation: false,
events: {
load: function() {
var chart = this,
offsetLeft = -20,
offsetTop = 10,
x = chart.plotLeft + chart.plotWidth / 2 + offsetLeft,
y = chart.plotTop + chart.plotHeight / 2 + offsetTop,
value = 0;
chart.series[0].yData.forEach(function(point) {
value += point;
});
chart.renderer.text(value, x, y).add().css({
fontSize: '30px'
}).toFront();
}
}
},
plotOptions: {
pie: {
dataLabels: {
enabled: true,
color: '#fff',
format: '{point.y}',
distance: -25,
style: {
fontSize: '20px',
textOutline: 0
},
},
animation: false,
showInLegend: true,
},
},
legend: {
layout: 'vertical',
verticalAlign: 'middle',
align: 'left',
symbolHeight: 15,
symbolRadius: 5,
symbolPadding: 10,
itemMarginTop: 10,
itemMarginBottom: 10,
itemStyle: {
fontSize: '15px'
}
},
series: [{
type: 'pie',
innerSize: '55%',
colors: ['rgb(212,33,71)', 'rgb(250,189,43)', 'rgb(60,168,74)'],
data: [
['Category 1', 4],
['Category 2', 2],
['Category 3', 12]
],
}, ],
});

Flot chart with Threshold and Fillbetween

I'm looking for advice on how I should/can configure Flotcharts using the Fillbetween and Threshold pluggins to create a chart that accomplishes the following:
Plot a line chart. (done)
Set some threshold values. (done)
Set and fill values that are outside of the threshold values. (not quite done)
Here's what I've accomplished so far,
https://jsfiddle.net/gstoa/utv4kvw2/
$(function() {
var values = {
'avgBottom': [
[1, -2],
[2, -2],
[3, -2],
[4, -2],
[5, -2]
],
'avgTop': [
[1, 3],
[2, 3],
[3, 3],
[4, 3],
[5, 3]
],
'values': [
[1, .5],
[2, -3],
[3, .8],
[4, 4.5],
[5, 6.6]
]
};
var dataset = [{
data: values['values'],
lines: {
show: true
},
color: "rgb(50,50,255)"
}, {
id: 'avgBottom',
data: values['avgBottom'],
lines: {
show: true,
lineWidth: 0,
fill: false
},
color: "rgb(50,50,255)"
}, {
id: 'values',
data: values['values'],
lines: {
show: true,
lineWidth: 0.5,
fill: 0.2,
shadowSize: 0
},
color: "rgb(50,50,255)",
fillBetween: 'avgBottom'
}, {
id: 'avgTop',
data: values['avgTop'],
lines: {
show: true,
lineWidth: 0,
fill: 0.2
},
color: "rgb(50,50,255)",
fillBetween: 'values'
}];
$.plot($("#placeholder"), dataset, {
xaxis: {
tickDecimals: 0
},
series: {
lines: {
show: true,
fill: true
},
points: {
show: false,
radius: 4
},
color: "#62CB31",
// threshold: {
// below: -2,
// color: "rgb(255,0,0)"
// }
},
yaxis: {
tickFormatter: function(v) {
return v;
}
}
});
$.plot($("#placeholder"), [d1, d2, d3]);
});
I'd like this line chart to look like the following:
Any advice is greatly appreciated.
To do this, I had to switch from the fillbetween to the fillbelow flot plugin. I then had to modify the source of the fillbelow plugin to look at a new fillColor property of the series (I've got a pull request to merge these changes back into the main branch).
All in all, your new data set looks like the code snippet below (this JSFiddle demonstrates how to get the chart to look like your example image).
var dataset = [{
id: 'topValues',
data: values['values'],
lines: {
show: true,
},
color: "rgb(50,50,255)",
fillBelowTo: 'avgTop',
fillBelowUseSeriesObjectFillColor: false,
fillColor: "#FF0000"
}, {
id: 'avgTop',
data: values['avgTop'],
lines: {
show: true,
lineWidth: 0,
fill: true
},
color: "rgb(50,50,255)"
}, {
id: 'bottomValues',
data: values['values'],
lines: {
show: true,
lineWidth: 0,
shadowSize: 0
},
color: "rgb(50,50,255)"
}, {
id: 'avgBottom',
data: values['avgBottom'],
lines: {
show: true,
lineWidth: 0,
fill: true,
},
fillBelowTo: 'bottomValues',
fillBelowUseSeriesObjectFillColor: false,
fillColor: "#FF0000",
color: "rgb(50,50,255)"
}];
The fillBelowTo property acts similarly to the fillBetween
property of the fillbetween plugin - it denotes to which series you'd
like to fill below to.
The fillBelowUseSeriesObjectFillColor
property (set to false) tells us to not use the lines.fillColor
color and instead use the fillColor value. If fillBelowUseSeriesObjectFillColor was true, the lines.fillColor color would be used (which in this case would be blue).

Resources