Quartz / Chartbuilder

A front-end charting application that facilitates easy creation of simple beautiful charts
http://quartz.github.io/Chartbuilder
MIT License
2.1k stars 354 forks source link

Architectural changes to make more deployable, configureable, and upgradeable. #211

Open zzolo opened 8 years ago

zzolo commented 8 years ago

I am a big fan of Chartbuilder. And please excuse any things I may have overlooked in researching how Chartbuilder works and how it should be used by other organizations. I may come off negative here, but I am mostly just trying to discuss a possibility here.

Chartbuilder seems like it is meant to be used by other organizations. Specifically I would think that the goal is to have organization install Chartbuilder, customize/configure for their needs, and then deploy somewhere. I personally don't think it's built in a way to do this effectively, and I am reluctant to use Chartbuilder in our organization since there is no real upgrade path or easy way to manage customizations/configuration.

This seems to be the current upgrade path for Chartbuilder, and this is not a very good/stable/usual way to upgrade. https://github.com/Quartz/Chartbuilder/blob/master/docs/git-workflow-forks.md

To solve this, Chartbuilder should be thought of as a library, i.e. an NPM or Bower module that can be installed like npm install chartbuilder. This would put a bit more work on the deployment side to set up an HTML page that called something like Chartbuilder({ el: ".cb-container" });. But, given that you need to do npm install and other commands to get running with Chartbuilder, I don't see much difference in skill level for this.

Another step to achieve this would have Chartbuilder not need to go through a build process to be used, but instead comes as a built library.

Secondly, configuration is managed through changing source files. This again, makes it difficult to upgrade. Configuration should happen in a way that is outside the source files, either through a JSON file or options in a function.

JS configuration is also happening in multiple places. It would be super nice to see/have this all in one place.

So, these sorts of changes would make it much easier to deploy, configure, upgrade, and ultimately invest in, at least in my opinion.

I don't think this is a perfect example, but this project gives a good idea of the architectural direction that I think would make Chartbuilder much easier to use from an organizational standpoint. https://github.com/datanews/tik-tok

zzolo commented 8 years ago

Also, for reference, these issues from a while back were aiming to move towards this architectural approach, though many things have changed since then. https://github.com/Quartz/Chartbuilder/pull/48 https://github.com/Quartz/Chartbuilder/pull/103

yanofsky commented 8 years ago

Hey @zzolo, thank you for your thoughts, and sorry for taking so long to respond.

We're looking forward to discussing this—and agree on many points—but have been slammed with other Chartbuilder related stuff, so it's going to take a little while longer for us to give you a the proper response your comments and suggestions deserve.

nsonnad commented 8 years ago

Hey @zzolo, thanks for the feedback.

We are actively working toward doing this, and it's the right way to go. It's not totally clear what the exact API is going to be, but the end result is basically as you say, to distribute chartbuilder as a pre-compiled library and instantiate a new chartbuilder with whatever settings. Of course, for serious customization, one will have to edit the source files.

As a potential user of the chartbuilder library, may I ask what you would be looking to configure? Is there much beyond just basically theming the chart? Would you, for example, want to be able to add additional settings or have really granular control of the data parsing?

I am currently working on completely separating out the chart rendering code into its own library, which I think is a necessary first step in this direction. With that out of the way I think we can aim to have an API where a new chartbuilder is instantiated with default UI elements tied to a chart type, which change the chart model, but with the user able to either use defaults or customize how that data gets rendered to the page.

zzolo commented 8 years ago

So, the two big things to customize are the charts themselves and the interface.

Most of this should be handled in CSS and CSS is trivial to override, the key is just try not to make the default styles too specific.

The second part of the customization would be the actual markup/HTML. This is a bit more complicated since there's no great way to override/include HTML natively with browsers, but what I like to do is just have the the markup in templates that can be overrided with config. Tik Tok is a fine simple example; the template files get complied in the build process and bundled in the distributed version.

From my understanding, Chartbuilder uses some custom ways to handle theming for the charts. I really like the ability to use em's. But this means overriding these values has to be handled in JS or some way of parsing some CSS file that would then override in JS. Highcharts is a really extreme example of style in JS config, but the idea is there.

So, then there are functional overriding/customizing. These would be handled by hooks or events, depending on the need. I think a hook or override of the data parsing function would be very helpful. In projects, I just allow for a config that is a function that gets passed specific things. For example:

Chartbuilder({
  el: ".cb-container",
  dataParser: function(data) {
    return data.map(String.toLowerCase);
  }
});

This could also be handled by JS events, like onParse, but I think a hook is a bit more appropriate since the goal is to alter data. Either way doesn't matter that much. More events could be included, like onRender, or onSave.

Things could get a bit more complicated if/when you separate out chart types. One way I have handled this sort of scenario is to add a hook for the config basically, so someone could change any of the config based on other config in code. This basically allows for all other possibilities.

I don't have a great view of the Chartbuilder code or goals to say what is best, this is just what I have done in the past.