Git Product home page Git Product logo

flutter_blurhash's People

Contributors

cbenhagen avatar deakjahn avatar f-person avatar lyio avatar renefloor avatar rkunboxed avatar robert-scub avatar rydein avatar slightfoot avatar solido avatar werainkhatri avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flutter_blurhash's Issues

onDecoded is not firing

We see onDecoded in the packages API however It is not connected to the related action at the moment.
There is no instance of call(widget.onDecoded)
Could you please add onDecoded on both the nullsafe and nullable versions.

Array of input blurhashes

Would it make sense to create a way for the user of flutter_blurhash to be able to provide an array of incrementaly bigger blurhashes so they would render in that order to make an ilusion of loading a clean image.

example:
AspectRatio( aspectRatio: 1.6, child: BlurHash( hashes: ["L5H2EC=PM+yV0g-mq.wG9c010J}I", "L5H2EC=PM+yV0g-mq.wG9c010J}IL5H2EC=PM+yV0g-mq.wG9c010J}I", "L5H2EC=PM+yV0g-mq.wG9c010J}IL5H2EC=PM+yV0g-mq.wG9c010J}IL5H2EC=PM+yV0g-mq.wG9c010J}IL5H2EC=PM+yV0g-mq.wG9c010J}I",] ), ),

Disable fade effect after image loaded

Hi,

Thanks for wonderful library.

When scrolling in a long list i see fade effect occurs again. This causes lag even in production release.
Can you add an option to disable effect after initial load?

Thanks!

Not Working with Flutter version 3.19.5, Dart version 3.3.3

Facing the below mentioned error, while upgrading my project to Flutter version 3.19.5, Dart version 3.3.3

../../../../../../.pub-cache/git/flutter_blurhash-f4f19e180ba3f689abb7a047c21100c4cfe83fb7/lib/src/blurhash_widget.dart:201:42:

Error: 'DecoderCallback' isn't a type.
ImageStreamCompleter load(UiImage key, DecoderCallback decode) =>
^^^^^^^^^^^^^^^

Dart 3.3.3 does not have the "DecoderCallback". hence, flutter is not able to find it.

My flutter doctor output:

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.19.5, on macOS 14.4.1 23E224 darwin-arm64, locale en-IN)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.3)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2023.2)
[✓] VS Code (version 1.87.2)
[✓] Connected device (4 available)
[✓] Network resources

• No issues found!

Images Flickers while loading

While Using BlurHash as placee holder in Cached Network image, it flickers while loading the image for the first time.

Flutter web canvaskit crash in flutter master 2.6.0 version

When read blur hash widget, there is error as below:
════════ Exception caught by scheduler library ═════════════════════════════════
The following assertion was thrown during a scheduler callback:
Assertion failed: org-dartlang-sdk:///flutter_web_sdk/lib/_engine/engine/canvaskit/skia_object_cache.dart:248:12
!browserSupportsFinalizationRegistry
is not true

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel master, 2.6.0-6.0.pre.146, on macOS 11.0.1 20B29
darwin-x64, locale zh-Hant-TW)
[!] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
✗ cmdline-tools component is missing
Run path/to/sdkmanager --install "cmdline-tools;latest"
See https://developer.android.com/studio/command-line for more details.
✗ Android license status unknown.
Run flutter doctor --android-licenses to accept the SDK licenses.
See https://flutter.dev/docs/get-started/install/macos#android-setup for
more details.
[✓] Xcode - develop for iOS and macOS (Xcode 12.5.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 3.6)
[✓] VS Code (version 1.60.1)
[✓] Connected device (1 available)

Get the hash from an image?

Hi friends,

I have an issue with flutter_blurhash, how to get the hash code from an image in Flutter?
I can't find any details for this :(

Thanks in advance!

Cannot clone a disposed image

I know this is a duplicated issue.

Please consider a fix. Its causing headache while in development (non fatal exception).
As well as in production it's sending so many reports to Crashlytics.

Non-fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: Bad state: Cannot clone a disposed image.
The clone() method of a previously-disposed Image was called. Once an Image object has been disposed, it can no longer be used to create handles, as the underlying data may have been released.. Error thrown Instance of 'ErrorDescription'.
       at Image.clone(Image.java)
       at ImageInfo.clone(image_stream.dart:51)
       at ImageStreamCompleter.setImage(image_stream.dart:635)Ï

