Embed json string in amchart chart? - javascript

I'm trying to embed some json into my amcharts. This is the javascript code in the html:
<script type="text/javascript">
AmCharts.makeChart("mapdiv", {
"type": "map",
"imagesSettings": {
"rollOverColor": "#089282",
"rollOverScale": 1,
"selectedScale": 0.5,
"selectedColor": "#089282",
"color": "#13564e",
"selectable": false,
"bringForwardOnHover": false
},
"areasSettings": {
"color": "#D3D3D3",
"autoZoom": true
},
"data": {
"map": "puertoRicoHigh"
},
"dataLoader": {
"url": "http://OurServer/Service1.svc/GetLocations",
"format": "json",
"showErrors": true,
"postProcess": function(data, config, map) {
// create a new dataProvider
var mapData = map.data;
// init images array
if (mapData.images === undefined)
mapData.images = [];
// create images out of loaded data
for(var i = 0; i < data.length; i++) {
var image = data[i];
image.type = "circle";
mapData.images.push(image);
}
return mapData;
}
}
});
</script>
And this is what the json looks like: [{"title":"Site1","latitude":18.37,"longitude":-67.18},{"title":"Site2","latitude":18.20,"longitude":-65.80}]
I've been trying to embed this json into the code, but I'm having trouble doing so.
I tried using dataprovider instead of dataloader since it's not an http request, but I know I'm missing something:
<script type="text/javascript">
AmCharts.makeChart("mapdiv", {
"type": "map",
"imagesSettings": {
"rollOverColor": "#089282",
"rollOverScale": 1,
"selectedScale": 0.5,
"selectedColor": "#089282",
"color": "#13564e",
"selectable": false,
"bringForwardOnHover": false
},
"areasSettings": {
"color": "#D3D3D3",
"autoZoom": true
},
"data": {
"map": "puertoRicoHigh"
},
"dataProvider": [{"title":"Site1","latitude":18.3764,"longitude":-67.1819},{"title":"Site2","latitude":18.2001,"longitude":-65.8081}],
"postProcess": function(data, config, map) {
// create a new dataProvider
var mapData = map.data;
// init images array
if (mapData.images === undefined)
mapData.images = [];
// create images out of loaded data
for(var i = 0; i < data.length; i++) {
var image = data[i];
image.type = "circle";
mapData.images.push(image);
}
return mapData;
}
});
</script>

The map dataProvider is an object, not an array, whose structure is demonstrated on the map demos on the AmCharts website. Since your JSON is basically an array of map images, going by the postProcess method, you can restructure your dataProvider like so, adding type: "circle" to each image and skipping the need for any further processing:
dataProvider: {
map: "puertoRicoHigh",
images: [
{"title":"Site1","latitude":18.3764,"longitude":-67.1819, "type": "circle"},
{"title":"Site2","latitude":18.2001,"longitude":-65.8081, "type": "circle"}
]
}
Demo:
AmCharts.makeChart("mapdiv", {
"type": "map",
"imagesSettings": {
"rollOverColor": "#089282",
"rollOverScale": 1,
"selectedScale": 0.5,
"selectedColor": "#089282",
"color": "#13564e",
"selectable": false,
"bringForwardOnHover": false
},
"areasSettings": {
"color": "#D3D3D3",
"autoZoom": true
},
"dataProvider": {
"map": "puertoRicoHigh",
"images": [{
"title": "Site1",
"latitude": 18.3764,
"longitude": -67.1819,
"type": "circle"
},
{
"title": "Site2",
"latitude": 18.2001,
"longitude": -65.8081,
"type": "circle"
}
]
}
});
<script src="//www.amcharts.com/lib/3/ammap.js"></script>
<script src="//www.amcharts.com/lib/3/maps/js/puertoRicoHigh.js"></script>
<div id="mapdiv" style="width: 100%; height: 400px;"></div>

Related

After using json2csv I need to now convert it BACK to the JSON with Node

