Giter VIP home page Giter VIP logo

Comments (42)

jakubdonovan avatar jakubdonovan commented on May 23, 2024 1

There is no priceData parameter in the series. Must use data={priceData}

My bad, it works now. Thanks for your assistance

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024 1

I don't have this information. I hope it will happen this year. Support for 4.0 does not require much effort on my part and I will release a new version on the same day.

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

Please describe your configuration: bundler, node version, dev server and package manager. I will try to reproduce this problem.

My package is not well defined esmodule because it does not contain "type": "module" in package.json and does not use imports with file extensions. But it is easy to run it in sveltekit or bundle via webpack. Maybe I will able to make a workaround for your configuration.

I want to notice that the base package (lightweight-charts) currently does not support SSR at all. It will crash in node environment due to dom api calls (there is a workaround but it also depends on config). This should be fixed in [email protected] but it is still not yet released =(

from svelte-lightweight-charts.

jakubdonovan avatar jakubdonovan commented on May 23, 2024

Hey there, thanks for your prompt response.

Here's my config inside svelte.config.js

import adapter from '@sveltejs/adapter-auto';
import preprocess from 'svelte-preprocess';

/** @type {import('@sveltejs/kit').Config} */
const config = {
	// Consult https://github.com/sveltejs/svelte-preprocess
	// for more information about preprocessors
	preprocess: [
		preprocess({
			postcss: true
		})
	],
	kit: {
		adapter: adapter(),
		vits: {
			optimizeDeps: {
				include: ['lightweight-charts', 'svelte-lightweight-charts']
			}
		}
	}
};
export default config;

I'm on node v16.15.0, I use npm, and I use the default sveltekit dev server through npm run dev.

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

Ok, I see this warning on my side.

You need to add:

		vite: {
			ssr: {
				noExternal: ['lightweight-charts']
			}
		}

This will prevent Cannot use import statement outside a module and will allow to build SSR bundle.

svelte-lightweight-charts doesn't appear to be written in CJS, but also doesn't appear to be a valid ES module (i.e. it doesn't have "type": "module" or an .mjs extension for the entry point). Please contact the package author to fix.
Cannot use import statement outside a module`

Unfortunately this one requires some changes to my package. I will try to figure out how I can fix this and release a new version. It looks like a warning not a blocker. If you have any further problems feel free to write me.

from svelte-lightweight-charts.

jakubdonovan avatar jakubdonovan commented on May 23, 2024

ssr: {
noExternal: ['lightweight-charts']
}

This will do for now. Thank you

from svelte-lightweight-charts.

jakubdonovan avatar jakubdonovan commented on May 23, 2024

Ok, I see this warning on my side.

You need to add:

		vite: {
			ssr: {
				noExternal: ['lightweight-charts']
			}
		}

This will prevent Cannot use import statement outside a module and will allow to build SSR bundle.

svelte-lightweight-charts doesn't appear to be written in CJS, but also doesn't appear to be a valid ES module (i.e. it doesn't have "type": "module" or an .mjs extension for the entry point). Please contact the package author to fix.
Cannot use import statement outside a module`

Unfortunately this one requires some changes to my package. I will try to figure out how I can fix this and release a new version. It looks like a warning not a blocker. If you have any further problems feel free to write me.

Unfortunately, adding this to my config did not solve the issue and I still get error Cannot use import statement outside a module

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

Try removing /node_modules/.vite/ folder and restart dev server. If it does not help, give me your npm list. I will install exactly the same versions of packages as you.

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

I've published next beta. Try npm install svelte-lightweight-charts@next.

Add to your config:

vite: {
	ssr: {
		noExternal: ['svelte-lightweight-charts', 'lightweight-charts']
	}
}

This version should run without any warnings and should reserve space for the chart in SSR. This means that there will be no "jumps" when the chart is initialized.

from svelte-lightweight-charts.

jakubdonovan avatar jakubdonovan commented on May 23, 2024

@trash-and-fire Hey, it looks like the lib stopped working after the recent sveltekit changes.

I moved the following into my vite.config.js

ssr: {
		noExternal: ['lightweight-charts']
	}

vite.config.js

import path from 'path';
import { sveltekit } from '@sveltejs/kit/vite';

/** @type {import('vite').UserConfig} */
const config = {
	plugins: [sveltekit()],

	ssr: {
		noExternal: ['lightweight-charts']
	}
};

export default config;

Unexpected token 'export'
/Users/jakubdonovan/Documents/code/shieldprotocol/node_modules/fancy-canvas/coordinate-space.js:4
export function bindToDevicePixelRatio(canvas, options) {
^^^^^^
SyntaxError: Unexpected token 'export'
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1033:15)
at Module._compile (node:internal/modules/cjs/loader:1069:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at ModuleWrap. (node:internal/modules/esm/translators:170:29)
at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:385:24)

Here is a minimal repo to reproduce the errors:
https://github.com/jakubdonovan/svelte-lightweight-charts-minimal

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

Yes, svelte-kit has had many breaking changes and is currently in a very unstable state. You are correct in moving the ssr section to vite.config.js.

Try using svelte-lightweight-charts@next as described here https://github.com/trash-and-fire/svelte-lightweight-charts#ssr-and-sveltekit.

I'll try it myself with the latest version of svelte-kit when I have time.

from svelte-lightweight-charts.

jakubdonovan avatar jakubdonovan commented on May 23, 2024

I followed the instructions and got the following error

500
Cannot use import statement outside a module

/Users/jakubdonovan/Documents/code/svelte-lightweight-charts-minimal/node_modules/lightweight-charts/dist/lightweight-charts.esm.development.js:7
import { bindToDevicePixelRatio } from 'fancy-canvas/coordinate-space';
^^^^^^

SyntaxError: Cannot use import statement outside a module
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1033:15)
at Module._compile (node:internal/modules/cjs/loader:1069:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object. (/Users/jakubdonovan/Documents/code/svelte-lightweight-charts-minimal/node_modules/lightweight-charts/index.js:6:19)
at Module._compile (node:internal/modules/cjs/loader:1105:14)

Here's what I did:
npm install svelte-lightweight-charts@next

"dependencies": {
    "lightweight-charts": "^3.8.0",
    svelte-lightweight-charts": "^1.7.0-next.0"
}

my vite.config.js

import { sveltekit } from '@sveltejs/kit/vite';

/** @type {import('vite').UserConfig} */
const config = {
	plugins: [sveltekit()],
	kit: {
		prerender: { default: true },
		ssr: {
			noExternal: ['svelte-lightweight-charts', 'lightweight-charts']
		}
	}
};
export default config;

I have also pushed the above changes to the minimal repo I linked in my previous comment.

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

I fixed dev mode with this config.

import { sveltekit } from '@sveltejs/kit/vite';

/** @type {import('vite').UserConfig} */
const config = {
	plugins: [sveltekit()],
	ssr: {
		noExternal: [
			'svelte-lightweight-charts',
			'lightweight-charts',
			'fancy-canvas',
		]
	},
};

export default config;

Unfortunately preview/build mode is not working yet. I'm trying to figure out why.

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

Oh, I'm confused with the commands.. Build preview also works.

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

The next version will be 2.0.0 with 4.0.0 charts which should work on server rendering without any extra effort.

from svelte-lightweight-charts.

jakubdonovan avatar jakubdonovan commented on May 23, 2024

I added fancy-canvas to my noExternals and got this error

500
Cannot use import statement outside a module

/Users/jakubdonovan/Documents/code/svelte-lightweight-charts-minimal/node_modules/lightweight-charts/dist/lightweight-charts.esm.development.js:7
import { bindToDevicePixelRatio } from 'fancy-canvas/coordinate-space';
^^^^^^

SyntaxError: Cannot use import statement outside a module
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1033:15)
at Module._compile (node:internal/modules/cjs/loader:1069:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object. (/Users/jakubdonovan/Documents/code/svelte-lightweight-charts-minimal/node_modules/lightweight-charts/index.js:6:19)
at Module._compile (node:internal/modules/cjs/loader:1105:14)

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

Try removing .svelte-kit folder from the root of the project. May be it is kind of cache or something.

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

Did not help. Did you try with my repo?

Yes, I did it with your repo. Note that there is no kit field in vite.config.js. Are you sure you are copying correctly?

from svelte-lightweight-charts.

jakubdonovan avatar jakubdonovan commented on May 23, 2024

Did not help. Did you try with my repo?

Yes, I did it with your repo. Note that there is no kit field in vite.config.js. Are you sure you are copying correctly?

Did the chart actually render for you? I just see a big black rectangle
https://imgur.com/18GosJW

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

There is no priceData parameter in the series. Must use data={priceData}

from svelte-lightweight-charts.

jakubdonovan avatar jakubdonovan commented on May 23, 2024

@trash-and-fire Hey there brother, quick question. How would I access the chart container to add UI elements as seen below?
Screenshot 2022-09-12 at 23 44 19

Your doc states that the container property can be used in the config like so:

 const chartOptions = {
	// container: { ref },
	container?: {
    	  ref?: (element: HTMLElement | null) => void;
    	  class?: string;
    	  id?: string;
	},
	width: 600,
	height: 400,
	etc........
}

But unfortunately, that did not work for me due to [svelte-preprocess] Encountered type error

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

See an example of a legend. This is close to what you want to do.

As for the properties of the container, they are slightly for other situations.

from svelte-lightweight-charts.

jakubdonovan avatar jakubdonovan commented on May 23, 2024

See an example of a legend. This is close to what you want to do.

As for the properties of the container, they are slightly for other situations.

Your doc mentions that ref should be used to access the chart instance, do you have an example showing that?

Also, the code snippet from your example logs undefined

function handleCrosshairMove({ detail: param }) {
    if (param.time) {
        const price = param.seriesPrices.get(CandlestickSeries);
        console.log(price);
    } else return;
}

I tried to access the price data via param.seriesPrices.get(this.CandlestickSeries) as suggested in another doc, but I always get undefined.

I am able to view the OHLC data with console.log(param.seriesPrices) but I can't access it in the code or do anything with it.
Screenshot 2022-09-13 at 06 25 32

Do you know why this happens?

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

I would recommend using on:crosshairMove to subscribe to the crosshair event. This is equivalent to a direct subscription to an instance.

A chart instance reference is also available, but should be used for one-time actions such as taking a screenshot or fitting content.

<script>
    let chartApi;
</script>
<Chart width={400} height={300} ref={(ref) => chartApi = ref}/>
<button on:click={() => chartApi.takeScreenshot()}>Take screenshot</button>
<button on:click={() => chartApi.timeScale().fitContent()}>Fit Content</button>

In your case, I think the problem is the CandlestickSeries. You need to get ref to the series via

<script>
let series;
</script>
<CandlestickSeries ref={(api) => series = api}/>

And then you can use series in the expression const price = param.seriesPrices.get(series)

from svelte-lightweight-charts.

jakubdonovan avatar jakubdonovan commented on May 23, 2024

ref={(api) => series = api}

Thank you, that did it!

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

You can have many series on a chart, such as a main series and a moving average series. Therefore, you need to ask the price for a specific instance of the series.

from svelte-lightweight-charts.

jakubdonovan avatar jakubdonovan commented on May 23, 2024

You can have many series on a chart, such as a main series and a moving average series. Therefore, you need to ask the price for a specific instance of the series.

I have a question regarding the reactive property. Aassuming that it's the equivalent to chart.setData(), I have set it to true and I am now able to switch to another data set via

function handleIntervalSwitch(interval) {
	seriesOptions.data = data2;
}

but the chart position does not reset. The initial data is only a couple candles long do it does not fill the chart container, but the data set I switch to is, yet it ends where the original does and the chart area does not get filled.

83f457207d953d4d76f10cca6427910f.mp4

EDIT: I managed to access the 'ITimeScaleApi' and used .scrollToRealTime() to scroll the chart when needed.

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

Could you please provide a minimal reproduction of the issue with reactive data.

Also keep in mind that data2 must not be equal to seriesOptions.data. To be sure, try this:

function handleIntervalSwitch(interval) {
	seriesOptions = {
		...seriesOptions,
		data: [...data2],
	}
}

or just this:

function handleIntervalSwitch(interval) {
	seriesOptions.data = [...data2];
}

I have a demo where data is reactive.

from svelte-lightweight-charts.

jakubdonovan avatar jakubdonovan commented on May 23, 2024

Could you please provide a minimal reproduction of the issue with reactive data.

Also keep in mind that data2 must not be equal to seriesOptions.data. To be sure, try this:

function handleIntervalSwitch(interval) {
	seriesOptions = {
		...seriesOptions,
		data: [...data2],
	}
}

or just this:

function handleIntervalSwitch(interval) {
	seriesOptions.data = [...data2];
}

I have a demo where data is reactive.

Hey again, I used your lib to create a sparkline with coingecko data and I'm experiencing a bug I'm not quite sure how to tackle. I have 3 items, and for each item, I render a card with its own sparkline. The problem is that more often than not, only the first one will render and the others will not until I switch to another route and then switch back. And then if I do it again, they will disappear again.

Firefox.Developer.Edition.-.24.September.2022.mp4

Here is a minimal reproduction repo:
https://github.com/jakubdonovan/svelte-lightweight-charts-minimal/tree/coingecko-sparkline

and here is the code

+page.svelte

<script>
  import { tokens } from '$lib/stores/tokens';
  import TokenCard from '$lib/components/TokenCard.svelte';
  import { isEmpty } from '$lib/utils/index';
</script>

<main class="h-screen bg-gray-100">
  <div class="max-w-7xl flex items-center justify-center p-4 h-full gap-2">
	{#if !isEmpty($tokens)}
		{#each Object.values($tokens) as token}
			{#if !isEmpty(token.coingecko_data || {})}
				<TokenCard id={token.coingecko_data.id} prices={token.coingecko_data.prices} />
			{/if}
		{/each}
	{/if}
  </div>
</main>

+TokenCard.svelte

<script>
  import Sparkline from '$lib/components/Sparkline.svelte';
  export let id, prices;
</script>

<div class="flex flex-col items-center gap-2 rounded-lg p-2 shadow-sm bg-white text-gray-600 text-xs">
  {id}
  <Sparkline data={prices} />
</div>

Sparkline.svelte

<script>
  import { Chart, AreaSeries } from 'svelte-lightweight-charts';
  import { formatCurrency } from '@coingecko/cryptoformat';
  export let data;

  let priceData = data.reverse().map(([time, value]) => ({ time, value }));

  const chartOptions = {
	height: 60,
	width: 150,
	layout: {
		backgroundColor: 'rgba(255, 255, 255, 0)',
		textColor: '#71717A'
	},
	grid: {
		vertLines: {
			visible: false
		},
		horzLines: {
			visible: false
		}
	},
	crosshair: {
		mode: 0,
		horzLine: {
		    visible: false
		},
		vertLine: {
			visible: false
		}
	},
	timeScale: {
		rightOffset: 0,
		borderVisible: false,
		barSpacing: 5,
		fixLeftEdge: true,
		timeVisible: false,
		visible: false
	},
	priceScale: {
		borderVisible: false,
		visible: false
	},
	rightPriceScale: {
		visible: false
	}
};

  const seriesOptions = {
	data: priceData,
	reactive: true,
	// lineColor: data[data.length - 1].value >= data[0].value ? '#57BD0D' : '#EE5465',
	lineColor: '#5472cc',
	lineWidth: 2,
	topColor: 'rgba(255, 255, 255, 0)',
	bottomColor: 'rgba(255, 255, 255, 0)',
	priceLineVisible: false,
	borderVisible: false
};
</script>

<Chart {...chartOptions}>
	<AreaSeries {...seriesOptions} />
</Chart>

Do you think you can please take a look and see what's causing it?

from svelte-lightweight-charts.

jakubdonovan avatar jakubdonovan commented on May 23, 2024

Could you please provide a minimal reproduction of the issue with reactive data.

Also keep in mind that data2 must not be equal to seriesOptions.data. To be sure, try this:

function handleIntervalSwitch(interval) {
	seriesOptions = {
		...seriesOptions,
		data: [...data2],
	}
}

or just this:

function handleIntervalSwitch(interval) {
	seriesOptions.data = [...data2];
}

I have a demo where data is reactive.

Just replying again in case you didn't see my earlier comment

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

Please create mocks for your data. Don't really want to go to unknown hosts.

Check this line https://github.com/jakubdonovan/svelte-lightweight-charts-minimal/blob/coingecko-sparkline/src/lib/stores/tokens.js#L14 please. It looks like you never add new keys to an object.

from svelte-lightweight-charts.

matthewwwz avatar matthewwwz commented on May 23, 2024

The next version will be 2.0.0 with 4.0.0 charts which should work on server rendering without any extra effort.

Do you have any information about the release date of 4.0 lightweight chart?

from svelte-lightweight-charts.

Swoorup avatar Swoorup commented on May 23, 2024

I fixed dev mode with this config.

import { sveltekit } from '@sveltejs/kit/vite';

/** @type {import('vite').UserConfig} */
const config = {
	plugins: [sveltekit()],
	ssr: {
		noExternal: [
			'svelte-lightweight-charts',
			'lightweight-charts',
			'fancy-canvas',
		]
	},
};

export default config;

Unfortunately preview/build mode is not working yet. I'm trying to figure out why.

Looks like this no longer works due to upstream changes. But I am also unable to find a replacement for it :/

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

@Swoorup

It still works for me with the following versions:

├── @sveltejs/[email protected]
├── @sveltejs/[email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]

Please provide minimal reproduction, or at least your npm ls log.

from svelte-lightweight-charts.

Swoorup avatar Swoorup commented on May 23, 2024
❯ npm ls
├── @improbable-eng/[email protected]
├── @rxjs-ninja/[email protected]
├── @sveltejs/[email protected]
├── @sveltejs/[email protected]
├── @sveltestack/[email protected]
├── @svelteuidev/[email protected]
├── @svelteuidev/[email protected]
├── @tailwindcss/[email protected]
├── @testing-library/[email protected]
├── @threlte/[email protected]
├── @threlte/[email protected]
├── @types/[email protected]
├── @types/[email protected]
├── @typescript-eslint/[email protected]
├── @typescript-eslint/[email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]
Unexpected token 'export'
webui/node_modules/fancy-canvas/coordinate-space.js:4
export function bindToDevicePixelRatio(canvas, options) {
^^^^^^

SyntaxError: Unexpected token 'export'
    at Object.compileFunction (node:vm:360:18)
    at wrapSafe (node:internal/modules/cjs/loader:1088:15)
    at Module._compile (node:internal/modules/cjs/loader:1123:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Module.load (node:internal/modules/cjs/loader:1037:32)
    at Module._load (node:internal/modules/cjs/loader:878:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:169:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:518:24)

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

Try using npm install svelte-lightweight-charts@next

from svelte-lightweight-charts.

Swoorup avatar Swoorup commented on May 23, 2024

Try using npm install svelte-lightweight-charts@next

Still the same issue with export. Think this is the PR that resulted in a drastic change to SSR config :/
sveltejs/kit#6197

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

You have the same version of @svelte/kit as I do. Try deleting the .svelte-kit folder and restart.

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

I don't see vite in your dependencies. What version of vite do you have? Try using npm install vite@latest

from svelte-lightweight-charts.

Swoorup avatar Swoorup commented on May 23, 2024

Tried deleting .svelte-kit along with vite@latest install still the same issue.

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

I double checked this. I removed node_modules and .svelte-kit, ran npm install. The result is the same: it still works seamlessly with the latest version of svelte-kit.

Can you provide a demo with the issue?

from svelte-lightweight-charts.

trash-and-fire avatar trash-and-fire commented on May 23, 2024

You can use [email protected]

from svelte-lightweight-charts.

Related Issues (20)

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.