Screen Shot 2022-04-21 at 10 38 12 PM

Update packages

A few things that can be updated:

Decoding freezes UI

Decoding (math operations) proceeds in UI isolate. This cause lags when scrolling list with images (like Instagram feed).

Very slow when in ListView

The screen is freezing.
Here is what I did

import 'package:flutter_blurhash/flutter_blurhash.dart';

class BlurHashPage extends StatelessWidget {
  var hashList = [
    "L5H2EC=PM+yV0g-mq.wG9c010J}I",
    'LEHV6nWB2yk8pyo0adR*.7kCMdnj',
    "BkF=hb}MQ+=S#lNL",
    "B6C=+r000000?d9p",
    "BWJaZl^:^ky__\$jb",
    "BEM3Hy?K0x,.wgI=",
    "BWFpeiEb=RNx;EW?",
  ];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Blur Hash"),
      ),
      body: ListView.builder(
        itemCount: hashList.length,
        itemBuilder: (context, index) {
          return Card(
            clipBehavior: Clip.hardEdge,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(10.0),
            ),
            child: SizedBox(
              height: 200,
              child: BlurHash(
                hash: hashList[index],
                color: Colors.lightBlue,
              ),
            ),
          );
        },
      ),
    );
  }
}

slow performance

as a snippet code:

    return ListView.builder(
      itemCount: 100,
      itemBuilder: (_, index) => Container(
        height: 200,
        child: ListView.builder(
          itemCount: 20,
          scrollDirection: Axis.horizontal,
          itemBuilder: (_, index) => BlurHash(
            image: 'https://picsum.photos/200/300',
            color: Colors.red,
            hash: '',
          ),
        ),
      ),
    );

as you can see the performance of using Image.network is very sensible.
is there any solution to fix it?

Add BlurHash encoding

There are some use-cases where it is useful to perform encoding on the device, e.g. when sending large images using e2e encryption.

Adding encoding to this package would support that use case without including another dependency. I'm not too familiar with the BlurHash algorithm but I suspect this wouldn't add much code to the implementation.

For reference, here's the blurhash_dart implementation, which itself has no dependencies: https://github.com/justacid/blurhash-dart/blob/master/lib/src/blurhash.dart#L70

CacheManager

Is there a way to control CacheManager?

Today we have added Blurhash like below, but I noticed we could also add in the actual url to blurhash as a parameter, and thus perhaps we could eliminate a lot of our own code (and hopefully piggyback-ride onto an smoother transition from blur to image).

CachedNetworkImage(
  imageUrl: url,
  fadeInCurve: Curves.linear,
  fadeOutCurve: Curves.linear,
  fit: BoxFit.cover,
  width: width,
  height: height,
  fadeInDuration: Duration(milliseconds: 250),
  fadeOutDuration: Duration(milliseconds: 250),
  cacheManager: CacheManager(
    Config(
      url,
      maxNrOfCacheObjects: 500,
      stalePeriod: stalePeriod ?? const Duration(days: 30),
    ),
  ),
  placeholder: Stack(
    fit: StackFit.expand,
    children: [
      BlurHash(
        hash: image.blurhash,
        imageFit: BoxFit.cover,
      ),
      Center(
        child: LoadingSpinner(
          radius: spinnerRadius ?? 15,
          strokeWidth: spinnerStrokeWidth ?? 1,
        ),
      ),
    ],
  ),
  errorWidget: (context, _, __) => ProfilePlaceholder(width: width, height: height),
)

However, it would be ideal for us to control errorWidget as well as the cacheManager.

Error: The method 'objectRuntimeType' isn't defined for the class 'BlurHashImage'

Hi, I'm getting this exception while building an app.

Error output from Xcode build:
↳
    ** BUILD FAILED **
Xcode's output:
↳
    Compiler message:
    ../../.pub-cache/hosted/pub.dartlang.org/flutter_blurhash-0.4.0/lib/src/blurhash_image.dart:76:10: Error: The method 'objectRuntimeType' isn't defined for the class 'BlurHashImage'.
     - 'BlurHashImage' is from 'package:flutter_blurhash/src/blurhash_image.dart' ('../../.pub-cache/hosted/pub.dartlang.org/flutter_blurhash-0.4.0/lib/src/blurhash_image.dart').
    Try correcting the name to the name of an existing method, or defining a method named 'objectRuntimeType'.
          '${objectRuntimeType(this, 'BlurHashImage')}(${describeIdentity(blurHash)}, scale: $scale)';
             ^^^^^^^^^^^^^^^^^
    Target kernel_snapshot failed: Exception: Errors during snapshot creation: null
    Failed to build bundle.
    Command PhaseScriptExecution failed with a nonzero exit code
    note: Using new build system
    note: Planning build
    note: Constructing build description