const { Parser, transforms: { unwind } } = require('json2csv');
const myCars = [
{
"carModel": "BMW",
"price": 15000,
"items": [
{
"name": "airbag",
"color": "white"
}, {
"name": "dashboard",
"color": "black"
}
]
}, {
"carModel": "Porsche",
"price": 30000,
"items": [
{
"name": "airbag",
"items": [
{
"position": "left",
"color": "white"
}, {
"position": "right",
"color": "gray"
}
]
}, {
"name": "dashboard",
"items": [
{
"position": "left",
"color": "gray"
}, {
"position": "right",
"color": "black"
}
]
}
]
}
];
const fields = ['carModel', 'price', 'items.name', 'items.color', 'items.items.position', 'items.items.color'];
const transforms = [unwind({ paths: ['items', 'items.items'], blankOut: true })];
const json2csvParser = new Parser({ fields, transforms });
const csv = json2csvParser.parse(myCars);
console.log(csv);
Will output
"carModel","price","items.name","items.color","items.items.position","items.items.color"
"BMW",15000,"airbag","white",,
,,"dashboard","black",,
"Porsche",30000,"airbag",,"left","white"
,,,,"right","gray"
,,"dashboard",,"left","gray"
,,,,"right","black"
I want to change all the GRAY to black as the CSV,
What would the best way to be then to convert the CSV back to the original JSON

heat map is not clear

Does anyone know how to set a colour range for this map? The variations between the values aren't large enough to notice the change in colour. So most of the values on the map appear to be in the same colour. I would either like to set my own colours or change much these colours vary by.
I cant find the answer on how to do this in react anywhere
import React, { Component } from 'react';
import AmCharts from "#amcharts/amcharts3-react";
import { connect } from "react-redux"
import { lookup } from 'country-data';
import * as adapter from "../Adapter.js";
class App extends Component {
constructor(props) {
super(props)
this.state = {
allCountriesHouseholdSpending: null,
selectedCoutry: null,
countrySpending: [{
"id": "AU",
"value": 4447100
},
{
"id": "US",
"value": 658188
}]
}
}
componentDidMount() {
adapter.getAllCountriesrtyHouseholdSpending()
.then(spendingData => this.setState({ allCountriesHouseholdSpending: spendingData }))
}
selectedCountrySpending = (country) => {
let selectedCity = country.mapObject.enTitle
if (selectedCity !== "Russia" && selectedCity !== "Venezuela" && selectedCity !== "Bolivia" && selectedCity !== "Svalbard and Jan Mayen" && selectedCity !== "Syria" && selectedCity !== "Tanzania" && selectedCity !== "Democratic Republic of Congo") {
// console.log(lookup.countries({ name: selectedCity }));
console.log(lookup.countries({ name: selectedCity })[0].alpha3);
console.log('selected!', selectedCity)
return selectedCity
}
}
render() {
const config = {
"type": "map",
"theme": "light",
"colorSteps": 10,
"dataProvider": {
"map": "worldLow",
"getAreasFromMap": true,
"areas": [{
"id": "AU",
"value": 658188.6034,
"selected": true
},
{
"id": "AT",
"value": 217653.4063
},
{
"id": "BE",
"value": 255659.6354
},
{
"id": "CA",
"value": 896977.0966
},
],
valueLegend: {
divId: "legenddiv",
left: 10,
bottom: 0,
minValue: "little",
maxValue: "a lot!"
},
},
"areasSettings": {
"selectedColor": "#CC0000",
"selectable": true,
"balloonText": "National Spending in [[title]]: <b>[[value]]</b>"
},
"listeners": [{
"event": "clickMapObject",
"method": (e) => {
console.log(e.mapObject.enTitle)
this.selectedCountrySpending(e)
}
}]
}
return (
<AmCharts.React style={{ width: "100%", height: "600px" }} options={config} />
);
}
}
const mapStateToProps = (state) => ({
})
const mapDispatchToProps = (dispatch) => ({
})
export default connect(mapStateToProps, mapDispatchToProps)(App)
You can customize the start and end colors by setting color and colorSolid in your areasSettings. You can also specify your own color by setting the color directly in the area object, e.g.
{
"id": "AU",
"value": 88323532,
"color": "#00ff00"
},
// ...
Note that setting getAreasFromMap: true essentially enables all the other areas as if they were defined in the dataProvider, which may not be what you want.
Here's a demo of color and colorSolid:
var chart = AmCharts.makeChart("chartdiv", {
"type": "map",
"theme": "light",
"colorSteps": 10,
"dataProvider": {
"map": "worldLow",
//"getAreasFromMap": true,
"areas": [{
"id": "AU",
"value": 658188.6034,
"selected": true
},
{
"id": "AT",
// "color": "#0000ff", //if you want to specify a color directly on an area
"value": 217653.4063
},
{
"id": "BE",
"value": 255659.6354
},
{
"id": "CA",
"value": 896977.0966
},
],
valueLegend: {
divId: "legenddiv",
left: 10,
bottom: 0,
minValue: "little",
maxValue: "a lot!"
},
},
"areasSettings": {
"color": "#880000",
"colorSolid": "#008888",
"selectedColor": "#CC0000",
"selectable": true,
"balloonText": "National Spending in [[title]]: <b>[[value]]</b>"
},
"listeners": [{
"event": "clickMapObject",
"method": (e) => {
}
}]});
html, body {
width: 100%;
height: 100%;
margin: 0px;
}
#chartdiv {
width: 100%;
height: 100%;
}
<script src="//www.amcharts.com/lib/3/ammap.js"></script>
<script src="//www.amcharts.com/lib/3/maps/js/worldLow.js"></script>
<script src="//www.amcharts.com/lib/3/themes/light.js"></script>
<div id="chartdiv"></div>

