Git Product home page Git Product logo

geonature's Introduction

GeoNature

branche backend frontend
master image image GeoNature
develop image image GeoNature

GeoNature V2 est une refonte complète de la BDD et changement de technologies :

  • Python
  • Flask
  • Leaflet
  • Angular
  • Bootstrap

Documentation sur https://docs.geonature.fr.

Application de saisie, de gestion, de synthèse et de diffusion d'observations faune et flore.

GeoNature est une application permettant de regrouper l'ensemble des données provenant des protocoles Faune et Flore, de saisir dans différents protocoles et de consulter l'ensemble de ces données dans une application de synthèse.

Celle-ci regroupe toutes les données des différents protocoles FAUNE et FLORE en les limitant au niveau QUI QUOI QUAND OU, en s'appuyant sur les référentiels, les standards et les nomenclatures du SINP.

Il est possible d'ajouter d'autres protocoles dans GeoNature sous forme de modules.

Une instance de démo est disponible sur http://demo.geonature.fr/geonature (admin / admin).

Présentation de GeoNature sur http://geonature.fr et dans http://geonature.fr/documents

Modules et projets liés

Gestion des utilisateurs

La gestion des utilisateurs est déportée dans l'application UsersHub (https://github.com/PnX-SI/UsersHub). Celle-ci permet de centraliser les utilisateurs et observateurs, de les ajouter dans un groupe et d'hériter directement de droits dans l'ensemble des applications (GeoNature, Faune, Flore, Geotrek, Police...).

A chaque ajout ou modification dans l'application UsersHub, sa base de données est mise à jour ainsi que tous les schémas utilisateurs des applications qui sont connectées à UsersHub.

Ne jamais modifier une donnée dans le schéma utilisateurs de GeoNature. Celui-ci est synchronisée automatiquement par les modifications apportées depuis l'application UsersHub dans le schéma utilisateurs de la BDD de UsersHub.

Attention aussi à ne jamais supprimer un utilisateur auquel serait associé des observations dans GeoNature. Vous pouvez lui supprimer ses identifiants de connexion et ses droits dans UsersHub mais surtout pas le supprimer car sinon le lien avec ses observations serait cassé.

Gestion de la taxonomie

GeoNature et les protocoles qui y sont intégrés s'appuient sur différentes listes de taxons. Celles-ci sont basées sur le référentiel national TAXREF du MNHN.

Pour chaque observation d'une espèce il est en effet crucial de garder un identifiant de référence du taxon pour pouvoir échanger et agglomérer les données avec d'autres structures.

Cependant, il est souvent nécessaire de limiter la liste des taxons à certaines espèces ou groupes. Voir d'ajouter des informations spécifiques sur chaque taxons (patrimonialité, statuts...).

Pour cela GeoNature s'appuie sur l'application TaxHub et sa structure de BDD qui est dupliquée dans le schéma taxonomie. Détails sur https://github.com/PnX-SI/TaxHub

image

Licence

  • OpenSource - GPL-3.0
  • Copyleft 2014-2023 - Parc National des Écrins - Parc national des Cévennes

image

image

geonature's People

Contributors

theolechemia avatar camillemonchicourt avatar bouttier avatar gildeluermoz avatar amandine-sahl avatar jbrieuclp avatar joelclems avatar gaetanbrl avatar donovanmaillard avatar jpm-cbna avatar flovollmer avatar adrien-pajot avatar quangphamll avatar pierrejego avatar cecchi-a avatar dependabot[bot] avatar metourneau avatar bastyen avatar vincentcauchois avatar pierre-narcisi avatar lpofredc avatar jbdesbas avatar ch-cbna avatar khanh-chau avatar ksamuel avatar andriacap avatar pnpyrenees avatar alainlaupinmnhn avatar ophdlv avatar xavyeah39 avatar

geonature's Issues

POC - Export d'un référentiel geo avec Data via module export + exploitation dans shiny