Could not build the precompiled application for the device.

Does not work on web

Hello. Very nice package, but it is not working on web even stated so in https://pub.dev/packages/flutter_blurhash

I noticed you closed an issue 20 days ago about this, but not before fooling a lot around with the package as it was supposed to work on web.

Could you remove the web compability notice on the package listing until the flutter web framework is compatible....?

[Feature] add errorBuilder

Hi, and thank u for such a good library!

It would be nice to have some analog Image.errorBuilder so we can show custom widget in case of error.

Dart sound null-safety

I was wondering if there are any plans on migrating the library to use non-nullable types and use Dart 2.12.0 in the future.

Universal BlurHash widget

Remote resource to download image is very specific way to use BlurHash widget.
Images could be loaded in many different ways using different protocols.
Could be nice to make BlurHash widget universal.

Error: Type 'DecoderCallback' not found. blurhash_widget.dart:218

I'm getting the following error when using flutter_blurhash: ^0.7.0 and Flutter 3.16.0

../../../../../.pub-cache/hosted/pub.dev/flutter_blurhash-0.7.0/lib/src/blurhash_widget.dart:218:42: Error: Type 'DecoderCallback'
not found.
  ImageStreamCompleter load(UiImage key, DecoderCallback decode) => OneFrameImageStreamCompleter(_loadAsync(key));

Recomended image resolutions for the algorithm

For example when we encode an image of 800x600px does the blurhash represantation have a native resolution of 800x600px too? Or is it fixed?
Or does it not matter and it is like a vectoral represantation and we can display the blurhash as big as we want?
Also is it better in terms of performance to encode images after downsizing them to resolutions corresponding to the placeholders size on our UI?

Encoding BlurHash from Image in dart

First of all thank you for introducing us Flutter community with this great tool. It is a game changer.
For this to reach to broader developers I think we should be able to encode the image to it's corresponding blurhash string. Are you planning on writing a function which does this on the client.
This way we can upload the image along with the blurhash to Firestore and Firebase Storage at the same time.
People might not be using server side code(cloud functions) since they will bring extra pricing/delay/performance issues. If this is not a good way, then I hope someone would show an cloud function example in type script.

Build failed on Flutter Master channel

DecoderCallback is deprecated since Flutter 2.13 and it is now removed in flutter/flutter#132679

    DecoderCallback decode,
    ^^^^^^^^^^^^^^^
../../AppData/Local/Pub/Cache/hosted/pub.dev/flutter_blurhash-0.7.0/lib/src/blurhash_widget.dart:218:42: Error: Type 'DecoderCallback' not found.
  ImageStreamCompleter load(UiImage key, DecoderCallback decode) => OneFrameImageStreamCompleter(_loadAsync(key));
                                         ^^^^^^^^^^^^^^^
../../AppData/Local/Pub/Cache/hosted/pub.dev/flutter_blurhash-0.7.0/lib/src/blurhash_image.dart:32:48: Error: Type 'DecoderCallback' not found.
  ImageStreamCompleter load(BlurHashImage key, DecoderCallback decode) => OneFrameImageStreamCompleter(_loadAsync(key));
                                               ^^^^^^^^^^^^^^^

Version 0.6.6 - Huge memory consumption and Crash

After Upgrading from 0.6.4 to 0.6.6,

I noticed huge lag while scrolling into multiple images that use BlurHash as loading widget.

I also noticed significant memory consumption and multiple _spawn stacks being generated.

Reverting back to 0.6.4 fixes the issue.

Extract color avarages from the BlurHash(for whole image and for seperate sides)

Can't compile

Using your exemple project with flutter_blurhash: ^0.4.0, I can't compile on Android :

Compiler message:
/C:/ProgramData/Flutter/.pub-cache/hosted/pub.dartlang.org/flutter_blurhash-0.4.0/lib/src/blurhash_image.dart:76:10: Error: The method 'objectRuntimeType' isn't defined for the class 'BlurHashImage'.
 - 'BlurHashImage' is from 'package:flutter_blurhash/src/blurhash_image.dart' ('/C:/ProgramData/Flutter/.pub-cache/hosted/pub.dartlang.org/flutter_blurhash-0.4.0/lib/src/blurhash_image.dart').
