APEX 5: How to edit dynamically chart xml?

2019-07-15 05:40发布

问题:

I am building an Apex Application with a couple of charts (html rendered barchart from the wizard). Now, I have to include two important features. Change the colour of the bars depending on the value and include some labels on top or after the bars. I know that this can be achieved by setting the option "Custom xml" to YES and editing the xml. The problem is that I have not been able to edit this dynamically.

I have tried to execute a function in the xml area, but it gets interpreted as a String(I guess the area is treated like a template). I have also tried to add an item, reference to it in the xml and add the generated text to the item trough a PL/SQL block, but this also didn't work.

回答1:

I can suggest a solution based on SVG format understanding. Here is an example: https://apex.oracle.com/pls/apex/f?p=34599:4 It contains a chart with bars and a button (To Red). Button's action is Dynamic action, which executes a javascript code. If you click the button, one of bars will change its color.

How does it work. SVG grafics works the same way as HTML and CSS. Tag defs inside the svg tag contains a list of styles, tags g, path, rect and many others contain graphics, which can use styles from the defs list. You need to change predefined defs list and graphics elements.

Here is the code. I am not a good javascript programmer, and, as you can see, all significant values are hardcoded here. But I hope the whole idea is clear:

// here we get defs list. Be careful if you have several charts on the page:
var defs = document.getElementsByTagName("defs")[0];

// here we get one of color styles:
var grad1 = document.getElementById("#ac_linearGradient_75");

// make a copy of the style:
var grad2 = grad1.cloneNode(true);

// and change its ID:
grad2.id = grad2.id + "_copy";

// then define new color:
grad2.firstChild.setAttribute("style", "stop-color:rgb(209, 29, 29);stop-opacity:0.9");

// append to the defs list:
defs.appendChild(grad2);

// get one of bars by ID:    
var bar1 = document.getElementById("#ac_path_8o");

// set new filling style:
bar1.setAttribute("fill", "url(##ac_linearGradient_75_copy)");

In Dynamic Action's properties you can set property Fire on page load - code will work automatically after page load. Also in javascript code you can get values from items, put them into the chart, etc.