Export d'un référentiel geo via module export + exploitation dans shiny

Contexte/objectif

a retravailler, travail presque abouti sur shiny

SQL

create view gn_exports.v_ref_geo_commune_api as
select st_asgeojson(data.*)
from (
select id_area, area_name , area_code , geom
from ref_geo.l_areas la
where id_type = 25
--and area_code ilike '56007'
)data

Module export

https://geonature.bretagne-vivante.org/api/exports/api/6
https://geonature.bretagne-vivante.org/api/exports/api/7

Taxhub - Liste Nicheurs

https://taxhub.bretagne-vivante.org/#!/listes/107
https://taxhub.bretagne-vivante.org/api/taxref/allnamebylist/107

API Geonature

https://geonature.bretagne-vivante.org/api/exports/api/7
avec variable

https://geonature.bretagne-vivante.org/api/exports/api/7?limit=1000&offset=1000&geojson=geojson

Shiny

https://shiny.posit.co/r/articles/build/layout-guide/

DOC

Paste

https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/paste
https://www.digitalocean.com/community/tutorials/paste-in-r
https://stackoverflow.com/questions/5738831/r-plus-equals-and-plus-plus-equivalent-from-c-c-java-etc
https://stackoverflow.com/questions/51143588/convert-string-into-json-string-and-parsing-in-r
https://www.math.ucla.edu/~anderson/rw1001/library/base/html/character.html

While + Merge Data

https://www.w3schools.com/r/r_while_loop.asp
https://sparkbyexamples.com/r-programming/r-create-an-empty-dataframe/
https://stackoverflow.com/questions/26508519/how-to-add-elements-to-a-list-in-r-loop
https://statisticsglobe.com/merge-multiple-data-frames-of-list-in-r

Json

https://cran.r-project.org/web/packages/geojsonR/geojsonR.pdf
https://community.rstudio.com/t/fromjson-in-shiny-app/68306/3
https://cran.r-project.org/web/packages/geojsonR/vignettes/the_geojsonR_package.html
https://rstudio.github.io/leaflet/json.html
https://cran.r-project.org/web/packages/jsonlite/vignettes/json-paging.html
https://www.flother.is/til/postgis-geojson/
https://jsonlint.com/
https://stackoverflow.com/questions/37933084/how-to-display-multiple-polygons-at-once-using-leaflet-addgeojson-function
https://www.tutorialspoint.com/r/r_json_files.htm
https://community.rstudio.com/t/fromjson-in-shiny-app/68306/4
https://datatracker.ietf.org/doc/pdf/rfc7946.pdf#page=5
https://cran.r-project.org/web/packages/geojsonsf/vignettes/geojson-sf-conversions.html

Filter dataframe

https://datatofish.com/remove-column-dataframe-r/
https://stackoverflow.com/questions/47191727/r-filtering-by-two-columns-using-is-not-equal-operator-dplyr-subset
https://stackoverflow.com/questions/60129630/special-symbols-pattern-search-with-str-detect
https://stackoverflow.com/questions/22850026/filter-rows-which-contain-a-certain-string/40233929#40233929
https://tidyselect.r-lib.org/reference/starts_with.html
https://stackoverflow.com/questions/74019414/r-how-to-filter-rows-where-the-start-of-entries-match-a-list

Leaflet

https://stackoverflow.com/questions/47789632/customizing-leaflet-popup-in-r
https://rstudio.github.io/leaflet/json.html

add-polygons

https://stackoverflow.com/questions/29480795/add-polygons-to-r-shiny-leaflet-map
https://rdrr.io/cran/geoops/man/FeatureCollection.html
https://cran.r-project.org/web/packages/sf/vignettes/sf2.html