Stacked bars in Charts.js from a JSON list of objects

i'm trying to create a Charts.js with stacked bars from a json list of objects, with no success...
my json is
[{
"machine": {
"machineId": 1,
"name": "a",
"description": "aaaaaa",
"active": true,
"direction": "IN"
},
"realEnergy": 56.99,
"lastUpdate": "2018-10-16 09:00:00"
}, {
"machine": {
"machineId": 2,
"name": "ABCD 1",
"description": "ABCD 1",
"active": true,
"direction": "OUT"
},
"realEnergy": 62.11,
"lastUpdate": "2018-10-16 09:00:00"
}, {
"machine": {
"machineId": 1,
"name": "M1",
"description": "Machine M1",
"active": true,
"direction": "IN"
},
"realEnergy": 57.11,
"lastUpdate": "2018-10-16 09:30:00"
}, {
"machine": {
"machineId": 2,
"name": "ABCD 1",
"description": "ABCD 1",
"active": true,
"direction": "OUT"
},
"realEnergy": 62.14,
"lastUpdate": "2018-10-16 09:30:00"
}, {
"machine": {
"machineId": 1,
"name": "M1",
"description": "Machine M1",
"active": true,
"direction": "IN"
},
"realEnergy": 58.18,
"lastUpdate": "2018-10-16 10:00:00"
}, {
"machine": {
"machineId": 2,
"name": "ABCD 1",
"description": "ABCD 1",
"active": true,
"direction": "OUT"
},
"realEnergy": 71.11,
"lastUpdate": "2018-10-16 10:00:00"
}, {
"machine": {
"machineId": 1,
"name": "M1",
"description": "Machine M1",
"active": true,
"direction": "IN"
},
"realEnergy": 64.11,
"lastUpdate": "2018-10-16 10:30:00"
}, {
"machine": {
"machineId": 2,
"name": "ABCD 1",
"description": "ABCD 1",
"active": true,
"direction": "OUT"
},
"realEnergy": 72.11,
"lastUpdate": "2018-10-16 10:30:00"
}]
I would like to have lastUpdate on the labels and stacked realEnergy values for the bars.
I was trying to adopt this json to match Charts.js dataset with no luck.
var size = Object.keys(json).length ;
labels = response.map(function(e) {
return e.lastUpdate;
});
for(var i = 0; i < size; i++){
datasetValue[i] = {
fillColor: 'rgba(220,220,220,0.5)',
strokeColor :'rgba(220,220,220,1)',
label :json[i].machine.name,
data : json[i].realEnergy
}
}
var myData = {
datasets : datasetValue
}
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets:myData
},
options: {
scales: {
yAxes: [{
stacked: true
}],
xAxes: [{
stacked: true
}]
}
}
});
}
I can get the labels correctly but no data on it, cannot understand how the dataset values should be created.
Dataset's data property is an array of values that will be distributed across the labels (in this case realEnergy value per each lastUpdate). I assume that each dataset should represent particular machine.
Here's the code to generate datasets and labels based on your JSON data:
const jsonData = JSON.parse(yourJSONData);
const colors = ['yellow', 'green', 'blue']; // purely optional
const machines = jsonData.reduce((uniqueMachines, record) => {
// find unique machines that will be base to our datasets
if (!uniqueMachines.find(machine => machine.machineId === record.machine.machineId))
uniqueMachines.push(record.machine);
return uniqueMachines;
}, []);
const lastUpdates = jsonData.reduce((uniqueLastUpdates, record) => {
// get labels for our chart
if (!uniqueLastUpdates.find(lastUpdate => lastUpdate === record.lastUpdate))
uniqueLastUpdates.push(record.lastUpdate);
return uniqueLastUpdates;
}, []);
const datasets = machines.map((machine, index) => {
const label = machine.name;
const backgroundColor = colors[index]; // purely optional
const data = lastUpdates.map(lastUpdate => {
const valueRecord = jsonData.find(record => record.machine.machineId === machine.machineId && record.lastUpdate === lastUpdate);
if (!valueRecord) return 0; // if value record is not defined, return 0;
return valueRecord.realEnergy;
});
return {
// here we return dataset
label,
backgroundColor,
data,
stack: 'main' // here we define the stack
};
});
And here's the final configuration for the chart:
const myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: lastUpdates,
datasets
},
options: {
scales: {
yAxes: [{
stacked: true
}]
}
}
});
A working example on the JSFiddle: click

