How to make a Specific polygon not get modified when user try to modified on basis of properties in open layer 6? - maps

when i render my geojson. i want user should not able to modified the polygon having property region key name- Serviceable. Other objects in the feature array user can modify on the map expect the
feature object having region key value Serviciable.Please help me here.
html file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Draw Features</title>
<!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer -->
<script src="https://unpkg.com/elm-pep"></script>
<!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=fetch,requestAnimationFrame,Element.prototype.classList,URL,TextDecoder,Number.isInteger"></script>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.bundle.min.js"></script>
<style>
.map {
width: 100%;
height:400px;
}
.ol-popup {
position: absolute;
background-color: white;
box-shadow: 0 1px 4px rgba(0,0,0,0.2);
padding: 15px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 12px;
left: -50px;
min-width: 280px;
}
.ol-popup:after, .ol-popup:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: white;
border-width: 10px;
left: 48px;
margin-left: -10px;
}
.ol-popup:before {
border-top-color: #cccccc;
border-width: 11px;
left: 48px;
margin-left: -11px;
}
.ol-popup-closer {
text-decoration: none;
position: absolute;
top: 2px;
right: 8px;
}
.ol-popup-closer:after {
content: "✖";
}
.hideForm{
display: none;
}
.hideHover{
display: none;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
<form class="form-inline">
<label for="type">Select type to create: </label>
<select class="form-control mr-2 mb-2 mt-2" id="type">
<option value="">Please Select</option>
<option value="Point">Point</option>
<option value="LineString">LineString</option>
<option value="Polygon"> Create Polygon</option>
<option value="Circle">Circle</option>
<option value="None">None</option>
</select>
<!-- <input class="form-control mr-2 mb-2 mt-2" type="button" value="undo" id="undo"> -->
</form>
<div id="popup" class="ol-popup hideForm" >
<div id="popup-content" >
<form class="form-inline">
<label for="type">Please Select: </label>
<select class="form-control mr-2 mb-2 mt-2" id="selectType">
<option value="">Please Select</option>
<option value="Serviceable">Serviceable Area</option>
<option value="cluster">Cluster</option>
<option value="Society"> Society</option>
</select>
<input class="form-control mr-2 mb-2 mt-2" type="button" onclick="submitData($event)" value="submit" id="submitForm">
</form>
</div>
</div>
<div id="hoverPopup" class="ol-popup hideHover" >
<div id="popup-content-hover">
</div>
</div>
<button id="download">Download</button>
<script src="main.js"></script>
</body>
</html>
This is my js file .i am new to open layer.
Is there any way through which i can filter the data before passing it to the modify object or any other approach that can help here
import 'ol/ol.css';
import Circle from 'ol/geom/Circle';
import Feature from 'ol/Feature';
import GeoJSON from 'ol/format/GeoJSON';
import Map from 'ol/Map';
import View from 'ol/View';
import Point from 'ol/geom/Point';
import {Circle as CircleStyle, Fill, Stroke, Style,Icon} from 'ol/style';
import {OSM, Vector as VectorSource} from 'ol/source';
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
import {Draw, Modify,Select, Snap} from 'ol/interaction';
import {fromLonLat} from 'ol/proj';
import Overlay from 'ol/Overlay';
const iconFeature = new Feature({
geometry: new Point([0, 0]),
name: 'Null Island',
population: 4000,
rainfall: 500,
});
const iconStyle = new Style({
image: new Icon({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png',
}),
});
iconFeature.setStyle(iconStyle);
let showHover = true;
const styles = {
'Polygon': new Style({
stroke: new Stroke({
color: 'blue',
width: 3,
}),
fill: new Fill({
color: 'rgba(0, 0, 255, 0.1)',
})
}),
'Serviceable': new Style({
stroke: new Stroke({
color: 'grey',
width: 3,
}),
fill: new Fill({
color: 'rgba(0, 0, 255, 0.1)',
}),
}),
'cluster': new Style({
stroke: new Stroke({
color: 'green',
width: 3,
}),
fill: new Fill({
color: 'rgba(0, 0, 255, 0.1)',
}),
}),
'society': new Style({
stroke: new Stroke({
color: 'yellow',
width: 3,
}),
fill: new Fill({
color: 'rgba(0, 0, 255, 0.1)',
})
}),
geometry: function(feature) {
let geometry = feature.getGeometry();
let geometryType = geometry.getType();
return (
geometryType == 'Polygon' ? geometry.getInteriorPoint() :
geometryType == 'MultiPolygon' ? geometry.getInteriorPoints() :
geometry
);
},
image: new Icon({
anchor: [0.5, 46],
anchorXUnits: "fraction",
anchorYUnits: "pixels",
src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png',
}),
};
const styleFunction = function (feature) {
const featureStyle =feature.values_.region?feature.values_.region:feature.getGeometry().getType();
return styles[featureStyle];
};
const geojsonObject = {
'type': 'FeatureCollection',
'crs': {
'type': 'name',
'properties': {
'name': 'EPSG:3857',
},
},
'features': [
{
'type': 'Feature',
'properties':{
'region':'Serviceable',
'name':'serviceable 1'
},
'geometry': {
'type': 'Polygon',
'coordinates': [
[
fromLonLat([ 77.15760062500001,30.890967638580772]),
fromLonLat([ 77.2941240625,29.57600861486909]),
fromLonLat([ 76.95873343750002,28.428848818170273]),
fromLonLat([ 75.9202178125,28.434726060930952]),
fromLonLat([ 75.5131084375,28.909133164756486]),
fromLonLat([ 74.70792777343749,29.39857793541408]),
fromLonLat([ 74.78873587890624,29.871326311523653]),
fromLonLat([ 75.48477835937497,29.65680741133687]),
fromLonLat([ 76.15957328125,29.79063051517841]),
],
],
},
},
{
'type': 'Feature',
'properties':{
'region':'cluster',
'name':'jhajjar'
},
'geometry': {
'type': 'Polygon',
'coordinates': [
[
fromLonLat([ 76.68930838867189,28.636901895884023]),
fromLonLat([ 76.69674247070313,28.57745043657983]),
fromLonLat([ 76.5677959375,28.5792192324589]),
fromLonLat([ 76.58323355957032,28.637598392669847]),
fromLonLat([ 76.68930838867189,28.636901895884023]),
],
],
},
},
{
'type': 'Feature',
'properties':{
'region':'cluster',
'name':'cluster 3'
},
'geometry': {
'type': 'Polygon',
'coordinates': [
[
fromLonLat([ 75.92163871093751,29.542932708619503]),
fromLonLat([ 76.2352342919922,29.539852918027435]),
fromLonLat([ 76.38952811523438,29.244818184007894]),
fromLonLat([ 76.03893607421875,28.974670297760245]),
fromLonLat([ 75.5955058984375,29.235604663759762]),
fromLonLat([ 75.92163871093751,29.542932708619503]),
],
],
},
},
{
'type': 'Feature',
'properties':{
'region':'society',
'name':'vatika city'
},
'geometry': {
'type': 'Polygon',
'coordinates': [
[
fromLonLat([ 75.91751883789064,29.38271030601346]),
fromLonLat([ 75.96332267089845,29.399966998733607]),
fromLonLat([ 76.01049979492188,29.35020995663461]),
fromLonLat([ 75.8823808984375,29.30093429893928]),
fromLonLat([ 75.84544486328124,29.35896121182201]),
fromLonLat([ 75.91751883789064,29.38271030601346]),
],
],
},
},
{
'type': 'Feature',
'properties':{
'region':'society',
'name':'orchid petals'
},
'geometry': {
'type': 'Polygon',
'coordinates': [
[
fromLonLat([ 76.1626512841797,29.33662949113684]),
fromLonLat([ 76.20845511718751,29.353893995208363]),
fromLonLat([ 76.1979540185547,29.305311991234767]),
fromLonLat([ 76.19205802246094,29.279375332655874]),
fromLonLat([ 76.12696952148437,29.324843490064747]),
fromLonLat([ 76.1626512841797,29.33662949113684]) ],
],
},
},
{
'type': 'Feature',
'properties':{
'region':'society',
'name':'Vatika City'
},
'geometry': {
'type': 'Polygon',
'coordinates': [
[
fromLonLat([ 77.14661429687501,28.326682984225194]),
fromLonLat([ 77.1348223046875,28.190829441589432]),
fromLonLat([ 76.9578105859375,28.19502541100354]),
fromLonLat([ 77.0000273828125,28.34067794211981]),
fromLonLat([ 77.14661429687501,28.326682984225194]),
],
],
},
}
],
};
const vectorSource = new VectorSource({
features: new GeoJSON().readFeatures(geojsonObject),
});
function vectorSourceData(feature){
console.log(feature,'feature data');
}
//vectorSource.addFeature(new Feature(new Circle([5e6, 7e6], 1e6)));
console.log(vectorSource,'source data');
const vectorLayer = new VectorLayer({
source: vectorSource,
style: styleFunction,
});
const container = document.getElementById('popup');
const content = document.getElementById('popup-content');
const closer = document.getElementById('popup-closer');
const hoverCloser = document.getElementById('popup-closer-hover');
const overlay = new Overlay({
element: container,
autoPan: true,
autoPanAnimation: {
duration: 250,
},
});
// var overlay = new ol.Overlay({
// element: document.getElementById('info'),
// positioning: 'bottom-left'
// });
// overlay.setMap(map);
const gurgaonLatLong = [77.019135, 28.481216];
const gurgaonLatitudeLongnitude = fromLonLat(gurgaonLatLong);
const map = new Map({
layers: [
new TileLayer({
source: new OSM(),
}),
vectorLayer,
],
target: 'map',
overlays: [overlay],
view: new View({
center: gurgaonLatitudeLongnitude,
zoom: 6,
}),
});
**This line makes the features modify**
const modify = new Modify({source: vectorSource});
map.addInteraction(modify);
let draw, snap; // global so we can remove them later
const typeSelect = document.getElementById('type');
function addInteractions() {
console.log(typeSelect.value,'value called ');
if(typeSelect.value === ''){
showHover= true;
} else if (typeSelect !== 'None') {
draw = new Draw({
source: vectorSource,
type: typeSelect.value,
});
map.addInteraction(draw);
snap = new Snap({source: vectorSource});
map.addInteraction(snap);
showHover= false;
}
}
/**
* Handle change event.
*/
typeSelect.onchange = function () {
// popUpData.style.display = 'none';
container.style.display = 'none';
map.removeInteraction(draw);
map.removeInteraction(snap);
addInteractions();
};
var coord;
var featureData;
map.on('click', function (evt) {
coord=evt
const coordinate = evt.coordinate;
featureData = map.forEachFeatureAtPixel(evt.pixel, function(feature,layer) {
if(layer){
popUpData.style.display = 'none';
container.style.display = 'block';
overlay.setPosition(coordinate);
}
return feature
});
});
const popUpData = document.getElementById('hoverPopup');
const popUpDataContent = document.getElementById('popup-content-hover');
map.on('pointermove', function (evt) {
if(showHover) {
featureData = map.forEachFeatureAtPixel(evt.pixel, function(feature,layer) {
console.log(layer,'layered data fetcehd');
if(layer){
popUpData.style.display = 'block';
const overlay = new Overlay({
element: popUpData,
autoPan: true,
autoPanAnimation: {
duration: 250,
},
});
popUpDataContent.innerHTML = `${evt.coordinate}`
overlay.setPosition(evt.coordinate);
map.addOverlay(overlay);
} else{
popUpData.style.display = 'none';
}
return feature
});
}
});
addInteractions();
const formSelect = document.getElementById('submitForm');
formSelect.onclick = function(ev){
const selectValue = document.getElementById('selectType').value;
var coordinate = coord.coordinate;
// var hdms = ol.coordinate.toStringHDMS (ol.proj.transform (coordinate, 'EPSG: 31700', 'EPSG: 3857'));
if(selectValue) {
var selected_polygon_style =
new Style({
stroke: new Stroke({
color: selectValue === 'Serviceable'?'grey':selectValue === 'cluster'?'green':'yellow',
width: 3,
}),
fill: new Fill({
color: 'rgba(0, 0, 255, 0.1)',
}),
// image: new Icon({
// color:'#8959AB',
// crossOrigin:'anonymous',
// src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png',
// imgSize:[20,20]
// }),
})
// add more styling key / value pairs as your need
featureData.setStyle(selected_polygon_style);
vectorSource.addFeatures(featureData);
selectValue.value='';
showHover=true;
closeWindow();
}
}
/**
* Handle change event.
*/
// document.getElementById('undo').addEventListener('click', function () {
// draw.removeLastPoint();
// });
/**
* Popup
**/
closer.onclick = closeWindow;
function closeWindow() {
overlay.setPosition(undefined);
closer.blur();
return false;
};
hoverCloser.onclick = function(){
popUpData.style.display = 'none';
overlay.setPosition(undefined);
hoverCloser.blur();
return false;
}

You can use a features collection instead of a source for the Modify interaction. Add features which are allowed to be modified to the collection:
const features = new Collection();
vectorSource.forEachFeature(function(feature) {
if (feature.get('name') != 'Serviceable') {
features.push(feature);
}
});
const modify = new Modify({features: features});

I got the answer. Handled it through filteration.
const modifiedSource = new VectorSource();
modifiedSource.clear();
const modified = vectorSource.getFeatures().filter(feature =>feature.get('region') != 'Serviceable')
modifiedSource.addFeatures(modified);
const modify = new Modify({source: modifiedSource});

Related

particlejs React typscript height width container

i want to do effect with particlejs i want to contain my particle in div with (width 250px height 250px) but i cant i dont know why the all particle are in all page
i tried to this contain the div in div and with position absolute/relative
import { useCallback } from "react";
import Particles from "react-tsparticles";
import type { Container, Engine } from "tsparticles-engine";
import { loadFull } from "tsparticles";
import '../style/Particules.css'
const Particule = () => {
const particlesInit = useCallback(async (engine: Engine) => {
console.log(engine);
// you can initialize the tsParticles instance (engine) here, adding custom shapes or presets
// this loads the tsparticles package bundle, it's the easiest method for getting everything ready
// starting from v2 you can add only the features you need reducing the bundle size
await loadFull(engine);
}, []);
const particlesLoaded = useCallback(async (container: Container | undefined) => {
await console.log(container);
}, []);
return (
<div className="container">
<div>
<h2>first</h2>
</div>
<div> <h2>second</h2>
<Particles
id="tsparticles"
init={particlesInit}
loaded={particlesLoaded}
options={{
background: {
color: {
value: "#0d47a1",
}
},
fullScreen: {
enable: true,
zIndex: -1,
},
fpsLimit: 60,
interactivity: {
events: {
onClick: {
enable: true,
mode: "push",
},
onHover: {
enable: true,
mode: "repulse",
},
resize: true,
},
modes: {
push: {
quantity: 1,
},
repulse: {
distance: 100,
duration: 0.04,
},
},
},
particles: {
color: {
value: "#fff",
},
links: {
color: "#ffffff",
distance: 15,
enable: true,
opacity: 0.1,
},
collisions: {
enable: false,
},
move: {
direction: "none",
enable: true,
outModes: {
default: "bounce",
},
random: false,
speed: 0.5,
straight: false,
},
number: {
density: {
enable: true,
area: 800,
},
value: 30,
},
opacity: {
value: 2,
},
style: {
position: "absolute"
},
shape: {
type: "images",
"images":
[{
"src": 'https://media.wuerth.com/stmedia/modyf/eshop/products/std.lang.all/resolutions/category/png-546x410px/56314216.png',
}, {
"src": "https://media.wuerth.com/stmedia/modyf/eshop/products/std.lang.all/resolutions/category/png-546x410px/56597539.png"
},
{
"src": "https://media.wuerth.com/stmedia/modyf/eshop/products/std.lang.all/resolutions/category/png-546x410px/4042942.png"
},
{
"src": ""
}
]
},
size: {
random: true,
value: 50,
},
},
detectRetina: true,
}}
/>
</div>
<div>
<h2>third</h2>
</div>
</div>
);
};
export default Particule;
css
.container{
display: flex;
position: absolute;
width: 100vw;
height : 100%;
top: 0;
left: 0;
}
.container > div {
position: relative;
width: 100%;
}
i have this result in the image your see me i want this
but me i want to contain my particle in the second div only [enter image description here](https://i.stack.imgur.com/Yxteq.png)
i try to add the style in the the position absolute , but nothing
<Particles
id="tsparticles"
init={particlesInit}
loaded={particlesLoaded}
options={{
background: {
color: {
value: "#0d47a1",
}
},
style:{
position:"absolute"
},
thanks for the help
i want to add the particle in the second div with heigth and width i dont want on the all page

How can I make streaming chart with react?

Currently, I'm trying to use chart.js streaming for my website. However, I tried to make that with searching but data is not changing, the below is what I tried to do for it.
Here is my code:
import "chartjs-plugin-streaming";
import React from "react";
import { Bar } from "react-chartjs-2";
import styled from "styled-components";
const Home = () => {
const data = {
datasets: [
{
label: "Dataset 1",
borderColor: "rgb(255, 99, 132)",
backgroundColor: "rgba(255, 99, 132, 0.5)",
lineTension: 0,
borderDash: [8, 4],
data: [],
},
],
};
const options = {
scales: {
xAxes: [
{
type: "realtime",
realtime: {
onRefresh: function () {
data.datasets[0].data.push({
x: Date.now(),
y: Math.random() * 100,
});
},
delay: 2000,
},
},
],
},
};
console.log(options);
return (
<Main>
<Bar data={data} options={options} />
</Main>
);
};
export default Home;
const Main = styled.div`
display: flex;
justify-content: center;
align-items: center;
margin-left: 20vw;
margin-top: 15vh;
width: 70vw;
height: 70vh;
`;
You need to update the data in the argument you get in the onRefresh function like so:
realtime: {
onRefresh: function(chart) {
chart.data.datasets[0].data.push({
x: Date.now(),
y: Math.random() * 100,
});
},
delay: 2000,
},

Openlayers popup in React doesn't follow the map zoom

I'm trying to code a modified version of this example.
Using vanilla Javascript all is working fine, but now I'm trying to move it to React and the popup doesn't follow the map when I zoom in or zoom out the map. I suppose that the popup is not linked to the map overlay, but it's totally disconnected from it and this should be the problem, but I don't know how to fix it:
This is my code:
import 'ol/ol.css';
import React, { Component } from "react";
import ReactDOM from 'react-dom';
import Map from 'ol/Map';
import View from 'ol/View';
import Overlay from 'ol/Overlay';
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
import { OSM, Vector as VectorSource } from 'ol/source';
import { Circle as CircleStyle, Icon, Fill, Stroke, Style, Text } from 'ol/style';
import GeoJSON from 'ol/format/GeoJSON';
import * as olExtent from 'ol/extent';
import $ from 'jquery';
import 'bootstrap';
import markerLogo from './marker.png';
class PublicMap extends Component {
constructor(props) {
super(props);
var shapeDisciplinare = this.props.geoJson;
var iconStyle = new Style({
image: new Icon({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: markerLogo
}),
text: new Text({
font: '12px Calibri,sans-serif',
fill: new Fill({ color: '#000' }),
stroke: new Stroke({
color: '#fff', width: 2
})
})
});
var getStyles = function (feature) {
var myStyle = {
'Point': iconStyle,
'Polygon': new Style({
stroke: new Stroke({
color: 'blue',
width: 3
}),
fill: new Fill({
color: 'rgba(0, 0, 255, 0.1)'
}),
text: new Text({
font: '12px Calibri,sans-serif',
fill: new Fill({ color: '#000' }),
stroke: new Stroke({
color: '#fff', width: 2
}),
text: feature.getProperties().denominazione
})
})
};
return [myStyle[feature.getGeometry().getType()]];
};
var raster = new TileLayer({
source: new OSM()
});
var source = new VectorSource();
var vector = new VectorLayer({
source: source,
style: new Style({
fill: new Fill({
color: 'rgba(255, 255, 255, 0.2)'
}),
stroke: new Stroke({
color: '#ffcc33',
width: 2
}),
image: new CircleStyle({
radius: 7,
fill: new Fill({
color: '#ffcc33'
})
})
})
});
vector.setZIndex(1);
this.olmap = new Map({
layers: [raster, vector],
target: null,
view: new View({
center: [-11000000, 4600000],
zoom: 4
})
});
var reader = new GeoJSON({
defaultDataProjection: 'EPSG:3857',
Projection: 'EPSG:3857'
});
var projector = {
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857'
};
let shapeDisciplinareJson = JSON.parse(shapeDisciplinare);
var vectorSource = new VectorSource({
features: reader.readFeatures(shapeDisciplinareJson, projector)
});
var vectorLayer = new VectorLayer({
source: vectorSource,
style: getStyles
});
this.state = { vs: vectorSource, vl: vectorLayer };
}
componentDidMount() {
this.olmap.setTarget("map");
var extent = olExtent.createEmpty();
extent = olExtent.extend(extent, this.state.vs.getExtent());
this.olmap.addLayer(this.state.vl);
this.olmap.getView().fit(extent, this.olmap.getSize());
this.olmap.getView().setZoom(8);
var element = document.getElementById('popup');
this.popup = new Overlay({
element: ReactDOM.findDOMNode(this).querySelector('#popup'),
positioning: 'bottom-center',
stopEvent: false,
offset: [0, -50]
});
// display popup on click
this.olmap.on('click', (evt) => {
var feature = this.olmap.forEachFeatureAtPixel(evt.pixel,
(feature) => {
return feature;
});
if (feature) {
var coordinates = feature.getGeometry().getCoordinates();
//if lenght is 2, then is a gps location, otherwise a shape
if (coordinates.length === 2) {
this.popup.setOffset([0, -50]);
this.popup.setPosition(coordinates);
} else {
this.popup.setOffset([0, 0]);
this.popup.setPosition(evt.coordinate);
}
this.olmap.addOverlay(this.popup);
$(element).popover({
'placement': 'top',
'html': true,
'content': feature.getProperties().denominazione
});
$(element).attr('data-content', feature.getProperties().denominazione);
$(element).popover('show');
} else {
$(element).popover('hide');
}
});
// change mouse cursor when over marker
this.olmap.on('pointermove', (e) => {
if (e.dragging) {
$(element).popover('hide');
return;
}
var pixel = this.olmap.getEventPixel(e.originalEvent);
var hit = this.olmap.hasFeatureAtPixel(pixel);
this.olmap.getTargetElement().style.cursor = hit ? 'pointer' : '';
});
}
componentWillUnmount() {
this.map.setTarget(null);
}
render() {
return (
<div id="map" style={{ width: "100%", height: "360px" }}>
<div id="popup"></div>
</div>
);
}
}
export default PublicMap;

Annotations not working with linear type in ChartJS 2

I am trying to create a graph using ChartJS2 in one of our application; where we are using AngularJS 1.x along with RequireJS. So for that we have used ChartJs 2.7.0
When I try to implement our requirement, I'm facing an abnormal issue where
When I define x axes type as linear then the annotation(vertical line) doesn't get displayed on the graph, as displayed in the attached image: when type: 'linear'
And When I comment the line axes(X) type as linear then only annotation(vertical line) gets displayed but the graph doesn't get displayed at all as shown in the attached image: when commented the line type: 'linear'
My HTML Code is as follows:
<canvas style='height: 350px; width: 400px;' id="line" class="chart chart-line" chart-data="ourFixData.data"
chart-labels="ourFixData.labels" chart-series="ourFixData.series" chart-options="ourFixData.options" chart-colors="ourFixData.colors"
chart-dataset-override="ourFixData.datasetOverride"></canvas>
And my controller code is as follows:
'use strict';
define(['app'], function (app) {
app.register.controller("demoCtrl", function ($scope) {
$scope.data = [];
$scope.ourFixData = {};
$scope.ourFixData.lineAtPoint = 2.20;
$scope.ourFixData.colors = ['#399c5f', '#399c5f', '#399c5f'];
$scope.ourFixData.labels = [0, 0.5, 1.5, 2.5, 5, 7.5, 12.5, 17.5, 27.5];
$scope.ourFixData.series = ['Invites Available'];
var dashArr = [,,,,4,5,6,7,8];
var mainArr = [0,1,2,3,4,,,,];
$scope.ourFixData.data = [
dashArr,
mainArr
];
$scope.ourFixData.onClick = function (points, evt) {
console.log(points, evt);
};
$scope.ourFixData.datasetOverride = [
{
data: dashArr,
borderColor: '#399c5f',
borderDash: [2,4],
borderWidth: 2,
pointBackgroundColor : '#399c5f',
fill: false
}, {
data: mainArr,
borderColor: '#399c5f',
borderWidth: 2,
pointBackgroundColor : '#399c5f',
fill: false
}
];
$scope.ourFixData.options = {
title: {
fontFamily: "Open Sans",
text: "Invite Graph"
},
scales: {
xAxes: [
{
id: 'x-axis-0',
display: true,
// ***** This is where I'm facing issues
type: 'linear', // When commented annotation doesn't get displayed
position: 'bottom',
scaleLabel: {
fontFamily: "Open Sans",
display: true,
labelString: 'Turn-Over in Lakh Rupees'
}
}
],
yAxes: [
{
id: 'y-axis-0',
display: true,
position: 'left',
scaleLabel: {
fontFamily: "Open Sans",
display: true,
labelString: 'Invites Available'
}
}
]
},
annotation: {
drawTime: 'afterDatasetsDraw',
annotations: [
{
type: 'line',
id: 'hline',
mode: 'vertical',
scaleID: 'x-axis-0',
value: $scope.ourFixData.lineAtPoint, // data-value at which the line is drawn
borderWidth: 1,
borderColor: 'blue',
borderDash: [4,5],
display: true,
title: "Current",
enabled: true,
label: {
fontFamily: "Open Sans",
backgroundColor: "blue",
content: $scope.ourFixData.lineAtPoint + " Lacks",
enabled: true,
position: 'top'
}
}
]
}
};
});
});
Any kind of help would be appreciated. Thanks in advance.

Visualization: Pie Chart Legend Text color based on Value

I'm using ng-google-chart (Google Chart Api Directive Module for AngularJS version 0.0.11) with Google Pie charts and I'm trying to display Legend Text in the same color as slices color.
Pie Chart View
Is there any way to place slices colors into the legend.textStyle option?
Pie Chart Options
drvPie.options = {
pieHole: 0.9,
pieSliceText: 'value',
pieSliceTextStyle: {
'fontSize': '25'
},
slices: {
0: { color: 'green' },
1: { color: 'orange' },
2: { color: 'red' }
},
height: '100%',
chartArea: {'width': '100%', 'height': '70%'},
legend: {
"textStyle": {
color: 'blue',
fontSize: 15
},
labeledValueText: 'value',
"position": "labeled"
}
};
Unfortunately it is not supported to specify a separate legend style per item, but you could consider the following solution that demonstrates how to customize legend labels:
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Task Status', 'Count'],
['At work', 22],
['Terminated', 3],
['Not working', 13]
]);
var options = {
pieHole: 0.9,
pieSliceText: 'value',
pieSliceTextStyle: {
'fontSize': '25'
},
slices: {
0: { color: 'green' },
1: { color: 'orange' },
2: { color: 'red' }
},
height: '100%',
chartArea: { 'width': '100%', 'height': '70%' },
legend: {
"textStyle": {
fontSize: 15
},
labeledValueText: 'value',
"position": "labeled"
}
};
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
google.visualization.events.addOneTimeListener(chart, 'ready', function(){
configureLegendLabel(data,options);
});
google.visualization.events.addListener(chart, 'onmouseover', function (e) {
configureLegendLabel(data,options);
});
google.visualization.events.addListener(chart, 'onmouseout', function (e) {
configureLegendLabel(data,options);
});
chart.draw(data, options);
}
function configureLegendLabel(data,options)
{
for(var key in options.slices){
var labelText = data.getValue(parseInt(key),0);
var label = $("text:contains('" + labelText + "')");
label.attr('fill',options.slices[key].color);
}
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['corechart']}]}"></script>
<div id="piechart" style="width: 900px; height: 500px;"></div>

Resources