如何更改 Chart.js 中使用的插值器?

2022-01-22 00:00:00 express javascript chart.js

我一直在寻找一些关于图表库的替代方案,适合我需要的是 Chart.js.但是,我不能使用它,因为 Chart.js 中使用的插值器与 Express 的 EJS 模板中使用的插值器相同,比如 <%%>.

I've been looking for some alternatives regarding chart libraries and the one that fits my needs is Chart.js. However, I can't use it because the interpolators used in Chart.js are the same used in EJS templates from Express, like <% and %>.

我使用了其他一些库,例如 underscore.js,您可以在其中修改插值器以便防止与 Javascript 库发生任何冲突.

I've used some other libraries like underscore.js where you're able to modify the interpolators in order to prevent any kind of conflict with the Javascript libraries.

任何帮助将不胜感激......

Any help would be appreciated...

推荐答案

如果更简单,我现在已将其添加到我的 chart.js 自定义构建中,您可以使用 min 或chart.js 版本 https://github.com/leighquince/Chart.js

if it's easier i've now added this to my custom build of chart.js you can use either the min or the chart.js version https://github.com/leighquince/Chart.js

这可以通过更改 helpers.template 函数来完成,尽管它在尝试使用与函数中使用的完全相同的替换方法时确实有其局限性.示例可以在这里找到 http://jsfiddle.net/leighking2/zjztm3or/ (如果图表 js 获取更新这个也需要手动合并)

This can be done by changing the helpers.template function although it does have it's limitations when trying to stick with the exact same replacing method used in the function. Example can be found here http://jsfiddle.net/leighking2/zjztm3or/ (if chart js gets update this would also need to be merged manually)

所以已经进行了更改(只是要突出显示我已更改的部分,而不是将整个图表 js 放在这里)

So changes that have been made (just going to give highlights of parts i have changed rather than placing the whole of chart js here)

设置一个新的默认值来表达模板字符串中所需的起点和终点(因为我们在模板函数中使用相同的替换方法=在想要打印值时仍然会使用)

set up a new default to express desired start and end points within tempalte string (because we are using the same method of replacing within the template function = will still be used when wanting to print a value)

Chart.defaults = {
    global: {
        templateInterpolators: {
            start: "<%",
            end: "%>"
        },
    }
};

然后在模板助手中,我们引用新对象并使用给定的开始和结束,而不是像以前那样硬编码的 <% 和 %>

Then within the template helper we refrence the new object and use the start and end given rather than the hard codded <% and %> as before

template = helpers.template = function (templateString, valuesObject) {
            // If templateString is function rather than string-template - call the function for valuesObject
            var interpolators = Chart.defaults.global.templateInterpolators;
            if (templateString instanceof Function) {
                return templateString(valuesObject);
            }

            var cache = {};

            function tmpl(str, data) {
                // Figure out if we're getting a template, or if we need to
                // load the template - and be sure to cache the result.
                var fn = !/W/.test(str) ? cache[str] = cache[str] :

                // Generate a reusable function that will serve as a template
                // generator (and which will be cached).
                new Function("obj",
                    "var p=[],print=function(){p.push.apply(p,arguments);};" +

                // Introduce the data as local variables using with(){}
                "with(obj){p.push('" +

                // Convert the template into pure JavaScript
                str.replace(/[	
]/g, " ")
                    .split(interpolators.start).join("	")
                    .replace(new RegExp("((^|" + interpolators.end + ")[^	]*)'", "g"), "$1")
                    .replace(new RegExp("	=(.*?)" + interpolators.end, "g"), "',$1,'")
                    .split("	").join("');")
                    .split(interpolators.end).join("p.push('")
                    .split("").join("\'") +
                    "');}return p.join('');");

                // Provide some basic currying to the user
                return data ? fn(data) : fn;
            }
            return tmpl(templateString, valuesObject);
        },

这里的限制是新的插值器不能在其中包含 },就像给定模板时一样 tooltipTemplate = "{{if (label){}}{{= label }}: {{}}}{{= value }}"; 它在匹配三元组 }}} 时遇到了麻烦,而我的正则表达式不足以弄清楚如何告诉它匹配最后一对而不是第一对,所以有了这个方法只要你避免'}'你应该很好.

The limitations here are that the new interpolators can not have } in them as when given a template like tooltipTemplate = "{{if (label){}}{{= label }}: {{}}}{{= value }}"; it runs into trouble when matching the tripple }}} and my regex is not good enough to figure out how to tell it to match the last pair not the first pair, so with this method as long as you avoid '}' you should be good.

现在要使用它,您需要确保声明要使用的插值器

Now to use it you will need to ensure you declare the interpolators you wish to use

    Chart.defaults.global.templateInterpolators = {
        start: "[[",
        end: "]]"
    };

然后设置模板,对于特定于每个图表的任何图例模板(如果您想使用它们)也需要这样做

then setup up the tempaltes, this will also need to happen for any legend templates that are specific to each graph (if you want to use them)

    Chart.defaults.global.scaleLabel = "[[= value ]]";
    Chart.defaults.global.tooltipTemplate = "[[if (label){]][[= label ]]: [[}]][[= value ]]";
    Chart.defaults.global.multiTooltipTemplate = "[[= value ]]";

现在您可以正常使用 Chart.js

and now you can just use Chart.js as normal

var ctxBar = document.getElementById("chart-bar").getContext("2d");
var ctxLine = document.getElementById("chart-line").getContext("2d");
var data = {
    labels: [1, 2, 3, 4],
    datasets: [{
        label: "My First dataset",
        fillColor: "rgba(220,220,220,0.2)",
        strokeColor: "rgba(220,220,220,1)",
        pointColor: "rgba(220,220,220,1)",
        pointStrokeColor: "#fff",
        pointHighlightFill: "#fff",
        pointHighlightStroke: "rgba(220,220,220,1)",
        data: [65, 34, 21, 11]
    }, ]
};




var myBarChart = new Chart(ctxBar).Bar(data);
var myLineChart = new Chart(ctxLine).Line(data);

相关文章