Offset guides label in case of text overlapping in amcharts

I would like to include guides into my amcharts graphs and I found very descriptive examples. However I'm struggling with positioning of label text, especially in case when guides are so close that labels overlap.
Here is example code https://jsfiddle.net/Tripy/1wwygcy7/2/
HTML:
<script src="https://www.amcharts.com/lib/3/amcharts.js"></script>
<script src="https://www.amcharts.com/lib/3/serial.js"></script>
<script src="https://www.amcharts.com/lib/3/amstock.js"></script>
<div id="chartdiv" style="width: 100%; height: 500px;"></div>
Javascript:
var chartData = weekendGuides = [];
generateChartData();
function generateChartData() {
var firstDate = new Date();
firstDate.setDate( firstDate.getDate() - 200 );
firstDate.setHours( 0, 0, 0, 0 );
for ( var i = 0; i < 200; i++ ) {
var newDate = new Date( firstDate );
newDate.setDate( newDate.getDate() + i );
var a1 = Math.round( Math.random() * ( 40 + i ) ) + 100 + i;
var b1 = Math.round( Math.random() * ( 1000 + i ) ) + 500 + i * 2;
chartData.push( {
"date": newDate,
"value": a1,
"volume": b1
} );
// add weekend guide
if ( 6 == newDate.getDay() ) {
var toDate = new Date( newDate );
toDate.setDate( newDate.getDate() + 2 );
weekendGuides.push( {
"date": newDate,
"toDate": toDate,
"lineAlpha": 0,
"fillAlpha": 0.05,
"fillColor": "#000",
"expand": true
} );
}
}
}
var chart = AmCharts.makeChart( "chartdiv", {
"type": "stock",
"dataSets": [ {
"title": "first data set",
"fieldMappings": [ {
"fromField": "value",
"toField": "value"
}, {
"fromField": "volume",
"toField": "volume"
} ],
"dataProvider": chartData,
"categoryField": "date"
} ],
"panels": [ {
"showCategoryAxis": false,
"title": "Value",
"percentHeight": 70,
"stockGraphs": [ {
"id": "g1",
"valueField": "value",
"comparable": true,
"compareField": "value",
"balloonText": "[[title]]:<b>[[value]]</b>",
"compareGraphBalloonText": "[[title]]:<b>[[value]]</b>"
} ],
"stockLegend": {
"periodValueTextComparing": "[[percents.value.close]]%",
"periodValueTextRegular": "[[value.close]]"
},
"categoryAxis": {
"guides": weekendGuides
},
"valueAxes": [ {
"guides": [ {
"value": 325,
"lineAlpha": 0.8,
"lineColor": "#0c0",
"label": "Guide #1",
"position": "right"
}, {
"value": 322,
"lineAlpha": 0.8,
"lineColor": "#0c0",
"label": "Guide #2",
"position": "right"
}]
} ]
} ],
"chartScrollbarSettings": {
"graph": "g1"
},
"chartCursorSettings": {
"valueBalloonsEnabled": true,
"fullWidth": true,
"cursorAlpha": 0.1
},
"periodSelector": {
"position": "bottom",
"periods": [ {
"period": "MM",
"selected": true,
"count": 1,
"label": "1 month"
}, {
"period": "YYYY",
"count": 1,
"label": "1 year"
}, {
"period": "YTD",
"label": "YTD"
}, {
"period": "MAX",
"label": "MAX"
} ]
}
} );
Any idea how to push label text below the guide for guides in case that labels are overlapping. Perhaps with CSS code for class name amcharts-guide-[id]?
There isn't a way to do this through the guide properties properties, but you have the right hunch with the css class name. Set addClassNames to true, give your guides IDs and then add a drawn event listener in your stock panel that adjusts the desired guide(s) directly by calling querySelector on the .amcharts-guide-[id] tspan selector and adjusting the y attribute:
AmCharts.makeChart("chartdiv", {
"addClassNames": true,
// ...
"stockPanels": [{
"valueAxes": [{
"guides": [{
"id": "guide-1",
// ..
}, {
"id": "guide-2",
// ..
}]
}],
"listeners": [{
"event": "drawn",
"method": function() {
var guide2Text = document.querySelector('.amcharts-guide-guide-2 tspan');
if (guide2Text) {
guide2Text.setAttribute('y', 20);
}
}
}]
}],
// ..
});
Updated fiddle