Try correcting the name to the name of an existing method, or defining a method named 'objectRuntimeType'.
      '${objectRuntimeType(this, 'BlurHashImage')}(${describeIdentity(blurHash)}, scale: $scale)';
         ^^^^^^^^^^^^^^^^^
Target kernel_snapshot failed: Exception: Errors during snapshot creation: null
build failed.

FAILURE: Build failed with an exception.

Any idea how to fix this ?

BlurHash shadow

Let's say we use a Stack and place the BlurHash image on bottom and the actual image on top(BlurHash image being a little bigger than the actual image). I haven't tried but just by imagining, this might end up with a cool shadow effect instead of the normal fixed color shadows. Of course in this case we would need to gradually decrease the opacity of the blurhas image for it to look like a real shadow.

Bad state: Cannot clone a disposed image

The clone() method of a previously-disposed Image was called. Once an Image object has been disposed, it can no longer be used to create handles, as the underlying data may have been released.

Navigate new screen and back to blur hash screen, I am getting this error

How to use with flutter_blurhash CachedNetworkImage?

It's possible to use CachedNetworkImage with flutter_blurhash ?

CachedNetworkImage( imageUrl: widget.imageUrls[0], height: MediaQuery.of(context).size.height * 0.5, width: MediaQuery.of(context).size.width, fit: BoxFit.cover, placeholder: (context, url) => const Padding( child: CupertinoActivityIndicator(), padding: EdgeInsets.all(20.0)), errorWidget: (context, url, error) => const Icon(Icons.error), );

thanks in advance!

Build Error with flutter_blurhash: 'DecoderCallback' Type Not Found on iOS Build

Issue Overview:

I'm encountering a build error when trying to compile my Flutter app for iOS. The error is specifically mentioning a missing DecoderCallback type.

Flutter Doctor:

Click to expand
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.16.0, on macOS 14.1.1 23B81 darwin-arm64, locale
    en-KW)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.2)
[✓] VS Code (version 1.84.2)
[✓] Connected device (3 available)
    ! Error: Browsing on the local area network for iPhone 11 Pro Max. Ensure
      the device is unlocked and attached with a cable or associated with the
      same local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code
      -27)
[✓] Network resources

• No issues found!

Error Output:

Click to expand
Launching lib/main.dart on iPhone 15 Pro Max in debug mode...
main.dart:1
Automatically signing iOS for device deployment using specified development team in Xcode project: L5GMX9Y2JD
Xcode build done.                                           227.0s
Failed to build iOS app
Could not build the precompiled application for the device.
Error (Xcode): ../../../.pub-cache/hosted/pub.dev/flutter_blurhash-0.7.0/lib/src/blurhash_widget.dart:218:42: Error: Type 'DecoderCallback' not found.
blurhash_widget.dart:218

Error launching application on iPhone 15 Pro Max.
Exited (1)

BlurHash widget does not have an error attribute

If you run into an exception trying to download the image (e.g. connection timeout due to bad connection) a red cross with the error message will be shown ontop of the blurhash image. Currently there is no way to disable this behaviour (I'd rather stick with the blur hash over having this ugly cross) or to set a custom error image.

Project Update Inquiry

Hello everyone,

Just wanted to give you a heads up that it's been over a year since the project received an update, and the most recent version was released in April 2022. I'm keen to learn about any upcoming plans for the project or if there are opportunities to the community to contribute to its further development.

I appreciate your commitment to this project!

[Feature] add header for download image

Hi, and thank u for such a good library!

In my case image on server protected by auth token which should be passed in the Header.
Since blurhash used Image.network under the hood now it is impossible to pass token.

Seems like to reach this goal at the BlurHashState.prepareDisplayedImage instead of Image.network we need use:

Image(
    image: NetworkImage(
    imagePath,
    headers: {
      HttpHeaders.authorizationHeader: 'token',
    },
),

Let me know what u thinking and i can help with implementation

Background issue on PNG image

I am using blurha.sh as mentioned on documentation. While using PNG image, hash effect is still visible on background,

image

Top image is using BlurHash and bottom one using Image.network. For some images I like this effect but for some not. How can get the original image after loading like Image.network.

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  final imageUrl =
      "https://flutter.dev/assets/images/homepage/garden-logos-color/google.png";
  final hash =
      "rOByL6JFEoCA,koaRX\$IS~X8kFo#jXfnf*adf,fP0yxC\${+[I^W=otNarqogkEbdbHfRjXW9jDacj]bcoLjXWVjXW,b0WCs;W.jZWqnzWAjXacjr";

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        AspectRatio(
          key: const ValueKey("GBH"),
          aspectRatio: 200 / 67,
          child: BlurHash(
            hash: hash,
            image: imageUrl,
            color: Colors.green,
          ),
        ),
        Image.network(
          imageUrl,
          key: const ValueKey("GMN"),
        )
      ],
    );
  }
}
[√] Flutter (Channel stable, 2.5.3, on Microsoft Windows [Version
    10.0.19043.1348], locale en-US)
    • Flutter version 2.5.3 at C:\Tools\flutter
    • Upstream repository https://github.com/flutter/flutter.git      
    • Framework revision 18116933e7 (4 weeks ago), 2021-10-15 10:46:35      -0700
    • Engine revision d3ea636dc5
    • Dart version 2.14.4