Colors (heatmap

https://r-graph-gallery.com/38-rcolorbrewers-palettes.html
https://www.rdocumentation.org/packages/leaflet.extras/versions/1.0.0/topics/addHeatmap
https://www.rdocumentation.org/packages/leaflet/versions/2.2.0/topics/colorNumeric
https://www.r-bloggers.com/2012/10/palettes-in-r/
https://stackoverflow.com/questions/51931610/r-leaflet-fill-polygons-with-colours

AddsearchFeature

https://campus.datacamp.com/courses/interactive-maps-with-leaflet-in-r/groups-layers-and-extras?ex=13

Legend

http://rstudio.github.io/leaflet/legends.html
https://leafletjs.com/examples/layers-control/
https://stackoverflow.com/questions/50641092/r-leaflet-map-change-legends-based-on-selected-layer-group
https://stackoverflow.com/questions/65572493/how-to-turn-off-the-layer-display-of-addlayerscontrol-first-when-launching-the-s

Export des données sensibles floutées

Export des donnée sensibles floutées

Issues utiles

PnX-SI#2558

Objectif

Ce que doit comporter cet export :
anonymiser les observateurs, les validateurs et supprimer les colonnes commentaires.
la geom calculée par la sensibilité

la vue de base est v_synthese_for_export et gn_synthese.synthese

Export par un membre BV

extrait des données des communes pour la période 2000-2023 pour les données sous statut "certain-très probable" ou "probable" (19 799 observations). Pour un projet d'ABC à l'échelle de ces communes. On a conventionné

Solution : export par un utilisateur avec permission limitée

a tester

Solution : export spécifique dans synthese

La requête suivante permet de renvoyer les géométries floutées en fonction du niveau de sensibilité :


SELECT
	s.id_synthese,
	COALESCE(a.geom, s.the_geom_4326) AS geom
FROM
	gn_synthese.synthese s
JOIN ref_nomenclatures.t_nomenclatures sensitivity
	ON s.id_nomenclature_sensitivity = sensitivity.id_nomenclature 
LEFT JOIN (
	gn_synthese.cor_area_synthese cas
		JOIN ref_geo.l_areas a ON a.id_area = cas.id_area
		JOIN ref_geo.bib_areas_types bat ON bat.id_type = a.id_type
		JOIN gn_sensitivity.cor_sensitivity_area_type sat ON bat.id_type = sat.id_area_type  
	) ON
		cas.id_synthese = s.id_synthese
		AND s.id_nomenclature_sensitivity = sat.id_nomenclature_sensitivity
WHERE sensitivity.cd_nomenclature != '4';

source PnX-SI#2558

Vue

Ces vues doivent obligatoirement avoir une colonne id_synthese, une colonne geojson_local représentant le geojson de la géometrie en projection locale (pour la génération du shapefile et geopackage) et une colonne geojson_4326 représentant le geojson de la géométrie en projection 4326 (pour la génération du geojson) (utilisez la fonction st_asgeojson - voir la vue par défaut gn_synthese.v_synthese_for_export)

https://github.com/PnX-SI/GeoNature/blob/8fae7270d75362c2292fe54be5258c6366b208ea/docs/admin-manual.rst#L467

Vue

CREATE OR REPLACE VIEW gn_synthese.v_synthese_for_export_floutage
AS SELECT s.id_synthese,
    s.date_min::date AS date_debut,
    s.date_max::date AS date_fin,
--    s.date_min::time without time zone AS heure_debut, -- non complété
--    s.date_max::time without time zone AS heure_fin, -- non complété
    t.cd_nom,
    t.cd_ref,
    t.nom_valide,
    t.nom_vern AS nom_vernaculaire,
    s.nom_cite,
    t.regne,
    t.group1_inpn,
    t.group2_inpn,
    t.group3_inpn,
    t.classe,
    t.ordre,
    t.famille,
    t.id_rang AS rang_taxo,
    s.count_min AS nombre_min,
    s.count_max AS nombre_max,
    s.altitude_min AS alti_min,
    s.altitude_max AS alti_max,
--    s.depth_min AS prof_min, -- non complété
--    s.depth_max AS prof_max, -- non complété
--    s.observers AS observateurs, -- anonymisation
    s.id_digitiser,
--    s.determiner AS determinateur, -- anonymisation
    sa.communes,
    coalesce (st_astext(floutage.geom),st_astext(s.the_geom_4326)) AS geometrie_wkt_4326,
--    st_x(s.the_geom_point) AS x_centroid_4326, 
--    st_y(s.the_geom_point) AS y_centroid_4326,
    coalesce (st_asgeojson(s.the_geom_4326) , st_asgeojson(floutage.geom)) AS geojson_4326,
    coalesce (st_asgeojson(s.the_geom_4326), st_asgeojson(floutage.geom)) AS geojson_local,
    s.place_name AS nom_lieu,
--    s.comment_context AS comment_releve, -- anonymisation
--    s.comment_description AS comment_occurrence, -- anonymisation
--    s.validator AS validateur, -- anonymisation
    n21.label_default AS niveau_validation,
    s.meta_validation_date AS date_validation,
--    s.validation_comment AS comment_validation, -- anonymisation
    s.digital_proof AS preuve_numerique_url,
    s.non_digital_proof AS preuve_non_numerique,
    d.dataset_name AS jdd_nom,
    d.unique_dataset_id AS jdd_uuid,
--    d.id_dataset AS jdd_id, -- inutile
    af.acquisition_framework_name AS ca_nom,
    af.unique_acquisition_framework_id AS ca_uuid,
--    d.id_acquisition_framework AS ca_id, -- inutile
    s.cd_hab AS cd_habref,
    hab.lb_code AS cd_habitat,
    hab.lb_hab_fr AS nom_habitat,
    s."precision" AS precision_geographique,
    n1.label_default AS nature_objet_geo,
    n2.label_default AS type_regroupement,
    s.grp_method AS methode_regroupement,
    n3.label_default AS technique_observation,
    n5.label_default AS biologique_statut,
    n6.label_default AS etat_biologique,
    n22.label_default AS biogeographique_statut,
    n7.label_default AS naturalite,
    n8.label_default AS preuve_existante,
    n9.label_default AS niveau_precision_diffusion,
    n10.label_default AS stade_vie,
    n11.label_default AS sexe,
    n12.label_default AS objet_denombrement,
    n13.label_default AS type_denombrement,
    n14.label_default AS niveau_sensibilite,
    n15.label_default AS statut_observation,
--    n16.label_default AS floutage_dee, -- données floutées dans le UNION
    n17.label_default AS statut_source,
    n18.label_default AS type_info_geo,
    n19.label_default AS methode_determination,
    n20.label_default AS comportement,
--    s.reference_biblio, -- anonymisation car url faune
--    s.entity_source_pk_value AS id_origine, --inutile
    s.unique_id_sinp AS uuid_perm_sinp,
    s.unique_id_sinp_grp AS uuid_perm_grp_sinp,
    s.meta_create_date AS date_creation,
--    s.meta_update_date AS date_modification, -- redondant
--    s.additional_data AS champs_additionnels, -- anonymisation
    COALESCE(s.meta_update_date, s.meta_create_date) AS derniere_action
   FROM gn_synthese.synthese s
     JOIN taxonomie.taxref t ON t.cd_nom = s.cd_nom
     JOIN gn_meta.t_datasets d ON d.id_dataset = s.id_dataset
     JOIN gn_meta.t_acquisition_frameworks af ON d.id_acquisition_framework = af.id_acquisition_framework
     LEFT JOIN ( SELECT cas.id_synthese,
            string_agg(DISTINCT a_1.area_name::text, ', '::text) AS communes
           FROM gn_synthese.cor_area_synthese cas
             LEFT JOIN ref_geo.l_areas a_1 ON cas.id_area = a_1.id_area
             JOIN ref_geo.bib_areas_types ta ON ta.id_type = a_1.id_type AND ta.type_code::text = 'COM'::text
          GROUP BY cas.id_synthese) sa ON sa.id_synthese = s.id_synthese
     LEFT JOIN ref_nomenclatures.t_nomenclatures n1 ON s.id_nomenclature_geo_object_nature = n1.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n2 ON s.id_nomenclature_grp_typ = n2.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n3 ON s.id_nomenclature_obs_technique = n3.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n5 ON s.id_nomenclature_bio_status = n5.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n6 ON s.id_nomenclature_bio_condition = n6.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n7 ON s.id_nomenclature_naturalness = n7.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n8 ON s.id_nomenclature_exist_proof = n8.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n9 ON s.id_nomenclature_diffusion_level = n9.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n10 ON s.id_nomenclature_life_stage = n10.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n11 ON s.id_nomenclature_sex = n11.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n12 ON s.id_nomenclature_obj_count = n12.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n13 ON s.id_nomenclature_type_count = n13.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n14 ON s.id_nomenclature_sensitivity = n14.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n15 ON s.id_nomenclature_observation_status = n15.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n16 ON s.id_nomenclature_blurring = n16.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n17 ON s.id_nomenclature_source_status = n17.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n18 ON s.id_nomenclature_info_geo_type = n18.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n19 ON s.id_nomenclature_determination_method = n19.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n20 ON s.id_nomenclature_behaviour = n20.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n21 ON s.id_nomenclature_valid_status = n21.id_nomenclature
     LEFT JOIN ref_nomenclatures.t_nomenclatures n22 ON s.id_nomenclature_biogeo_status = n22.id_nomenclature
     LEFT JOIN ref_habitats.habref hab ON hab.cd_hab = s.cd_hab
     -- Jointure Calcul geom floutée
	LEFT JOIN LATERAL (
	    SELECT
			COALESCE(ST_Transform(a.geom,4326), s.the_geom_4326) AS geom
	    FROM
	        gn_synthese.cor_area_synthese cas
	    JOIN ref_geo.l_areas a ON a.id_area = cas.id_area
	    JOIN ref_geo.bib_areas_types bat ON bat.id_type = a.id_type
	    JOIN gn_sensitivity.cor_sensitivity_area_type sat ON bat.id_type = sat.id_area_type
	    WHERE
	        cas.id_synthese = s.id_synthese
	        AND s.id_nomenclature_sensitivity = sat.id_nomenclature_sensitivity
	    LIMIT 1
	) floutage ON TRUE
	WHERE  -- règles floutage
     -- validation certaine et probable
     s.id_nomenclature_valid_status in (ref_nomenclatures.get_id_nomenclature('STATUT_VALID', '1'), ref_nomenclatures.get_id_nomenclature('STATUT_VALID', '2') )
     and 
     -- non diffusion mm floutée
     s.id_nomenclature_diffusion_level != ref_nomenclatures.get_id_nomenclature('NIV_PRECIS', '4') -- Aucune diffusion
     and 
     s.id_nomenclature_sensitivity != ref_nomenclatures.get_id_nomenclature('SENSIBILITE', '4') --Aucune diffusion
     ;

GRANT SELECT ON TABLE gn_synthese.v_synthese_for_export_floutage TO geonatadmin;

--------    
-- Tests    
select distinct ST_SRID(geom) from ref_geo.l_areas
    
    SELECT
	s.id_synthese,
	ST_SRID(COALESCE(ST_Transform(a.geom,4326), s.the_geom_4326)) AS geom
FROM
	gn_synthese.synthese s
JOIN ref_nomenclatures.t_nomenclatures sensitivity
	ON s.id_nomenclature_sensitivity = sensitivity.id_nomenclature 
LEFT JOIN (
	gn_synthese.cor_area_synthese cas
		JOIN ref_geo.l_areas a ON a.id_area = cas.id_area
		JOIN ref_geo.bib_areas_types bat ON bat.id_type = a.id_type
		JOIN gn_sensitivity.cor_sensitivity_area_type sat ON bat.id_type = sat.id_area_type  
	) ON
		cas.id_synthese = s.id_synthese
		AND s.id_nomenclature_sensitivity = sat.id_nomenclature_sensitivity
WHERE sensitivity.cd_nomenclature != '4';

Config

[SYNTHESE]
...
# Export custom dans synthese
EXPORT_OBSERVATIONS_CUSTOM_VIEWS = [
{
label = "Export obs certaine/probable avec anonymisation et floutage",
view_name = "gn_synthese.v_synthese_for_export_floutage",
},
]

MAJ de geonature pour 2.14.2 ok

Absence du type de financement dans la page de métadonnées

Version
Version de GeoNature affectée par le bug.

Description du bug
Absence du type de financement dans la page de métadonnées

Comportement attendue
Affichage du type de financement dans la page de métadonnées dans sa section

Comment reproduire
page metadata/dataset_detail

Logs
Extrait du fichier /var/log/geonature.log dans le cas d’une erreur 500.

Pistes

image

https://github.com/PnX-SI/GeoNature/blob/19e16f63c7e4a9481afcb92b68fdd86ff9a19747/backend/geonature/core/gn_meta/routes.py#L507

https://github.com/PnX-SI/GeoNature/blob/19e16f63c7e4a9481afcb92b68fdd86ff9a19747/frontend/src/app/metadataModule/af/af-card.component.html#L313

Tests


{
"nomenclature_financing_type": {
"active": true,
"cd_nomenclature": "1",
"definition_default": "Type de financement public",
"definition_fr": "Type de financement public",
"hierarchy": "111.001",
"id_broader": 0,
"id_nomenclature": 383,
"id_type": 111,
"label_default": "Publique",
"label_fr": "Publique",
"mnemonique": "Publique",
"source": "SINP",
"statut": "Validé"
}
}

      <div class="a" data-qa='pnx-metadata-acq-framework-id'> <b> Identifiant GeoNature du cadre d'acquisition :</b>
        {{af?.id_acquisition_framework}}</div>

  <b> Etendue territoriale : </b>{{ af?.nomenclature_territorial_level?.label_default }}
        </div>

      <div class="b">Créateur</div>

      <div class="a">
        <b> Créateur du cadre d'acquisition :</b>
        {{ af?.creator?.nom_complet || 'Non renseigné' }}
      </div>

V0

      <div class="b">Type de financement :</div>

      <div class="a">
        <b> Financement :</b>
        {{ af?.nomenclature_financing_type?.label_default }}
      </div>

Geonature - Error API sur login - génération token

Version
2.13.4

Description du bug
error API sur login + taxhub

https://taxhub.bretagne-vivante.org/api/taxref/allnamebylist/101

non fonctionnel -> error 500

Comportement attendu
Description du comportement attendu en lieu et place du problème rencontré.

Comment reproduire
Étapes à suivre pour reproduire le problème (sur quelle page se rendre, sur quel bouton cliquer, avec quelles données présentes, …).

Logs
Extrait du fichier /var/log/geonature.log dans le cas d’une erreur 500.

[Fri Feb 16 12:15:53.393527 2024] [proxy_http:error] [pid 32971:tid 140286911047424]
[client 192.168.30.2:51318] AH01114: HTTP: failed to make connection to backend: 127.0.0.1, referer: https://geonature.bretagne-vivante.org/


Tentative résolution

DOC

https://serverfault.com/questions/965602/apache-2-4-proxy-httperror-proxyerror

Issues similaires

PnX-SI#2521
https://wiki-sinp.cbn-alpin.fr/serveurs/installation/hosts-hostname

Auto-complétion - Amélioration de la recherche - bug accent

Version
Version de GeoNature 2.13.0

Description du bug
module pop reptile et amphibien
Non affichage des noms verns des espèces lorsqu'il y a un accent

Comportement attendue
affichage du vern avec accent
exemple pour pop
crapaud épineux ou triton alpestre

API Taxref MNHN

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.