Hide legend if value is 0 - Kendo UI Pie Chart

I've have Kendo pie chart and its legend still show even there is no value.
Is it possible to hide legend that no value or value = 0. I'm passing value through the function, so I does not know which value is 0. I've tried to set up data in array but I am stuck. Anybody can help me...
Here is my script:
function createPieChart(a,b,c,d) {
var e = a+b+c+d;
var aa = a/e*100;
var bb = b/e*100;
var cc = c/e*100;
var dd = d/e*100;
var perA = Math.round(aa*100.0)/100.0;
var perB = Math.round(bb*100.0)/100.0;
var perC = Math.round(cc*100.0)/100.0;
var perD = Math.round(dd*100.0)/100.0;
var arrValue = [perA, perB, perC, perD];
var data = [{
"source": "Positive",
"percentage": perA,
"color": "#9de219",
"explode": true
},{
"source": "Neutral",
"percentage": perB,
"color": "#90cc38"
},{
"source": "Negative",
"percentage": perC,
"color": "#068c35"
},{
"source": "Unknown",
"percentage": perD,
"color": "#006634"
}];
$("#chart_div").kendoChart({
dataSource: {
transport: {
read: function(e) {
e.success(data);
}
}
},
title: {
position: "top",
text: "Sentiment Result"
},
legend: {
position: "bottom",
visible: true
},
seriesDefaults: {
labels: {
visible: false,
template: "#= category #: \n #= value#%"
}
},
series: [{
type: "pie",
startAngle: 150,
field: "percentage",
categoryField: "source",
colorField: "color",
explodeField: "explode"
}],
tooltip: {
visible: true,
template: "${ category } - ${ value }%"
}
}
Replace this code:
var data = [{
"source": "Positive",
"percentage": perA,
"color": "#9de219",
"explode": true
},{
"source": "Neutral",
"percentage": perB,
"color": "#90cc38"
},{
"source": "Negative",
"percentage": perC,
"color": "#068c35"
},{
"source": "Unknown",
"percentage": perD,
"color": "#006634"
}];
With this code:
var arrValue = [perA, perB, perC, perD];
var arrSource = ["Positive","Neutral","Negative","Unknown"];
var arrColor = ["#9de219","#90cc38","#068c35","#006634"];
var data=[];
for (var i=0; i<arrValue.length; i++){
if(arrValue[i]>0){
data.push({
source: arrSource[i],
percentage: arrValue[i],
color: arrColor[i],
explode: true
});
}
}

Categories