Blurhash octoimage bug

Code snippet

`import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:instagram/presentation/widgets/global/others/play_this_video.dart';
// ignore: depend_on_referenced_packages
import 'package:octo_image/octo_image.dart';

class NetworkDisplay extends StatefulWidget {
final int cachingHeight, cachingWidth;
final String url, blurHash;
final double aspectRatio;
final bool isThatImage;
final double? height;
final double? width;

const NetworkDisplay({
Key? key,
required this.url,
this.isThatImage = true,
this.cachingHeight = 720,
this.cachingWidth = 720,
this.height,
this.width,
this.blurHash = "",
this.aspectRatio = 0.0,
}) : super(key: key);

@OverRide
State createState() => _NetworkDisplayState();
}

class _NetworkDisplayState extends State {
@OverRide
void initState() {
super.initState();
}

@OverRide
void didChangeDependencies() {
if (widget.isThatImage && widget.url.isNotEmpty) {
precacheImage(NetworkImage(widget.url), context);
}
super.didChangeDependencies();
}

@OverRide
Widget build(BuildContext context) {
return widget.aspectRatio == 0 ? whichBuild(height: null) : aspectRatio();
}

Widget aspectRatio() {
return AspectRatio(
aspectRatio: widget.aspectRatio,
child: whichBuild(),
);
}

Widget whichBuild({double? height = double.infinity}) {
return !widget.isThatImage
? PlayThisVideo(
play: true,
videoUrl: widget.url,
blurHash: widget.blurHash,
)
: buildOcto(height);
}

Widget buildOcto(height) {
int cachingHeight = widget.cachingHeight;
int cachingWidth = widget.cachingWidth;
if (widget.aspectRatio != 1 && cachingHeight == 720) cachingHeight = 960;
return OctoImage(
image: CachedNetworkImageProvider(widget.url,
maxWidth: cachingWidth, maxHeight: cachingHeight),
errorBuilder: (context, url, error) => buildError(),
fit: BoxFit.cover,
width: widget.width ?? double.infinity,
height: widget.height ?? height,
placeholderBuilder: widget.blurHash.isNotEmpty
? OctoImage.blurHash(widget.blurHash, fit: BoxFit.cover)
: (context) => Center(child: loadingWidget()),
);
}
//Error is over here (Attached screenshot)
Screenshot (129)

SizedBox buildError() {
return SizedBox(
width: double.infinity,
height: widget.aspectRatio,
child: Icon(Icons.warning_amber_rounded,
size: 30, color: Theme.of(context).focusColor),
);
}

Widget loadingWidget() {
double aspectRatio = widget.aspectRatio;
return aspectRatio == 0
? buildSizedBox()
: AspectRatio(
aspectRatio: aspectRatio,
child: buildSizedBox(),
);
}

Widget buildSizedBox() {
return Container(
width: double.infinity,
color: Theme.of(context).textTheme.bodyMedium!.color,
child: Center(
child: CircleAvatar(
radius: 57,
backgroundColor: Theme.of(context).textTheme.bodySmall!.color,
child: Center(
child: CircleAvatar(
radius: 56,
backgroundColor: Theme.of(context).textTheme.bodyMedium!.color,
)),
)),
);
}
}
`

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.